OpenSSL中AES加密的用法

来源:互联网 发布:差分方程matlab编程 编辑:程序博客网 时间:2024/05/29 09:09

《OpenSSL中AES加密的用法》
作者: 游蓝海
原文链接: http://blog.csdn.net/you_lan_hai/article/details/50992719
转载请注明出处

使用API的时候,需要特别小心数据长度,我在初次使用的时候简直被弄的晕头转向,遂作此文留个备忘。一般没有指定长度的参数,默认都是16(AES_BLOCK_SIZE)个字节。输出数据的长度一般都是16字节的倍数,否则会出现数组越界访问。
以下API中,encrypt表示加密,decrypt表示解密。

1.生成加密/解密的Key

int AES_set_encrypt_key(const unsigned char *userKey, const int bits,                        AES_KEY *key);int AES_set_decrypt_key(const unsigned char *userKey, const int bits,                        AES_KEY *key);

参数说明:

参数名称 描述 userKey 用户指定的密码。注意:只能是16、24、32字节。如果密码字符串长度不够,可以在字符串末尾追加一些特定的字符,或者重复密码字符串,直到满足最少的长度。 bits 密码位数。即userKey的长度 * 8,只能是128、192、256位。 key 向外输出参数。

如果函数调用成功,返回0,否则是负数。

2.使用AES加密/解密

void AES_encrypt(const unsigned char *in, unsigned char *out,                 const AES_KEY *key);void AES_decrypt(const unsigned char *in, unsigned char *out,                 const AES_KEY *key);

参数说明:

参数名称 描述 in 输入数据。必须是16字节。 out 输出数据。必须是16字节。 key 使用AES_set_encrypt/decrypt_key生成的Key。

AES_encrypt/AES_decrypt一次只处理16个字节。如果输入数据较长,你需要使用循环语句,每16个字节处理一次,直到所有数据处理完毕。如果数据不足16字节,可以用0填充至16字节。

3.使用AES CBC加密/解密

void AES_cbc_encrypt(const unsigned char *in, unsigned char *out,                     size_t length, const AES_KEY *key,                     unsigned char *ivec, const int enc);

参数说明:

参数名称 描述 in 输入数据。长度任意。 out 输出数据。能够容纳下输入数据,且长度必须是16字节的倍数。 length 输入数据的实际长度。 key 使用AES_set_encrypt/decrypt_key生成的Key。 ivec 可读写的一块内存。长度必须是16字节。 enc 是否是加密操作。AES_ENCRYPT表示加密,AES_DECRYPT表示解密。

这个函数比AES_encrypt多了一个ivec参数,ivec的内容可以任意指定,但是加密和解密操作必须使用同样的数据。在AES_cbc_encrypt底层,实际上是每16个字节做一次处理,先和ivec做异或运算,然后调用AES_encrypt函数进行加密。
AES_cbc_encrypt在加密的过程中会修改ivec的内容,因此ivec参数不能是一个常量,而且不能在传递给加密函数后再立马传递给解密函数,必须重新赋值之后再传递给解密函数。

关于输出数据的长度
虽然输出数据缓冲区的长度必须是16字节的倍数,但是加密完成后,比输入长度多出来的输出数据是可以丢弃的。

关于输入数据的长度不必是16字节的倍数(做个备忘):
下面是AES_cbc_encrypt函数的底层实现代码

    ...     //处理16字节倍数的数据    while (len >= 16) {            for (n = 0; n < 16; ++n)                out[n] = in[n] ^ iv[n];            (*block) (out, out, key); //调用AES_encrypt处理数据            iv = out;            len -= 16;            in += 16;            out += 16;        }    //当数据小于16字节的时候,进入下面的循环    while (len) {         for (n = 0; n < 16 && n < len; ++n)            out[n] = in[n] ^ iv[n];        for (; n < 16; ++n)            out[n] = iv[n]; //使用ivec补齐不足16字节的部分        (*block) (out, out, key); //调用AES_encrypt处理数据        iv = out;        if (len <= 16)            break;        len -= 16;        in += 16;        out += 16;    }

4结尾

其他加密函数我还没有用过,在此就不继续列举了,但是参数跟上面几个相似,弄明白上面的就不成问题。

0 0
原创粉丝点击