使用openssl命令剖析RSA私钥文件格式

Openssl提供了强大证书功能,生成密钥对、证书,颁发证书、生成crl、验证证书、销毁证书等。本文将j介绍如何利用openssl的命令分析RSA私钥文件格式,同时也将简单介绍几种常见的私钥文件格式。

 

1 生成私钥文件

openssl有多种方法生成私钥:

  • genrsa生成RSA密钥。
  • req在生成req证书请求时同时产生密钥。
  • genpkey除了可以生成RSA密钥外,还可以生成DSA、DH密钥。

 这里我使用genpkey命令生成RSA私钥文件,选择DES-EDE3-CBC算法进行加密,口令是1234:

[plain] view plain copy
  1. openssl genpkey -algorithm RSA -out privatekey.pem -pass pass:1234 -des-ede3-cbc  


命令执行后输出私钥文件 privatekey.pem,默认输出为 PEM格式,密钥长度为1024,接下来使用文本工具直接打开该文件,可以看到如下内容: 
  1. -----BEGINENCRYPTED PRIVATE KEY-----  
  2. MIICxjBABgkqhkiG9w0BBQ0wMzAbBgkqhkiG9w0BBQwwDgQIhrQ3ApYYe1ACAggA  
  3. MBQGCCqGSIb3DQMHBAgyM5zYLuXOdQSCAoAFqnCRqkpoHJTY0BpLeekzjsuzdTOq  
  4. DkgxJMi4WRt1rZNyHqarbhHCZGC9Lug/xbLW5e2ZtjYVJ+ljmFb4lUaAch4nAgoz  
  5. m0J5YyrbFKppiqlk6vkS5hKfpKbWrx5hkQzMt6OsVEQFj2U+EvOI8SVgI6LkjNmh  
  6. 7qokYxv9Inx9joM6agEUY9fXdAu53CyfjpneX95vxUHIn7hHmhxH7MYua619N7x+  
  7. JVA65b3Kj45aH3cnY/kMAQ78EN9aLpqYXzn6j9GRdUd2JMuP0IrYlREw3/z8Qn68  
  8. CwGXzGtkYnlt0xHdOG/tnmKWqBg1cY9uVx6g6JT1BUabqwxVODaMqaSsFr4o3xJo  
  9. 3TTh8TswK0V/+3JLkXtasI7V8cRj2dksccGApujmB5eymU3XXTlX3iXs481I4kmz  
  10. JOZHbqfGOpyzW6WqhMO+LebIkyIGMlCGRiJ3PNSQI9w6bfZ9FoqC6OfFKY1OEmBN  
  11. 6ALtPc+cYXeO5Msx9mbakIYRbcjlVmelPsLyvAceW/09OG909turflvYaGnM+SKd  
  12. KzWn2gFr3YwF57WZlX2jifYUUnjHVMZW7s/k6hgOxcEnvBOg4Ug/cKdNPUEB7tJx  
  13. nvsR+odHypyjgyphLEP8UmEiz3/hnPV8lhLDAPV7fKaK+zDglKqQYF3KBLh55q6h  
  14. PPe1HqahifK9EKqWOl7m1HhFPIZTex4clLy98rB3gyXnL0qx4+A7WD6uLJbU285j  
  15. IWMNq3f1c80ZPrpbhT6hd6Z9zUwfYT6gTO9gIIe4d5KVmfjNaFwSls5zaI6x7AJp  
  16. d/Xl/m1u469+J0rWyeY3D4wtahvZrKMXRrILtJ5OgkWPak2FTyMu/Hs/  
  17. -----ENDENCRYPTED PRIVATE KEY-----  

私钥经过PEM编码后在文件头尾都添加了标签,用以说明当前的文件格式。从标签内容也可以看出私钥是加密的,因为有“ ENCRYPTED”。中间的私钥内容是经过BASE64编码的,这样方便私钥的传递,例如在网络上传输,数据复制粘贴。

 

例子只是PEM文件格式的其中一种,以下是平时可能会碰到的PEM私钥格式:

PKCS#8 私钥加密格式

  1. -----BEGIN ENCRYPTED PRIVATE KEY-----  
  2. BASE64私钥内容  
  3. -----ENDENCRYPTED PRIVATE KEY-----  

PKCS#8 私钥非加密格式
  1. -----BEGIN PRIVATE KEY-----  
  2. BASE64私钥内容  
  3. -----END PRIVATEKEY-----  

Openssl ASN格式

  1. -----BEGIN RSA PRIVATE KEY-----  
  2. Proc-Type: 4,ENCRYPTED  
  3. DEK-Info:DES-EDE3-CBC,4D5D1AF13367D726  
  4. BASE64私钥内容  
  5. -----END RSA PRIVATE KEY-----  


除了以上几种,还有微软的PVK格式;以及DER编码格式,就是在使用PEM编码前的数据,由于没有密码保护,平时很少直接使用。

 

Openssl ASN格式在加密私钥数据时只能用MD5算法生成key,而且只迭代计算了1次。

所以从1.0.0开始Openssl把PKCS#8格式作为默认格式,可以为私钥文件提供更好的安全性和扩展性。

我们这里就针对PKCS#8格式的私钥进行讨论。 如果大家想要研究其他格式,可以使用以下命令:

 genrsa 生成ASN格式

 rsa 生成或转换为PVK格式

  1. openssl rsa -in privatekey.pem -out privatekey.pvk -outform PVK  
  

2 分析私钥文件 

使用asn1parse命令读取私钥ASN.1结构,其中–i表示输出使用缩进格式。

openssl asn1parse -i -in privatekey.pem 

  1.  0:d<
  • 5
    点赞
  • 25
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
你可以使用OpenSSL库来读取RSA私钥文件,并将其转换为JWK格式。以下是一个简单的示例代码,你可以根据自己的需要进行修改: ```c++ #include <openssl/rsa.h> #include <openssl/pem.h> #include <openssl/evp.h> #include <openssl/bio.h> #include <openssl/buffer.h> #include <iostream> // 将二进制数据编码为Base64字符串 std::string base64_encode(const unsigned char* input, size_t length) { BIO *bmem = nullptr, *b64 = nullptr; BUF_MEM *bptr = nullptr; b64 = BIO_new(BIO_f_base64()); bmem = BIO_new(BIO_s_mem()); b64 = BIO_push(b64, bmem); BIO_write(b64, input, length); BIO_flush(b64); BIO_get_mem_ptr(b64, &bptr); std::string result(bptr->data, bptr->length - 1); BIO_free_all(b64); return result; } int main() { RSA *rsa = nullptr; EVP_PKEY *pkey = nullptr; std::string private_key_file = "/path/to/private/key/file.pem"; // 读取RSA私钥文件 FILE *fp = fopen(private_key_file.c_str(), "rb"); if (!fp) { std::cerr << "Failed to open private key file." << std::endl; return 1; } rsa = PEM_read_RSAPrivateKey(fp, nullptr, nullptr, nullptr); fclose(fp); if (!rsa) { std::cerr << "Failed to load RSA private key." << std::endl; return 1; } // 将RSA私钥转换为EVP格式 pkey = EVP_PKEY_new(); if (!pkey) { std::cerr << "Failed to create EVP_PKEY object." << std::endl; return 1; } if (EVP_PKEY_assign_RSA(pkey, rsa) != 1) { std::cerr << "Failed to assign RSA to EVP_PKEY." << std::endl; EVP_PKEY_free(pkey); return 1; } // 将EVP格式私钥转换为JWK格式 std::cout << "{"; std::cout << "\"kty\": \"RSA\","; std::cout << "\"n\": \"" << base64_encode(rsa->n->data, rsa->n->length) << "\","; std::cout << "\"e\": \"" << base64_encode(rsa->e->data, rsa->e->length) << "\","; std::cout << "\"d\": \"" << base64_encode(rsa->d->data, rsa->d->length) << "\","; std::cout << "\"p\": \"" << base64_encode(rsa->p->data, rsa->p->length) << "\","; std::cout << "\"q\": \"" << base64_encode(rsa->q->data, rsa->q->length) << "\","; std::cout << "\"dp\": \"" << base64_encode(rsa->dmp1->data, rsa->dmp1->length) << "\","; std::cout << "\"dq\": \"" << base64_encode(rsa->dmq1->data, rsa->dmq1->length) << "\","; std::cout << "\"qi\": \"" << base64_encode(rsa->iqmp->data, rsa->iqmp->length) << "\""; std::cout << "}" << std::endl; // 释放资源 EVP_PKEY_free(pkey); RSA_free(rsa); return 0; } ``` 在上面的代码中,我们首先使用PEM_read_RSAPrivateKey函数从私钥文件中读取RSA私钥,然后将其转换为EVP_PKEY格式。最后,我们将EVP_PKEY格式的私钥转换为JWK格式,并使用base64_encode函数将二进制数据编码为Base64字符串。 需要注意的是,JWK格式中的各个字段都需要进行Base64编码。在上面的代码中,我们使用了base64_encode函数来实现这一功能。你需要自己实现这个函数或者使用现成的Base64库来完成编码操作。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值