简体   繁体   English

OpenSSL C ++加密问题

[英]OpenSSL C++ Encrypting Issue

So what I'm trying to do is have an encryption key on my PC that is based off of the time, and have the server generate the same encryption key. 所以我想做的是在我的PC上有一个基于时间的加密密钥,并让服务器生成相同的加密密钥。 I have done that successfully, except for the cipher on my PC. 除PC上的密码外,我已经成功完成了此操作。 I am trying to encrypt text in AES-256-CBC on the server and on my PC. 我正在尝试在服务器和PC上的AES-256-CBC中加密文本。 On my PC I have: 在我的电脑上,我有:

std::string Encrypt( const unsigned char *szPlainText, const unsigned char *szKey, unsigned char *szIV, const int iTextLength )
{
    unsigned char szOutput[ 16 ];
    memset( szOutput, 0, sizeof( szOutput ) );

    std::string strOutput { };
    AES_KEY enc_key;
    AES_set_encrypt_key( szKey, 256, &enc_key );
    AES_cbc_encrypt( szPlainText, szOutput, iTextLength, &enc_key, (unsigned char*)szKey, AES_ENCRYPT );
    strOutput.append( reinterpret_cast< const char* >( szOutput ) );
    return strOutput;
}

std::string MD5Hash( const unsigned char *szPlainText, const int iCharacters )
{
    unsigned char chDigest[ MD5_DIGEST_LENGTH ] { };

    MD5( szPlainText, iCharacters, reinterpret_cast< unsigned char* >( &chDigest ) );

    char mdString[ 33 ];

    for ( int i = 0; i < MD5_DIGEST_LENGTH; i++ )
        sprintf( &mdString[ i * 2 ], "%02x", ( unsigned int )chDigest[ i ] );

    return mdString;
}

int main( )
{
    const unsigned char *szPlainText = reinterpret_cast< const unsigned char* >( "test" );
    std::string strCipher { };
    std::string strResponseBuffer { };
    std::string strEncryptionKey { };
    strEncryptionKey = MD5Hash( reinterpret_cast< const unsigned char* >( std::to_string( int( std::chrono::duration_cast< std::chrono::seconds >( std::chrono::system_clock::now( ).time_since_epoch( ) ).count( ) / 10 ) ).c_str( ) ), std::to_string( int( std::chrono::duration_cast< std::chrono::seconds >( std::chrono::system_clock::now( ).time_since_epoch( ) ).count( ) / 10 ) ).length(  ) );
    strEncryptionKey = strEncryptionKey.substr( 0, 16 );
    std::cout << "Our enc key before encryption: " << strEncryptionKey << std::endl;
    strCipher = Encrypt( szPlainText, reinterpret_cast< const unsigned char* >( strEncryptionKey.c_str( ) ), ( unsigned char* )( strEncryptionKey.c_str( ) ), strlen(reinterpret_cast< const char* >( szPlainText ) ));

    curl_global_init( CURL_GLOBAL_ALL );
    void *vCurl = curl_easy_init( );
    curl_easy_setopt( vCurl, CURLOPT_URL, strURL );
    //curl_easy_setopt( vCurl, CURLOPT_POSTFIELDS, strPostData.c_str( ) );
    curl_easy_setopt( vCurl, CURLOPT_WRITEFUNCTION, WriteCallback );
    curl_easy_setopt( vCurl, CURLOPT_WRITEDATA, &strResponseBuffer );
    curl_easy_perform( vCurl );
    curl_easy_cleanup( vCurl );

    std::cout << "Our time: " << std::chrono::duration_cast< std::chrono::seconds >( std::chrono::system_clock::now( ).time_since_epoch( ) ).count( ) / 10 << std::endl;
    std::cout << "Our enc key: " << strEncryptionKey << std::endl;
    std::cout << "Our cipher: " << strCipher << std::endl;
    std::cout << "Our plain text: " << szPlainText << std::endl;
    std::cout << strResponseBuffer << std::endl;

    system( "pause" );
    return 0;
}

On the server, where the PHP code is, I have: 在PHP代码所在的服务器上,我有:

<?php
    $encmethod = "AES-256-CBC";
    $plaintext = "test";
    $time = microtime(false);
    $time = substr($time, 11, strlen($time) - 11);
    $time = floor($time / 10);

    $enckey = substr(md5($time), 0, 16);
    $cipher = openssl_encrypt($plaintext, $encmethod, $enckey, 0, $enckey);
    die("Server's time: ".$time."\r\n"."Server's enc key: ".$enckey."\r\n"."Server's cipher: ".base64_decode($cipher)."\r\n"."Server's plain text: ".$plaintext);
?>

I do realize that I am using my encryption key for an IV. 我确实意识到我正在使用IV的加密密钥。 I Base64 decode the encryption because OpenSSL for PHP apparently encodes the cipher by default. 我使用Base64解码加密,因为默认情况下,PHP的OpenSSL显然对密码进行了编码。 What I don't understand is the output I get: 我不明白的是我得到的输出:

Our enc key before encryption: bd40cb464c24382e
Our time: 151693026
Our enc key: ▐τA╕cæσ@c¿svcî
Our cipher: ▐τA╕cæσ@c¿svcî╠╠╠╠HÇ~╖D·█
Our plain text: test
Server's time: 151693026
Server's enc key: bd40cb464c24382e
Server's cipher: nr"δµûa¢╝│)║\ß■V
Server's plain text: test
Press any key to continue . . .

This changes every 10 seconds because that's what it's based on. 这是每10秒更改一次,因为这是基于此。 What appears to be happening is after encryption, my encryption key is becoming encrypted and I don't know what my cipher is supposed to be. 似乎正在发生加密之后,我的加密密钥正在加密,我不知道密码应该是什么样。 The 4 repeating characters ╠╠╠╠ appear to be there every time the encryption changes. 每次更改加密时,都会出现4个重复字符╠╠╠╠。 If anyone knows what I'm doing wrong I would appreciate it. 如果有人知道我在做什么错,我将不胜感激。

The bug comes from bad casting. 该错误来自错误的投射。 In this line of code: 在这行代码中:

strCipher = Encrypt( 
    szPlainText, 
    reinterpret_cast< const unsigned char* >( strEncryptionKey.c_str( ) ),
    ( unsigned char* )( strEncryptionKey.c_str( ) ), 
    strlen(reinterpret_cast< const char* >( szPlainText ) ));

The second cast is a bit abusive. 第二个演员阵容有点滥用。 Apparently the function expects a non-const buffer. 显然,该函数需要一个非常量缓冲区。 You should provide the address of a separate 16 bytes work array there. 您应该在那里提供一个单独的16字节工作数组的地址。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM