php - OpenSSL C++ 加密问题

标签 php c++ openssl cryptography

所以我想做的是在我的 PC 上有一个基于时间的加密 key ,并让服务器生成相同的加密 key 。我已经成功地做到了,除了我电脑上的密码。我正在尝试在服务器和我的 PC 上使用 AES-256-CBC 加密文本。在我的电脑上,我有:

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;
}

在 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);
?>

我确实意识到我正在使用我的加密 key 进行 IV。我使用 Base64 解码加密,因为 OpenSSL for PHP 显然默认对密码进行编码。我不明白的是我得到的输出:

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 . . .

这每 10 秒更改一次,因为这是它的基础。似乎发生的事情是在加密之后,我的加密 key 正在加密,我不知道我的密码应该是什么。每次加密更改时,4 个重复字符 ╠╠╠╠ 似乎都在那里。如果有人知道我做错了什么,我将不胜感激。

最佳答案

错误来自错误的转换。在这行代码中:

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

第二个 Actor 有点辱骂。显然该函数需要一个非常量缓冲区。您应该在那里提供一个单独的 16 字节工作数组的地址。

关于php - OpenSSL C++ 加密问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48454660/

相关文章:

php - MySQL - SELECT 语句的 WHERE 子句结果中的变量

php - 使用 PHP 将 SQL 查询行添加到新数组

c++ - 如何在我的系统中使用 OpenCL

c++ - 计算c++中操作之间的时间长度

c++ - 如何以编程方式读取/写入 ISO 文件的某些 LBA 上的扇区?

php - Mysql if else条件

javascript - 如何在 innerHTML 值的表单中使用 php 变量?

ios - 带有 openssl 加密数据的 NSString initWithBytes 使用 NSUTF8StringEncoding 返回 nil

ssl - keytool 错误 : java. lang.Exception:回复中的公钥和 keystore 不匹配

flash - 延长/续订 p12 自签名证书已过期