linux openssl 16进制的模数n和指数e转换成pkcs.pem证书秘钥格式

Posted 听我吹牛逼

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了linux openssl 16进制的模数n和指数e转换成pkcs.pem证书秘钥格式相关的知识,希望对你有一定的参考价值。

rsa加解密在pc电脑端已经有了非常广泛的应用,但是在pc端进行rsa加解密大多数都是使用base64编码格式,而在嵌入式开发中一般进行数据加解密都使用16进制的数据格式,因此要在嵌入式开发中使用rsa加解密就有一个编码转换的问题。

通常我们在嵌入式单片机开发时用的rsa秘钥都是16进制的hex数组,类似于下面这样

char pubkey_n[128]={  //1024 bit RSA 公钥 模数
0x01,0x02,0x03,0x04 ......
}
char pubkey_e[4]={ //1024 bit RSA 公钥 指数
0x00,0x01,0x00,0x01 
}

而在linux或者pc环境下用的秘钥通常是.pem后缀的文件。类似下面这种

-----BEGIN PUBLIC KEY-----
MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQC/x7JUUCPHGe6y50G4oYpygGoX
M5GVreltOtOEHWhr5qCkNtRVAUrpYdUBj/dOALiKy5rOTp4RKX9b9E+ZxJhYDfeA
l6dSkhe+pAvwem7PkGTvlI+glh1kK7WhXwFPzQNzrLcV51K4sP0RqC8WqMErXx9n
1XCCVAbF3L5KZ4I7OwIDAQAB
-----END PUBLIC KEY-----

如何将 16进制的hex秘钥转换为pem格式呢?

经过一番研究,发现其实也不难,用下面这段代码即可完成

//------------------------------------------------------------------------------
// Funtion: RSA 公钥数组生成openssl 标准 pem 格式证书
// Input  : 输入公钥 N和E,和N,E的长度(字节),生成pem证书路径和证书名字path
// Output :
// Return :
// Info   :
//------------------------------------------------------------------------------
int RSA_PubKey_Creat(const unsigned char* dn,int dn_len,const unsigned char* de,int de_len,char* path)
{
	BIGNUM* n = BN_bin2bn(dn, dn_len, NULL);
	BIGNUM* e = BN_bin2bn(de, de_len, NULL);
	RSA* rsa = RSA_new();
	int ret =0;

	ret = RSA_set0_key(rsa, n, e, NULL);
	if(ret == 0)
	{
		 printf("RSA Set Key Error !\\r\\n");
		 ret = -1;
	}
	else
	{
		FILE* file = fopen(path, "w");
		PEM_write_RSA_PUBKEY(file, rsa);
		fflush(file);
		fclose(file);
		ret = 1;
	}

	RSA_free(rsa);
	BN_clear_free(e);
	BN_clear_free(n);

	return ret;
}

使用方法如下

RSA_PubKey_Creat(pubkey_n,128,pubkey_e,4,"/var/volatile/tmp/pubkey.pem");

这样就能在/var/volatile/tmp/路径下生成pubkey.pem,证书文件了。

私钥证书有了,如何进行16进制的数据加解密呢?

void pub_encrypt(char *str, int lenth,char* out,char *path_key)
 {
     RSA  *p_rsa = NULL;
     FILE *file = NULL;

     if((file = fopen(path_key, "rb")) == NULL)
     {
        perror("pub key  error  ");
         goto End;
     }

     if((p_rsa = PEM_read_RSA_PUBKEY(file, NULL,NULL,NULL )) == NULL)
     {
         ERR_print_errors_fp(stdout);
         goto End;
     }

     memset(out, 0, 256);

     if(RSA_public_encrypt(lenth, (unsigned char*)str, (unsigned char*)out, p_rsa,RSA_NO_PADDING) < 0)
     {
     perror("public_encrypt error ");
     goto End;
     }

 End:

     if(p_rsa)    RSA_free(p_rsa);
     if(file)     fclose(file);

 }

验证测试

 //私钥加密,用公钥解密,解密后out数组内容和in数组内容一致
int  main()
{
	char in[256];
	char out[256];
	char enc[256];
	int i=0;
	for(i=0;i<256;i++)
	{
		in[i]=i;    //随意填充16进制数据进行加密
		out[i]=0;   //清空
		enc[i]=0;   
	}
	RSA_PubKey_Creat(pubkey_n,128,pubkey_e,4,"/var/volatile/tmp/pubkey.pem");、//16进制数组生成私钥 pem文件
	pub_encrypt(in, 128,enc,"/var/volatile/tmp/pubkey.pem");    //公钥加密,加密后数据保存在enc数组
	pri_decrypt(enc, 128,out,"/var/volatile/tmp/key.pri");    //私钥解密 , 私钥解密,解密后内容在out数组
}

代码基于嵌入式linux,openssl 1.1 版本  编译验证OK。

以上是关于linux openssl 16进制的模数n和指数e转换成pkcs.pem证书秘钥格式的主要内容,如果未能解决你的问题,请参考以下文章

linux openssl 16进制的模数n和指数e转换成pkcs.pem证书秘钥格式

linux openssl 16进制的模数n和指数e转换成pkcs.pem证书秘钥格式

如何将证书转换为十进制模数和指数

生成具有预定义模数和指数的公钥

使用Python从公钥获取RSA指数和模数

如何验证 Apple 登录的 Jwt 令牌(后端验证)。如何从 Java 中的模数和指数 (n,e) 生成 RSA 公钥