问题
I am using C-API of OpenSSL, but I am confused on how IV (Initialization Vector) is used in OpenSSL.
Say, I have
plaintext.txt file = "This is a top secret."
Key = "example#########"
IV = 010203040506070809000a0b0c0d0e0f
when I encrypt this using OpenSSL AES-128-CBC, I should get:
e5accdb667e8e569b1b34f423508c15422631198454e104ceb658f5918800c22
Which is true when I try this (key converted to hex):
openssl enc -aes-128-cbc -e -in plaintext.txt -out ciphertext.bin
-K 6578616d706c65232323232323232323 -iv 010203040506070809000a0b0c0d0e0f
I get:
xxd -p ciphertext.bin
e5accdb667e8e569b1b34f423508c15422631198454e104ceb658f5918800c22
But I got different ciphertext thing using C
char plaintext[] = "This is a top secret.";
unsigned char iv[16] = {
0x01, 0x02, 0x03, 0x04,
0x05, 0x06, 0x07, 0x08,
0x09, 0x00, 0x0A, 0x0B,
0x0C, 0x0D, 0x0E, 0x0F
};
unsigned char ciphertext[] = {
0xe5, 0xac, 0xcd, 0xb6,
0x67, 0xe8, 0xe5, 0x69,
0xb1, 0xb3, 0x4f, 0x42,
0x35, 0x08, 0xc1, 0x54,
0x22, 0x63, 0x11, 0x98,
0x45, 0x4e, 0x10, 0x4c,
0xeb, 0x65, 0x8f, 0x59,
0x18, 0x80, 0x0c, 0x22
};
key (example) is in a words.txt
file.
My encryption process:
while(fgets(words, 16, wordsfile)) { //for getting key and padding
index = strlen(words) - 1; //key "example" is the last word in words.txt
while(index < 16) {
words[index] = 0x20;
index++;
}
words[index] = '\0';
EVP_CIPHER_CTX ctx;
EVP_CIPHER_CTX_init(&ctx);
EVP_CipherInit_ex(&ctx, EVP_aes_128_cbc(), NULL, words, iv, 1);
EVP_CipherUpdate(&ctx, outbuf, &outlen, plaintext, strlen(plaintext));
EVP_CipherFinal_ex(&ctx, outbuf + outlen, &templ);
outlen += templ;
EVP_CIPHER_CTX_cleanup(&ctx);
}
When I check the ciphertext matches to key "example", I got a completely different ciphertext. Which part I was wrong? I am assuming the format of IV or the way I implemented IV is wrong.
回答1:
It looks like you are pretty close. By narrowing down the problem to just the encryption, the correct ciphertext can be produced. So in stead of reading the key from the file, define it as an array of unsigned chars, similar to what you did for the other variables:
unsigned char key[]={0x65,0x78,0x61,0x6d,0x70,0x6c,0x65,0x23,0x23,0x23,0x23,0x23,0x23,0x23,0x23,0x23};
Then the following code (reusing your variables) shows the successful encryption:
EVP_CIPHER_CTX ctx;
EVP_CIPHER_CTX_init(&ctx);
EVP_CipherInit_ex(&ctx, EVP_aes_128_cbc(),NULL, key, iv, 1);
EVP_CipherUpdate(&ctx, outbuf, &outlen, (unsigned char *)plaintext, strlen(plaintext));
EVP_CipherFinal_ex(&ctx, outbuf+outlen, &templ);
outlen+=templ;
EVP_CIPHER_CTX_cleanup(&ctx);
int cmpres = memcmp(outbuf, ciphertext, sizeof(ciphertext));
printf("cmpres is %d, sizeof(ciphertext) is %lu, outlen is %d\n",
cmpres, sizeof(ciphertext), outlen);
because it prints
$ ./main
cmpres is 0, sizeof(ciphertext) is 32, outlen is 32
This means that the problem is in how you read the key from the file. That is much easier to analyze than cryptographic issues :-) and I will leave it up to you to figure out that part...
By the way, make sure to check all return codes for your OpenSSL calls, it will help you to detect error situations.
来源:https://stackoverflow.com/questions/52619332/c-openssl-encryption-using-cbc-cipher-block-chaining-mode