0

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

ありがとう。

4

1 に答える 1

3

私は実際、あなたがコードの基にした例の作成者です。上記のコメントで WhozCraig が指摘したようにstringstream、暗号化されたメッセージをファイルに書き込むために を使用しています。これの問題は、暗号化されたメッセージが通常の ASCII 文字列ではないことです。これらはバイナリ データ (値が 127 より大きいため、unsigned char 配列が必要) であり、バイナリ データは ASCII 文字列と同じように扱うことはできません。

私はあまり C++ の人ではないので、C の方法でデータをファイルに書き込みますがfwrite、C++ の方法で行いたい場合ifstreamは、stringstream.

補足として、これはデバッグのためだけのものだと思いますが、念のため指摘しておきます: AES キーと IV ( strncpy((char*)aesKey, (const char*)"B374A26A71490437AA024E4FADD5B4AA", AES_KEYLEN/8)) をハードコーディングすると、暗号化の目的が完全に無効になります。EVP_BytesToKeyPBKDF ( )を回避したい場合RAND_Bytesは、AES キーのランダム データを取得するために使用できます。

于 2013-07-31T21:30:47.683 に答える