算法:
AES加密算法是根据“S盒”(如下图所示)来对明文进行字节替换的,这一点也就是说对于AES算法来说其加密明文和密文大小是一样的,对于具体的S盒的构造方法和AES算法理论(手写加密算法)后面有时间再进行整理,这里先解决项目的当务之急吧。
2.OpenSSL -API讲解:
设置加密解密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:用户自设置的初始密码值,AES算法根据此初始化值来进行后续S盒的生成;
bits:密钥长度,以bit为单位,如果密钥数字是16个字节,则此参数值应为128;
key:AES_KEY对象指针;
返回值: 0 成功, -1 userkey,key为空, -2: 密钥长度不是128,192,256
void AES_encrypt(const unsigned char *in, unsigned char *out, const AES_KEY *key);
AES 加密,加密单个数据块,in,out可以是同一内存区;
in: 需要加密的数据,每次加密长度是AES_BLOCK_SIZE长度的数据,加密比较成的数据需要循环加密;
out: 加密后的数据(本文开篇已说:明文长度==密文长度);
key:AES 密钥;
void AES_decrypt(const unsigned char *in, unsigned char *out, const AES_KEY *key);
AES 解密,解密单个数据块,in,out可以是同一内存区;
in: 需要解密的数据,既然加密是按AES_BLOCK_SIZE长度来进行的(所谓的块加密),那么自然解密也是按此大小的块来循环进行;
out: 解密后的数据;
key:AES 密钥;
3.使用实例代码:
#include<Windows.h>
#include<stdio.h>
#include<stdlib.h>
#include<openssl/aes.h>
#include<openssl/pem.h>
#include<openssl/err.h>
#include <openssl/bio.h>
#pragma comment(lib, "libcrypto.lib")
#pragma comment(lib, "libssl.lib")
int main()
{
BYTE userKey[AES_BLOCK_SIZE];
unsigned char *data = (unsigned char *)malloc(AES_BLOCK_SIZE * 3);
unsigned char *encrypto = (unsigned char *)malloc(AES_BLOCK_SIZE * 3);
unsigned char *plain = (unsigned char *)malloc(AES_BLOCK_SIZE * 3);
AES_KEY key;
memcpy(userKey, "zheshiopensslexq", 16);
memset((void*)data, 'p', AES_BLOCK_SIZE * 3);
memset((void*)encrypto, 0, AES_BLOCK_SIZE * 3);
memset((void*)plain, 0, AES_BLOCK_SIZE * 3);
//设置加密key及秘钥长度
//理论上AES加密是根据S盒进行字节替换的,因此原文和密文个字节一一对应大小相同
AES_set_encrypt_key((const unsigned char *)userKey, AES_BLOCK_SIZE * 8, &key);
int len = 0;
//循环加密, 每次加密长度是AES_BLOCK_SIZE长度的数据
while (len < AES_BLOCK_SIZE * 3)
{
AES_encrypt(data + len, encrypto + len, &key);
len += AES_BLOCK_SIZE;
}
//设置解密key及秘钥长度
AES_set_decrypt_key((const unsigned char *)userKey, AES_BLOCK_SIZE * 8, &key);
len = 0;
//循环解密
//每次输入16字节,输出16字节,如果不够需要填充
while (len < AES_BLOCK_SIZE * 3)
{
AES_decrypt(encrypto + len, plain + len, &key);
len += AES_BLOCK_SIZE;
}
//解密后与元数据是否一致
if (memcmp(plain, data, AES_BLOCK_SIZE * 3) == 0)
{
printf("test success\n");
}
else
{
printf("test failed\n");
}
system("pause");
return 0;
}