【树莓派4B测评】+openssl库代码测试
上一贴大体测试了使用openssl命令行对文本进行摘要算法,对称加解密,非对称算法加解密和签名验签的操作,接下来我们使用代码再完成一遍。
首先是MD5摘要算法测试:
unsigned char encrypt_file_path[]="test_data.txt";
unsigned char md5_file_path[]="md5_file.bin";
//MD5摘要算法测试
int MD5_test(void)
{
MD5_CTX ctx;
unsigned char outmd[16];
char buffer[1024];
int len=0;
int i;
FILE * fp=NULL;
memset(outmd,0,sizeof(outmd));
memset(buffer,0,sizeof(buffer));
//printf("MD5 test file name:%s\r\n",encrypt_file_path);
fp=fopen(encrypt_file_path,"rb");
if(fp==NULL)
{
printf("Can't open file\n");
return 0;
}
MD5_Init(&ctx);
while((len=fread(buffer,1,1024,fp))>0)
{
MD5_Update(&ctx,buffer,len);
memset(buffer,0,sizeof(buffer));
}
fclose(fp);
MD5_Final(outmd,&ctx);
printf("file(%s) MD5 = ",encrypt_file_path);
for(i=0;i<16;i<i++)
{
printf("%02X",outmd[i]);
}
fp=fopen(md5_file_path,"wt");
if(fp==NULL)
{
printf("Can't open file\n");
return 0;
}
fwrite(outmd, 16 , 1, fp );
fclose(fp);
printf("\n");
return 0;
}
还是测试上一次的文本文件,内容是0123456789;
首先编译: gcc -o test openssl_test.c -lssl -lcrypto
然后运行:./test
接着我们测试AES加解密:
// out的内存大小需要注意 后边有 out += AES_BLOCK_SIZE
// 所以out 内存最小不能小于 AES_BLOCK_SIZE
int aes_encrypt(char* in, char* key, char* out)
{
if (!in || !key || !out)
{
return 0;
}
AES_KEY aes;
if (AES_set_encrypt_key((unsigned char*)key, 128, &aes) < 0)
{
return 0;
}
int len = strlen(in), en_len = 0;
//输入输出字符串够长。而且是AES_BLOCK_SIZE的整数倍,须要严格限制
while (en_len < len)
{
AES_encrypt((unsigned char*)in, (unsigned char*)out, &aes);
in += AES_BLOCK_SIZE;
out += AES_BLOCK_SIZE;
en_len += AES_BLOCK_SIZE;
}
return 1;
}
int aes_decrypt(char* in, char* key, char* out)
{
if (!in || !key || !out)
{
return 0;
}
AES_KEY aes;
if (AES_set_decrypt_key((unsigned char*)key, 128, &aes) < 0)
{
return 0;
}
int len = strlen(in), en_len = 0;
while (en_len < len)
{
AES_decrypt((unsigned char*)in, (unsigned char*)out, &aes);
in += AES_BLOCK_SIZE;
out += AES_BLOCK_SIZE;
en_len += AES_BLOCK_SIZE;
}
return 1;
}
//AES加解密测试
int AES_test(void)
{
AES_KEY aes;
char outbuffer[1024];
char decrypt_buffer[1024];
char buffer[1024];
int en_len,len=0;
int i;
FILE * fp=NULL;
unsigned char key[] = {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f};
memset(outbuffer,0,sizeof(outbuffer));
memset(buffer,0,sizeof(buffer));
memset(decrypt_buffer,0,sizeof(decrypt_buffer));
char *in = NULL;
char *out = NULL;
fp=fopen(encrypt_file_path,"rb");
if(fp==NULL)
{
printf("Can't open file\n");
return 0;
}
while((len=fread(buffer,1,1024,fp))>0)
{
aes_encrypt(buffer, key, outbuffer);
memset(buffer,0,sizeof(buffer));
}
fclose(fp);
printf("AES encrypt:%s\r\n",outbuffer);
aes_decrypt(outbuffer, key, decrypt_buffer);
printf("AES decrypt = %s\r\n",decrypt_buffer);
return 0;
}
还是编译运行结果如下图:
然后是RSA加解密测试:
#define PUBLICKEY "rsa_public_key.pem"
#define PRIVATEKEY "rsa_private_key.pem"
#define PASS "8888" //口令
//RSA加密测试
int RSA_test(void)
{
char outbuffer[1024];
int filelen=0;
FILE *fp = NULL;
RSA *publicRsa = NULL;
RSA *privateRsa = NULL;
if ((fp = fopen(PUBLICKEY, "r")) == NULL)
{
printf("public key path error\n");
return -1;
}
if ((publicRsa = PEM_read_RSA_PUBKEY(fp, NULL, NULL, NULL)) == NULL)
{
printf("PEM_read_RSA_PUBKEY error\n");
return -1;
}
fclose(fp);
if ((fp = fopen(PRIVATEKEY, "r")) == NULL)
{
printf("private key path error\n");
return -1;
}
OpenSSL_add_all_algorithms();//密钥有经过口令加密需要这个函数
if ((privateRsa = PEM_read_RSAPrivateKey(fp, NULL, NULL, (char *)PASS)) == NULL)
{
printf("PEM_read_RSAPrivateKey error\n");
return 0;
}
fclose(fp);
fp=fopen(encrypt_file_path,"rb");
if(fp==NULL)
{
printf("Can't open file\n");
return 0;
}
while((filelen=fread(outbuffer,1,1024,fp))>0)
{
//aes_encrypt(buffer, key, outbuffer);
//memset(buffer,0,sizeof(buffer));
}
int rsa_len = RSA_size(publicRsa);
unsigned char *encryptMsg = (unsigned char *)malloc(rsa_len);
memset(encryptMsg, 0, rsa_len);
int len = rsa_len - 11;
if (RSA_public_encrypt(len, outbuffer, encryptMsg, publicRsa, RSA_PKCS1_PADDING) < 0)
printf("RSA_public_encrypt error\n");
else
{
printf("RSA encrypt = %s\n", encryptMsg);
rsa_len = RSA_size(privateRsa);
unsigned char *decryptMsg = (unsigned char *)malloc(rsa_len);
memset(decryptMsg, 0, rsa_len);
int mun = RSA_private_decrypt(rsa_len, encryptMsg, decryptMsg, privateRsa, RSA_PKCS1_PADDING);
if ( mun < 0)
printf("RSA_private_decrypt error\n");
else
printf("RSA decrypt = %s\n", decryptMsg);
}
RSA_free(publicRsa);
RSA_free(privateRsa);
return 0;
}
这里也用之前生成的RSA公私密钥测试;
编译后运行如下图:
最后测试RSA签名验签:
//签名验签测试
#define PRIVATE_KEY_PATH ("rsa_private_key.pem")
#define SHA_WHICH NID_sha256
#define WHICH_DIGEST_LENGTH SHA256_DIGEST_LENGTH
void printHex(unsigned char *md, int len)
{
int i = 0;
for (i = 0; i < len; i++)
{
printf("0x%02x, ", md[i]);
}
printf("\n");
}
/*读取私钥*/
RSA* ReadPrivateKey(char* p_KeyPath)
{
FILE *fp = NULL;
RSA *priRsa = NULL;
printf("PrivateKeyPath[%s] \n", p_KeyPath);
/* 打开密钥文件 */
if(NULL == (fp = fopen(p_KeyPath, "r")))
{
printf( "fopen[%s] failed \n", p_KeyPath);
return NULL;
}
/* 获取私钥 */
priRsa = PEM_read_RSAPrivateKey(fp, NULL, NULL,NULL);
if(NULL == priRsa)
{
ERR_print_errors_fp(stdout);
printf( "PEM_read_RSAPrivateKey\n");
fclose(fp);
return NULL;
}
fclose(fp);
return priRsa;
}
int test_RSA_sign(void)
{
char *data = "china";
char buf[128] = {0};
RSA *privKey = NULL;
int nOutLen = sizeof(buf);
int nRet = 0;
//对数据进行sha256算法摘要
unsigned char md[WHICH_DIGEST_LENGTH];
SHA256((unsigned char *)data, strlen(data), md);
printHex(md, WHICH_DIGEST_LENGTH);
privKey = ReadPrivateKey(PRIVATE_KEY_PATH);
if (!privKey)
{
ERR_print_errors_fp (stderr);
return -1;
}
/* 签名 */
nRet = RSA_sign(SHA_WHICH, md, WHICH_DIGEST_LENGTH, buf, &nOutLen, privKey);
if(nRet != 1)
{
printf("RSA_sign err !!! \n");
goto quit;
}
printf("RSA_sign len = %d:", nOutLen);
printHex(buf, nOutLen);
quit:
RSA_free(privKey);
return 0;
}
#define PUBLIC_KEY_PATH ("rsa_public_key.pem")
#define SHA_WHICH NID_sha256
#define WHICH_DIGEST_LENGTH SHA256_DIGEST_LENGTH
/*读取公匙*/
RSA* ReadPublicKey(char* p_KeyPath)
{
FILE *fp = NULL;
RSA *pubRsa = NULL;
printf("PublicKeyPath[%s]\n", p_KeyPath);
/* 打开密钥文件 */
if(NULL == (fp = fopen(p_KeyPath, "r")))
{
printf( "fopen[%s] \n", p_KeyPath);
return NULL;
}
/* 获取公钥 */
if(NULL == (pubRsa = PEM_read_RSA_PUBKEY(fp, NULL, NULL,NULL)))
{
printf( "PEM_read_RSAPrivateKey error\n");
fclose(fp);
return NULL;
}
fclose(fp);
return pubRsa;
}
int test_RSA_verify(void)
{
char *data = "china";
char buf[128] = {0x72, 0xe8, 0xcc, 0xb0, 0x65, 0xf8, 0x6d, 0x06, 0x49, 0xdc, 0x25, \
0x8c, 0xb6, 0x04, 0x22, 0xbf, 0x72, 0x18, 0xf4, 0x9d, 0x4f, 0x37, 0x2d, 0x56, 0x62, \
0x77, 0xaf, 0x97, 0xd6, 0x09, 0xd4, 0x79, 0x25, 0xd9, 0xab, 0x3e, 0x59, 0xe3, 0xf5, \
0x65, 0x85, 0x84, 0xb3, 0x6e, 0x18, 0x9c, 0x85, 0xed, 0x58, 0xe8, 0x9a, 0x7d, 0x8c, \
0x9e, 0x6b, 0xd9, 0xd7, 0x79, 0x20, 0xf0, 0x36, 0x8e, 0xe1, 0xbc, 0xdf, 0x55, 0x5c, \
0xeb, 0xcf, 0xc6, 0x3e, 0x75, 0x37, 0x34, 0x0b, 0xa1, 0x1c, 0x81, 0x25, 0x87, 0x2b, \
0x97, 0xdb, 0x98, 0x2d, 0xb2, 0xe3, 0xf3, 0x68, 0x38, 0xfd, 0xc2, 0x25, 0x47, 0x3d, \
0x9a, 0x30, 0x44, 0x35, 0x5b, 0xd6, 0x54, 0xaf, 0xe0, 0xf7, 0x43, 0x82, 0xcf, 0x08, \
0x10, 0x86, 0x8d, 0x6d, 0xa0, 0x3e, 0x5b, 0xc4, 0x72, 0xb1, 0xe7, 0xb3, 0x49, 0x41, \
0x04, 0xe5, 0x2b, 0xc7, 0x80,
};
RSA *pubKey = NULL;
int nOutLen = sizeof(buf);
int nRet = 0;
//对数据进行sha256算法摘要
unsigned char md[WHICH_DIGEST_LENGTH];
SHA256((unsigned char *)data, strlen(data), md);
printHex(md, WHICH_DIGEST_LENGTH);
pubKey = ReadPublicKey(PUBLIC_KEY_PATH);
if (!pubKey)
{
printf("Error: can't load public key");
return -1;
}
/* 验签 */
nRet = RSA_verify(SHA_WHICH, md, WHICH_DIGEST_LENGTH, buf, nOutLen, pubKey);
printf("RSA_verify %s(ret=%d).\r\n", (1 == nRet) ? "Success" : "Failed", nRet);
RSA_free(pubKey);
return 0;
}
运行结果如下:
最后附上测试文件