为什么我的OpenSSL C++代码会创建二进制加密输出

Why does my OpenSSL C++ code create binary encryption output?

本文关键字:创建 二进制 加密 输出 代码 我的 OpenSSL C++ 为什么      更新时间:2023-10-16

我正在尝试使用OpenSSL中的AES加密文件,然后将输出写入文件。但我得到了混乱的输出,有时可以破译,有时无法破译。

主要代码基于以下内容:https://github.com/shanet/Crypto-Example/blob/master/crypto-example.cpp

这是代码:

int Crypt::__aesEncrypt(const unsigned char *msg, size_t msgLen, unsigned char **encMsg) {
EVP_CIPHER_CTX *aesEncryptCtx = (EVP_CIPHER_CTX*)malloc(sizeof(EVP_CIPHER_CTX));
EVP_CIPHER_CTX_init(aesEncryptCtx);
unsigned char *aesKey = (unsigned char*)malloc(AES_KEYLEN/8);
unsigned char *aesIV = (unsigned char*)malloc(AES_KEYLEN/8);
unsigned char *aesPass = (unsigned char*)malloc(AES_KEYLEN/8);
unsigned char *aesSalt = (unsigned char*)malloc(8);
if(RAND_bytes(aesPass, AES_KEYLEN/8) == 0) {
    return FAILURE;
}
if(RAND_bytes(aesSalt, 8) == 0) {
    return FAILURE;
}
if(EVP_BytesToKey(EVP_aes_256_cbc(), EVP_sha1(), aesSalt, aesPass, AES_KEYLEN/8, AES_ROUNDS, aesKey, aesIV) == 0) {
    return FAILURE;
}
strncpy((char*)aesKey, (const char*)"B374A26A71490437AA024E4FADD5B4AA", AES_KEYLEN/8);
strncpy((char*)aesIV, (const char*)"7E892875A52C59A3B588306B13C31FBD", AES_KEYLEN/16);
size_t blockLen = 0;
size_t encMsgLen = 0;
*encMsg = (unsigned char*)malloc(msgLen + AES_BLOCK_SIZE);
if(encMsg == NULL) return FAILURE;
if(!EVP_EncryptInit_ex(aesEncryptCtx, EVP_aes_256_cbc(), NULL, aesKey, aesIV)) {
    return FAILURE;
}
if(!EVP_EncryptUpdate(aesEncryptCtx, *encMsg, (int*)&blockLen, (unsigned char*)msg, msgLen)) {
    return FAILURE;
}
encMsgLen += blockLen;
if(!EVP_EncryptFinal_ex(aesEncryptCtx, *encMsg + encMsgLen, (int*)&blockLen)) {
    return FAILURE;
}
EVP_CIPHER_CTX_cleanup(aesEncryptCtx);
free(aesEncryptCtx);
free(aesKey);
free(aesIV);
return encMsgLen + blockLen;

}

我是这样打电话的:

unsigned char *encMsg = NULL;
    __aesEncrypt((const unsigned char*)decrypted_string.c_str(), decrypted_string.size(), &encMsg);
    std::stringstream ss;
    ss << encMsg;
    //write ss to file...

谢谢。

实际上,我是您的代码所基于的示例的作者。正如WhozCraig在上面的评论中指出的那样,您正在使用stringstream将加密消息写入文件。问题是加密的消息不是常规的ASCII字符串。它们是二进制数据(值大于127,因此需要无符号字符数组),二进制数据不能像ASCII字符串一样处理。

我不太喜欢C++,所以我会用fwrite以C的方式将数据写入文件,但如果你想用C++的方式,我认为你在寻找ifstream而不是stringstream

附带说明,我打赌这只是为了调试,但无论如何我都会指出这一点,只是为了确保:对AES密钥和IV(strncpy((char*)aesKey, (const char*)"B374A26A71490437AA024E4FADD5B4AA", AES_KEYLEN/8))进行硬编码完全违背了加密的目的。如果你想避免PBKDF(EVP_BytesToKey),你可以使用RAND_Bytes来获得AES密钥的随机数据。