Created
November 14, 2016 10:13
-
-
Save cameronehrlich/6f77a4982f141ee516fe52242eb803db to your computer and use it in GitHub Desktop.
PHP's M_CRYPT in C Environment
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| ///////////////////////// | |
| // Base64.h | |
| #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 // BASE64_H | |
| ///////////////////////// | |
| // Base64.cpp | |
| //#include "Base64.h" | |
| #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 ] ); | |
| } | |
| ///////////////////////// | |
| // main.cpp | |
| #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; | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment