0

我正在尝试从文件中读取字符串,使用 AES 对其进行加密,然后将其保存到其他文件中。稍后我需要读取新文件,解密并将输出再次保存到新文件中。问题是出现了一些奇怪的字符。

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*)"B374A26A714904AAB374A26A714904AA", AES_KEYLEN/8);
strncpy((char*)aesIV, (const char*)"B374A26A714904AA", AES_KEYLEN/16);

size_t blockLen = 0;
size_t encMsgLen = 0;

*encMsg = (unsigned char*)malloc(msgLen + AES_BLOCK_SIZE);
if(encMsg == NULL) return FAILURE;
(*encMsg)[0] = '\0';

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

int Crypt::__aesDecrypt(unsigned char *encMsg, size_t encMsgLen, char **decMsg) {
EVP_CIPHER_CTX *aesDecryptCtx = (EVP_CIPHER_CTX*)malloc(sizeof(EVP_CIPHER_CTX));
EVP_CIPHER_CTX_init(aesDecryptCtx);

unsigned char *aesKey;
unsigned char *aesIV;

aesKey = (unsigned char*)malloc(AES_KEYLEN/8);
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*)"B374A26A714904AAB374A26A714904AA", AES_KEYLEN/8);
strncpy((char*)aesIV, (const char*)"B374A26A714904AA", AES_KEYLEN/16);

size_t decLen = 0;
size_t blockLen = 0;

*decMsg = (char*)malloc(encMsgLen);
if(*decMsg == NULL) return FAILURE;

if(!EVP_DecryptInit_ex(aesDecryptCtx, EVP_aes_256_cbc(), NULL, aesKey, aesIV)) {
    return FAILURE;
}

if(!EVP_DecryptUpdate(aesDecryptCtx, (unsigned char*)*decMsg, (int*)&blockLen, encMsg, (int)encMsgLen)) {
    return FAILURE;
}
decLen += blockLen;

if(!EVP_DecryptFinal_ex(aesDecryptCtx, (unsigned char*)*decMsg + decLen, (int*)&blockLen)) {
    return FAILURE;
}
decLen += blockLen;

(*decMsg)[decLen] = '\0';

EVP_CIPHER_CTX_cleanup(aesDecryptCtx);

return encMsgLen;
}

加密:

    unsigned char *encMsg = NULL;
    int size = __aesEncrypt((const unsigned char*)decrypted_string.c_str(), decrypted_string.size(), &encMsg);


    return std::string(reinterpret_cast<const char*>(encMsg), size);

解密:

    char *decMsg = NULL;
    int size = __aesDecrypt((unsigned char*)encrypted_string.c_str(), encrypted_string.size(), &decMsg);

    return std::string(reinterpret_cast<const char*>(decMsg), size);

我可以成功加密和解密,但是加密文件的末尾出现了一些奇怪的字符,它们就像空格:

4

1 回答 1

2

AES 是一种块密码。它需要 16 个字节的块,并将它们加密成一个 16 个字节的块。如果您尝试将其用于长度不是 16 倍数的数据,则会添加填充(通常是随机数据)以将其四舍五入为 16 字节的倍数。您需要自己管理数据的长度。

例子:

int encryptHelper(const string& msg, ...)
{
    uint32_t msgSize = msg.length();
    newMsg.push_back((msgSize >> 0)  & 0xFF);
    newMsg.push_back((msgSize >> 8)  & 0xFF);
    newMsg.push_back((msgSize >> 16) & 0xFF);
    newMsg.push_back((msgSize >> 24) & 0xFF);
    string newMsg(reinterpret_cast<const char*>(&msgSize), sizeof(msgSize));
    newMsg += msg;
    return __aesEncrypt(newMsg.c_str(), newMsg.length(), ...);
}

int decryptHelper(const string& encrypted, ...)
{
    string msg = ... whatever you are doing to decrypt
    uint32_t actualSize = 0;
    // remove signal first, then widen
    actualSize |= static_cast<uint32_t>(static_cast<unsigned char>(msg[0])) << 0;
    actualSize |= static_cast<uint32_t>(static_cast<unsigned char>(msg[1])) << 8;
    actualSize |= static_cast<uint32_t>(static_cast<unsigned char>(msg[2])) << 16;
    actualSize |= static_cast<uint32_t>(static_cast<unsigned char>(msg[3])) << 24;
    string actualMsg = msg.substr(4, actualSize);
    ...
}

我没有费心编写确切的代码来调用你的函数,因为所有的强制转换和内存泄漏让我感到恶心。填空。

于 2013-08-02T22:13:13.303 回答