C-使用CBC(密码块链接)模式的OpenSSL加密 [英] C - OpenSSL encryption using CBC (Cipher Block Chaining) mode

查看:206
本文介绍了C-使用CBC(密码块链接)模式的OpenSSL加密的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用 OpenSSL 的C-API,但是我对 IV (初始化矢量).

I am using C-API of OpenSSL, but I am confused on how IV (Initialization Vector) is used in OpenSSL.

说,我有

plaintext.txt file = "This is a top secret."
Key                = "example#########"
IV                 = 010203040506070809000a0b0c0d0e0f

当我使用 OpenSSL AES-128-CBC 对此进行加密时,我应该得到:

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

我得到:

xxd -p ciphertext.bin 
e5accdb667e8e569b1b34f423508c15422631198454e104ceb658f5918800c22

但是我得到了不同的密文使用C

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

键(示例)在words.txt文件中.

我的加密过程:

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

当我检查密文与密钥"example"的匹配时,我得到了完全不同的密文.我错了哪一部分?我认为IV的格式或我实施IV的方式是错误的.

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.

推荐答案

您似乎很接近.通过将问题缩小到仅加密,就可以生成正确的密文.因此,与其从文件中读取密钥,不如将其定义为一个无符号字符数组,类似于您对其他变量所做的操作:

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

因为它打印

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

顺便说一句,请确保检查您的OpenSSL调用的所有返回码,这将帮助您检测错误情况.

By the way, make sure to check all return codes for your OpenSSL calls, it will help you to detect error situations.

这篇关于C-使用CBC(密码块链接)模式的OpenSSL加密的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆