mcrypt, PHP?
, Rijndael AES, , . Rijndael , AES - Rijndael os 128, 192 256, 128. mcrypt, PHP, .
++ - , , :
plain text: the book is on the table!
cipher text: dGhlIGJvb2sgaXMgb24gdGhlIHRhYmxlIQ==
back to: the book is on the table!
sample cipher text: 2Fa9cICuUFa/UnmAAa5FjXZK4ht9q3cN2qgk1pCvDSs=
sample plain text: ":F‚m&X"Öwÿ ï@í`D’ühà¢äè"˜‚)
, PHP- ( !:-)). .
- libmcrypt ( 2.5.8 )
- OpenSSL md5 Base64 ( ...)
... , OpenSSL md5() Base64, , , md5/base64, OpenSSL, . Apple CommonCrypto.
#ifndef BASE64_H
#define BASE64_H
#include <string>
#include <vector>
class Base64
{
public:
static std::string encode( const unsigned char * p_buffer, size_t p_size );
static std::string encode( const std::string & p_string );
static std::string encode( const std::vector< unsigned char > & p_buffer );
static std::string decode( const std::string & p_input );
static void decode( const std::string & p_input, std::vector< unsigned char > & p_output );
};
#endif
#include <openssl/evp.h>
using namespace std;
string Base64::encode( const unsigned char * p_buffer, size_t p_size )
{
unsigned char * output( new unsigned char[ p_size * 4 / 3 + 4 ] );
size_t outputLength( EVP_EncodeBlock( output, p_buffer, static_cast< int >( p_size ) ) );
string ret( reinterpret_cast< char * >( output ), outputLength );
delete [] output;
return ret;
}
string Base64::encode( const string & p_string )
{
return Base64::encode( reinterpret_cast< const unsigned char * >( p_string.c_str() ), p_string.size() );
}
string Base64::encode( const vector< unsigned char > & p_buffer )
{
return Base64::encode( &p_buffer[ 0 ], p_buffer.size() );
}
void Base64::decode( const string & p_input, vector< unsigned char > & p_output )
{
p_output.resize( p_input.length() * 3 / 4 );
size_t outputLength( EVP_DecodeBlock( &p_output[ 0 ], reinterpret_cast< const unsigned char * >( p_input.c_str() ), static_cast< int >( p_input.size() ) ) );
size_t length( p_input.length() );
if ( p_input[ length - 2 ] == '=' )
{
outputLength -= 2;
}
else if ( p_input[ length - 1 ] == '=' )
{
outputLength--;
}
p_output.resize( outputLength );
}
string Base64::decode( const string & p_input )
{
vector< unsigned char > output;
Base64::decode( p_input, output );
return reinterpret_cast< const char * >( &output[ 0 ] );
}
#include <iostream>
#include <string>
#include <regex>
#include <openssl/evp.h>
#include <mcrypt.h>
#define MCRYPT_MODE_CBC "cbc"
using namespace std;
string md5( const string & p_string )
{
EVP_MD_CTX mdContext;
const EVP_MD * md;
unsigned int outputLength;
unsigned char output[ 16 ];
OpenSSL_add_all_digests();
if ( !( md = EVP_get_digestbyname( "MD5" ) ) )
{
throw std::runtime_error( "Unable to init MD5 digest." );
}
EVP_MD_CTX_init( &mdContext );
EVP_DigestInit_ex( &mdContext, md, 0 );
EVP_DigestUpdate( &mdContext, p_string.c_str(), p_string.length() );
EVP_DigestFinal_ex( &mdContext, output, &outputLength );
EVP_MD_CTX_cleanup( &mdContext );
char outputString[ sizeof( output ) * 2 + 1 ];
for ( int i( 0 ); i < sizeof( output ); ++i )
{
snprintf( outputString + i * 2, 2 + 1, "%02x", output[ i ] );
}
return outputString;
}
string trimString( const string & p_string )
{
string ret( p_string );
regex functionRegex( "\\s*(.*)\\s*", regex_constants::icase );
smatch matches;
if ( regex_search( p_string, matches, functionRegex ) )
{
ret = matches[ 1 ].str();
}
return ret;
}
void mcrypt_encrypt( vector< unsigned char > & p_output, const char * p_cryptEngine, const string & p_key, const vector< unsigned char > & p_input, const char * p_mode, const string & p_iv )
{
MCRYPT td = mcrypt_module_open( ( char * )p_cryptEngine, 0, ( char * )p_mode, 0 );
if ( td == MCRYPT_FAILED )
{
throw std::runtime_error( "can't init mcrypt" );
}
if ( mcrypt_generic_init( td, ( char * )p_key.c_str(), mcrypt_enc_get_key_size( td ), ( char * )p_iv.c_str() ) < 0 )
{
throw std::runtime_error( "can't setup key/iv" );
}
p_output.reserve( p_input.size() );
copy( p_input.begin(), p_input.end(), back_inserter( p_output ) );
mcrypt_generic( td, ( void * )&p_output[ 0 ], (int)p_output.size() );
mcrypt_generic_end( td );
}
void mcrypt_decrypt( vector< unsigned char > & p_output, const char * p_cryptEngine, const string & p_key, const vector< unsigned char > & p_input, const char * p_mode, const string & p_iv )
{
MCRYPT td = mcrypt_module_open( ( char * )p_cryptEngine, 0, ( char * )p_mode, 0 );
if ( td == MCRYPT_FAILED )
{
throw std::runtime_error( "can't init mcrypt" );
}
if ( mcrypt_generic_init( td, ( char * )p_key.c_str(), mcrypt_enc_get_key_size( td ), ( char * )p_iv.c_str() ) < 0 )
{
throw std::runtime_error( "can't setup key/iv" );
}
p_output.reserve( p_input.size() );
copy( p_input.begin(), p_input.end(), back_inserter( p_output ) );
mdecrypt_generic( td, ( void * )&p_output[ 0 ], (int)p_output.size() );
mcrypt_generic_end( td );
}
string encrypt_decrypt( const string & action, const string & p_string )
{
string output = "";
string key = "mykeyhereblah";
string iv = md5( md5( key ) );
vector< unsigned char > cipherText, plainText;
if ( action == "encrypt" )
{
copy( p_string.begin(), p_string.end(), back_inserter( plainText ) );
mcrypt_encrypt( cipherText, MCRYPT_RIJNDAEL_256, md5( key ), plainText, MCRYPT_MODE_CBC, iv );
output = Base64::encode( cipherText );
}
else if ( action == "decrypt" )
{
Base64::decode( p_string, cipherText );
mcrypt_decrypt( plainText, MCRYPT_RIJNDAEL_256, md5( key ), cipherText, MCRYPT_MODE_CBC, iv );
output = string( ( char* )&plainText[ 0 ], plainText.size() );
output = trimString( output );
}
return output;
}
int main( int argc, char * argv[] )
{
string plainText = "the book is on the table!";
string cipherText = encrypt_decrypt( "encrypt", plainText );
cout << "plain text: " << plainText << endl;
cout << "cipher text: " << cipherText << endl;
cout << "back to: " << encrypt_decrypt( "decrypt", cipherText ) << endl;
cout << endl;
cout << "your sample: " << encrypt_decrypt( "decrypt", "2Fa9cICuUFa/UnmAAa5FjXZK4ht9q3cN2qgk1pCvDSs=" ) << endl;
return 0;
}