Crypto ++到PHP mcrypt无法正常工作

Jef*_*eff 2 php c++ mcrypt crypto++

我有一个C++应用程序,它使用Crypto ++将加密数据发送到PHP站点.但是,当数据进入PHP端时,它不会正确解密数据.

C++/Crypto ++代码:

char stupidKey[AES::MAX_KEYLENGTH] = "thisisastupidkeythisisastupidke";

ECB_Mode<AES>::Encryption aes((byte *)stupidKey, AES::MAX_KEYLENGTH);

std::string cypher;
StringSource(aData, true, new StreamTransformationFilter(aes, new StringSink( cypher ))); 
StringSource(cypher, true, new Base64Encoder( new StringSink(aOutput) ));
Run Code Online (Sandbox Code Playgroud)

PHP代码:

define('CRYPT_SECRET', 'thisisastupidkeythisisastupidke');

$postData = mcrypt_decrypt(MCRYPT_RIJNDAEL_256, 
                CRYPT_SECRET, base64_decode($_POST['request']), 
                MCRYPT_MODE_ECB);
Run Code Online (Sandbox Code Playgroud)

注意:我知道ECB是加密模式的一个不好的选择,但是我希望能够在没有IV的额外奇怪之处的情况下使用它,然后使事情复杂化.

Mic*_*pso 6

我没有运气mcrypt,但openssl似乎更好地使用Crypto ++.

这是Crypto ++代码:

#include <iostream>
#include <cryptopp/aes.h>
#include <cryptopp/modes.h>
#include <cryptopp/base64.h>

std::string encrypt(const std::string& str_in, const std::string& key, const std::string& iv)
{
    std::string str_out;
    CryptoPP::CFB_Mode<CryptoPP::AES>::Encryption encryption((byte*)key.c_str(), key.length(), (byte*)iv.c_str());

    CryptoPP::StringSource encryptor(str_in, true, 
        new CryptoPP::StreamTransformationFilter(encryption, 
            new CryptoPP::Base64Encoder(
                new CryptoPP::StringSink(str_out),
                false // do not append a newline
            )
        )
    );
    return str_out;
}

std::string decrypt(const std::string& str_in, const std::string& key, const std::string& iv)
{
    std::string str_out;

    CryptoPP::CFB_Mode<CryptoPP::AES>::Decryption decryption((byte*)key.c_str(), key.length(), (byte*)iv.c_str());

    CryptoPP::StringSource decryptor(str_in, true, 
        new CryptoPP::Base64Decoder(
            new CryptoPP::StreamTransformationFilter(decryption, 
                new CryptoPP::StringSink(str_out)
            )
        )
    );
    return str_out;
}

int main(int argc, char *argv[])
{
    std::string str = "Hello, world!";
    std::string key = "01234567891234560123456789123456"; // 32 bytes
    std::string iv  = "0123456789123456"; // 16 bytes
    std::string str_encrypted = encrypt(str, key, iv);
    std::string str_decrypted = decrypt(str_encrypted, key, iv);
    std::cout << "str_encrypted: " << str_encrypted << std::endl;
    std::cout << "str_decrypted: " << str_decrypted << std::endl;
}
Run Code Online (Sandbox Code Playgroud)

这是PHP代码:

<?php
    $string = 'Hello, world!';
    $key = '01234567891234560123456789123456'; // 32 bytes
    $iv  = '0123456789123456'; // 16 bytes
    $method = 'aes-256-cfb';
    $encrypted = base64_encode( openssl_encrypt ($string, $method, $key, true, $iv));
    $decrypted = openssl_decrypt( base64_decode($encrypted), $method, $key, true, $iv);
    echo "encrypted: $encrypted<br/>";
    echo "decrypted: $decrypted<br/>";
?>
Run Code Online (Sandbox Code Playgroud)

这是Crypto ++输出:

str_encrypted: pF1gsk+GolfeTSYnEQ==
str_decrypted: Hello, world!
Run Code Online (Sandbox Code Playgroud)

...和PHP输出:

encrypted: pF1gsk+GolfeTSYnEQ==
decrypted: Hello, world!
Run Code Online (Sandbox Code Playgroud)

不要忘记将密钥和iv更改为更智能的值:o)


Ben*_*rth 5

查看PHP手册(http://php.net/manual/en/function.mcrypt-decrypt.php),MCRYPT_RIJNDAEL_256与AES_256不同.第一条评论提供了一些帮助:http://www.php.net/manual/en/function.mcrypt-decrypt.php#105985

注意,MCRYPT_RIJNDAEL_256不等同于AES_256.

使用openssl从AES解密RIJNDAEL的方法是使用MCRYPT_RIJNDAEL_128并在使用以下函数加密之前填充字符串进行加密:

<?php 
function pkcs5_pad ($text, $blocksize) { 
    $pad = $blocksize - (strlen($text) % $blocksize); 
    return $text . str_repeat(chr($pad), $pad); 
} 
?> 
Run Code Online (Sandbox Code Playgroud)

在解密时,AES_256或AES_128等的选择基于加密中使用的密钥大小.在我的情况下它是128位密钥所以我使用AES_128.