[原创] 【树莓派4B测评】+openssl库代码测试

29447945   2020-8-14 19:40 楼主

【树莓派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

image.png MD5值和上一贴中的值也能对应;

接着我们测试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;
}

还是编译运行结果如下图:

image.png 解密后得到原文;

然后是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公私密钥测试;

编译后运行如下图:

image.png 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;
}

运行结果如下:

image.png 可以看到验签通过了。

最后附上测试文件

游客,如果您要查看本帖隐藏内容请回复

回复评论 (3)

1 来自 2楼 okhxyyo 

玩板看这里: https://bbs.eeworld.com.cn/elecplay.html EEWorld测评频道众多好板等你来玩,还可以来频道许愿树许愿说说你想要玩的板子,我们都在努力为大家实现!
点赞  2020-8-14 20:14

不错

点赞  2020-8-14 20:27
6666
点赞  2020-8-20 17:25
电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 京公网安备 11010802033920号
    写回复