[Raspberry Pi 4B review] + openssl library code test
The previous post roughly tested the use of the openssl command line to perform digest algorithms, symmetric encryption and decryption, asymmetric algorithm encryption and decryption, and signature verification on text. Next, we will use the code to complete it again.
First is the MD5 digest algorithm test:
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;
}
Let’s test the text file from last time. The content is 0123456789.
First compile: gcc -o test openssl_test.c -lssl -lcrypto
Then run: ./test
The MD5 value also corresponds to the value in the previous post;
Next we test AES encryption and decryption:
// 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;
}
The compilation and running results are as follows:
After decryption, we get the original text;
Then comes the RSA encryption and decryption test:
#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;
}
Here we also use the previously generated RSA public and private key test;
After compiling and running, the following figure is shown:
After RSA decryption, the original text was also obtained;
Finally test the RSA signature verification:
//签名验签测试
#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;
}
The results are as follows:
You can see that the signature verification has passed.
Finally, attach the test file