Openssl库之RSA格式解析
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Openssl库之RSA格式解析相关的知识,希望对你有一定的参考价值。
参考技术A Abstract Syntax Notation dot one,抽象语法标记,描述了一种对数据进行表示、传输和解码的数据格式。它提供了一整套正规的格式用于描述对象的结构。它包含两部分:一部分描述信息内数据,数据类型及序列格式;另一部分描述如何将各部分组成消息。而不管语言上如何执行及这些数据的具体指代,也不用去管到底是什么样的应用程序;ASN1有很多实现版本,Openssl主要采用DER格式,ASN1相关的头文件参见Openssl的源码 asn1.h、asn1t.h,如下所示:
ANS1字段含义:
length —— 管理的数据长度。
type —— 管理的数据类型。
data —— 数据指针。
flags —— 标志位,跟具体数据类型有关
TLV结构即:Type类型, Lenght长度,Value值;它是一种可变格式;Type和Length的长度固定,一般那是2、4个字节;Value的长度由Length指定;
在一段TLV结构描述的数据中例如RSA密钥:
接下来按照TLV格式来分析Openssl所生成的der格式的2048位私钥,这里先说明一下pem格式的密钥和der格式的密钥的区别仅仅在于将der格式的密钥进行base64编码之后加上表头和结尾即为pem格式;
可见私钥当中包含了n、e、d值,所以理论上可以使用私钥进行加密和解密,而在一些加密锁的厂家为了节省内存,会对私钥进行删减,仅仅保留相关解密的参数;
私钥的二进制数据按照TLV结构排列如下:
Openssl查看密钥参数如下:
这里我们大致可以看出TLV结构中的Value和上述过程中的各个参数一致,但是需要说明的是Openssl在查看密钥参数时,已经做了处理保证了modulus、p、q之类有符号位的大数不为负数;所以当我们自己根据这各个参数进行拼接der格式时,具体的方法应当参见上述TLV结构说明;
30 :Type
04A2: 下面内容总长度,超过了0xFF,所以用两个字节描述,所以第二个字节为82,如果下面总长度没有超过0xFF,只用一个字节可以描述,则为81
02:表示asn1_string_st中的type
81:表示长度大于0x80,同时只用一个字节就可以描述
81:参数长度
02:表示asn1_string_st中的type
82:表示长度大于0xFF,需要用两个字节描述
0100:参数长度
02:表示asn1_string_st中的type
03:表示长度是3,小于0x80
OpenSSL笔记-生成RSA公私密钥以PEM格式到char*中(非保存为文件)
OpenSSL笔记-生成RSA公私密钥以PEM格式到char*中(非保存为文件)
不多说,直接上关键代码:
int ret = 0;
RSA *r = RSA_new();
BIGNUM *bne = BN_new();
int bits = 2048;
unsigned long e = RSA_F4;
bne = BN_new();
ret = BN_set_word(bne, e);
if(!ret)
qDebug() << "BN_set_word() error";
RSA_free(r);
BN_free(bne);
return;
ret = RSA_generate_key_ex(r, bits, bne, nullptr);
if(!ret)
qDebug() << "RSA_generate_key() error";
RSA_free(r);
BN_free(bne);
return;
BIO *bp_public = BIO_new(BIO_s_mem());;
BIO *bp_private = BIO_new(BIO_s_mem());
ret =PEM_write_bio_RSAPrivateKey(bp_private, r, NULL, NULL, 0, NULL, NULL);
if(!ret)
qDebug() << "PEM_write_bio_RSAPrivateKey() error";
BIO_free_all(bp_private);
RSA_free(r);
BN_free(bne);
return;
ret = PEM_write_bio_RSAPublicKey(bp_public, r);
if(!ret)
qDebug() << "PEM_write_bio_RSAPublicKey() error";
BIO_free_all(bp_public);
BIO_free_all(bp_private);
RSA_free(r);
BN_free(bne);
return;
//存储到Map中
size_t nPriKeyLen = BIO_pending(bp_private);
size_t nPubKeyLen = BIO_pending(bp_public);
//密钥对读取到字符串
char* pPriKey = new char[nPriKeyLen];
char* pPubKey = new char[nPubKeyLen];
BIO_read(bp_private, pPriKey, nPriKeyLen);
BIO_read(bp_public, pPubKey, nPubKeyLen);
RSAStu rsaStu;
rsaStu.privateKey = pPriKey;
rsaStu.publicKey = pPubKey;
这个RSAStu是我自己写的结构体。
打印下:
这里包含的头文件为:
#include <openssl/rsa.h>
#include <openssl/bio.h>
#include <openssl/pem.h>
以上是关于Openssl库之RSA格式解析的主要内容,如果未能解决你的问题,请参考以下文章