PEM文件

OpenSSL 使用 PEM 文件格式存储证书和密钥。PEM 实质上是 Base64 编码的二进制内容,再加上开始和结束行,如证书文件的
-----BEGIN CERTIFICATE-----

-----END CERTIFICATE-----
。在这些标记外面可以有额外的信息,如编码内容的文字表示。文件是 ASCII 的,可以用任何文本编辑程序打开它们。观察这个 示例 PEM 文件

 

Certificate: Data: Version: 3 (0x2) Serial Number: 1 (0x1) Signature Algorithm: md5WithRSAEncryption Issuer: C=UK, ST=Hampshire, L=Winchester, O=IBM, OU=JTC, CN=Paul H Abbott/Email=Paul_H_Abbott@uk.ibm.com Validity Not Before: Dec 19 15:17:27 2003 GMT Not After : Dec 18 15:17:27 2004 GMT Subject: C=UK, ST=Hampshire, L=Winchester, O=Private, OU=Home, CN=Paul Abbott/Email=Paul.Abbott@bcs.org.uk Subject Public Key Info: Public Key Algorithm: rsaEncryption RSA Public Key: (1024 bit) Modulus (1024 bit): 00:b9:64:00:40:ad:d1:06:45:a2:ae:fb:32:91:64: 04:4b:17:23:fa:cf:36:64:17:9a:51:9a:28:46:c9: db:91:ea:d0:ee:72:2c:81:31:ba:35:a6:c6:ce:d8: 6d:3d:77:46:57:aa:bd:33:28:19:e4:d6:4f:13:f6: 74:af:5f:3c:ee:b8:7f:03:b4:13:53:aa:df:b5:7d: fc:ad:81:4d:c0:11:85:28:82:da:d9:bf:22:e4:6f: 34:04:42:9b:d6:f3:da:20:88:b5:38:4f:21:fc:d5: dc:5e:00:dc:eb:19:c6:31:ad:78:88:24:4e:40:38: 30:73:80:a7:55:1e:f6:30:9d Exponent: 65537 (0x10001) X509v3 extensions: X509v3 Basic Constraints: CA:FALSE Netscape Comment: OpenSSL Generated Certificate X509v3 Subject Key Identifier: F5:7E:D6:46:75:AA:7B:20:7D:B1:6D:96:6B:F9:24:A4:B9:15:A6:55 X509v3 Authority Key Identifier: keyid:D2:90:DA:BA:17:9A:0D:56:21:F8:56:22:04:23:37:C3:72:7C:CC:FE DirName:/C=UK/ST=Hampshire/L=Winchester/O=IBM/OU=JTC/CN=Paul H Abbott/Email=Paul_H_Abbott@uk.ibm.com serial:00 Signature Algorithm: md5WithRSAEncryption 08:ec:99:13:58:2b:99:b9:77:b8:80:c5:3b:2f:73:e5:6c:97: a8:6b:8c:1f:a2:cf:23:48:6c:df:de:d1:23:64:b0:fd:73:bb: 31:c4:28:99:6a:b1:0f:d5:d7:da:ab:ac:e5:31:85:ff:46:32: 5b:0d:83:4a:d6:b5:41:a8:4e:c3:8e:2d:2b:2e:f6:ef:a0:ab: 9a:26:0c:87:16:c8:d4:4f:f2:e6:09:a3:2b:02:5c:8d:ea:b7: c2:3c:e1:eb:22:75:7b:68:5e:de:4c:5d:40:59:06:a2:d5:d5: 75:f6:fe:ac:5a:e7:8d:62:56:9a:fd:15:c6:a0:4a:4a:14:1c: c8:62 -----BEGIN CERTIFICATE----- MIIDvzCCAyigAwIBAgIBATANBgkqhkiG9w0BAQQFADCBkzELMAkGA1UEBhMCVUsx EjAQBgNVBAgTCUhhbXBzaGlyZTETMBEGA1UEBxMKV2luY2hlc3RlcjEMMAoGA1UE ChMDSUJNMQwwCgYDVQQLEwNKVEMxFjAUBgNVBAMTDVBhdWwgSCBBYmJvdHQxJzAl BgkqhkiG9w0BCQEWGFBhdWxfSF9BYmJvdHRAdWsuaWJtLmNvbTAeFw0wMzEyMTkx NTE3MjdaFw0wNDEyMTgxNTE3MjdaMIGTMQswCQYDVQQGEwJVSzERMA8GA1UECBMI SGFtc2hpcmUxEzARBgNVBAcTCldpbmNoZXN0ZXIxEDAOBgNVBAoTB1ByaXZhdGUx DTALBgNVBAsTBEhvbWUxFDASBgNVBAMTC1BhdWwgQWJib3R0MSUwIwYJKoZIhvcN AQkBFhZQYXVsLkFiYm90dEBiY3Mub3JnLnVrMIGfMA0GCSqGSIb3DQEBAQUAA4GN ADCBiQKBgQC5ZABArdEGRaKu+zKRZARLFyP6zzZkF5pRmihGyduR6tDuciyBMbo1 psbO2G09d0ZXqr0zKBnk1k8T9nSvXzzuuH8DtBNTqt+1ffytgU3AEYUogtrZvyLk bzQEQpvW89ogiLU4TyH81dxeANzrGcYxrXiIJE5AODBzgKdVHvYwnQIDAQABo4IB HzCCARswCQYDVR0TBAIwADAsBglghkgBhvhCAQ0EHxYdT3BlblNTTCBHZW5lcmF0 ZWQgQ2VydGlmaWNhdGUwHQYDVR0OBBYEFPV+1kZ1qnsgfbFtlmv5JKS5FaZVMIHA BgNVHSMEgbgwgbWAFNKQ2roXmg1WIfhWIgQjN8NyfMz+oYGZpIGWMIGTMQswCQYD VQQGEwJVSzESMBAGA1UECBMJSGFtcHNoaXJlMRMwEQYDVQQHEwpXaW5jaGVzdGVy MQwwCgYDVQQKEwNJQk0xDDAKBgNVBAsTA0pUQzEWMBQGA1UEAxMNUGF1bCBIIEFi Ym90dDEnMCUGCSqGSIb3DQEJARYYUGF1bF9IX0FiYm90dEB1ay5pYm0uY29tggEA MA0GCSqGSIb3DQEBBAUAA4GBAAjsmRNYK5m5d7iAxTsvc+Vsl6hrjB+izyNIbN/e 0SNksP1zuzHEKJlqsQ/V19qrrOUxhf9GMlsNg0rWtUGoTsOOLSsu9u+gq5omDIcW yNRP8uYJoysCXI3qt8I84esidXtoXt5MXUBZBqLV1XX2/qxa541iVpr9FcagSkoU HMhi -----END CERTIFICATE-----


openssl之PEM系列之1---PEM编码文件结构介绍


EM全称是Privacy Enhanced Mail,该标准定义了加密一个准备要发送邮件的标准。它的基本流程是这样的:
1.信息转换为ASCII码或其它编码方式;
2.使用对称算法加密转换了的邮件信息;
3.使用BASE64对加密后的邮件信息进行编码;
4.使用一些头定义对信息进行封装,这些头信息格式如下(不一定都需要,可选的):
 Proc-Type,4:ENCRYPTED 
 DEK-Info: cipher-name, ivec 
   其中,第一个头信息标注了该文件是否进行了加密,该头信息可能的值包括ENCRYPTED(信息已经加密和签名)、MIC-ONLY(信息经过数字签名但 没有加密)、MIC-CLEAR(信息经过数字签名但是没有加密、也没有进行编码,可使用非PEM格式阅读)以及CLEAR(信息没有签名和加密并且没有 进行编码,该项好象是openssl自身的扩展,但是并没有真正实现);;第二个头信息标注了加密的算法以及使用的ivec参量,ivec其实在这儿提供 的应该是一个随机产生的数据序列,与块加密算法中要使用到的初始化变量(IV)不一样。
5.在这些信息的前面加上如下形式头标注信息:
-----BEGIN PRIVACY-ENHANCED MESSAGE-----
  在这些信息的后面加上如下形式尾标注信息:
-----END PRIVACY-ENHANCED MESSAGE----- 

上面是openssl的PEM文件的基本结构,需要注意的是,Openssl并没有实现PEM的全部标准,它只是对openssl中需要使用的一些选项做了实现,详细的PEM格式,请参考RFC1421-1424。

下面是一个PEM编码的经过加密的DSA私钥的例子:
-----BEGIN DSA PRIVATE KEY-----
Proc-Type: 4,ENCRYPTED
DEK-Info: DES-EDE3-CBC,F80EEEBEEA7386C4

GZ9zgFcHOlnhPoiSbVi/yXc9mGoj44A6IveD4UlpSEUt6Xbse3Fr0KHIUyQ3oGnS
mClKoAp/eOTb5Frhto85SzdsxYtac+X1v5XwdzAMy2KowHVk1N8A5jmE2OlkNPNt
of132MNlo2cyIRYaa35PPYBGNCmUm7YcYS8O90YtkrQZZTf4+2C4kllhMcdkQwkr
FWSWC8YOQ7w0LHb4cX1FejHHom9Nd/0PN3vn3UyySvfOqoR7nbXkrpHXmPIr0hxX
RcF0aXcV/CzZ1/nfXWQf4o3+oD0T22SDoVcZY60IzI0oIc3pNCbDV3uKNmgekrFd
qOUJ+QW8oWp7oefRx62iBfIeC8DZunohMXaWAQCU0sLQOR4yEdeUCnzCSywe0bG1
diD0KYaEe+Yub1BQH4aLsBgDjardgpJRTQLq0DUvw0/QGO1irKTJzegEDNVBKrVn
V4AHOKT1CUKqvGNRP1UnccUDTF6miOAtaj/qpzra7sSk7dkGBvIEeFoAg84kfh9h
hVvF1YyzC9bwZepruoqoUwke/WdNIR5ymOVZ/4Liw0JdIOcq+atbdRX08niqIRkf
dsZrUj4leo3zdefYUQ7w4N2Ns37yDFq7
-----END DSA PRIVATE KEY-----

有时候PEM编码的东西并没有经过加密,只是简单进行了BASE64编码,下面是一个没有加密的证书请求的例子:
-----BEGIN CERTIFICATE REQUEST-----
MIICVTCCAhMCAQAwUzELMAkGA1UEBhMCQVUxEzARBgNVBAgTClNvbWUtU3RhdGUx
ITAfBgNVBAoTGEludGVybmV0IFdpZGdpdHMgUHR5IEx0ZDEMMAoGA1UEAxMDUENB
MIIBtTCCASkGBSsOAwIMMIIBHgKBgQCnP26Fv0FqKX3wn0cZMJCaCR3aajMexT2G
lrMV4FMuj+BZgnOQPnUxmUd6UvuF5NmmezibaIqEm4fGHrV+hktTW1nPcWUZiG7O
Zq5riDb77Cjcwtelu+UsOSZL2ppwGJU3lRBWI/YV7boEXt45T/23Qx+1pGVvzYAR
5HCVW1DNSQIVAPcHMe36bAYD1YWKHKycZedQZmVvAoGATd9MA6aRivUZb1BGJZnl
aG8w42nh5bNdmLsohkj83pkEP1+IDJxzJA0gXbkqmj8YlifkYofBe3RiU/xhJ6h6
kQmdtvFNnFQPWAbuSXQHzlV+I84W9srcWmEBfslxtU323DQph2j2XiCTs9v15Als
QReVkusBtXOlan7YMu0OArgDgYUAAoGBAKbtuR5AdW+ICjCFe2ixjUiJJzM2IKwe
6NZEMXg39+HQ1UTP

TmfLZLps+rZfolHDXuRKMXbGFdSF0nXYzotPCzi7GauwEJTZ
yr27ZZjA1C6apGSQ9GzuwNvZ4rCXystVEagAS8OQ4H3D4dWS17Zg31ICb5o4E5r0
z09o/Uz46u0VoAAwCQYFKw4DAhsFAAMxADAuAhUArRubTxsbIXy3AhtjQ943AbNB
nSICFQCu+g1iW3jwF+gOcbroD4S/ZcvB3w==
-----END CERTIFICATE REQUEST-----

可以看到,该文件没有了前面两个头信息。大家如果经常使用openssl的应用程序,就对这些文件格式很熟悉了。



1.  描述:

Openssl使用PEM(RFC 1421-1424)文档格式,如果使用其他语言包,则需要将此格式进行解码并将各个私公钥加入。

2.  说明:

a)         首先使用BASE64解码,如果是非ANSI TXT格式,需要做转换。

b)        一个RSA私钥包含一下信息(1024位):

>openssl rsa -in key.pem -noout -text

modulus:

00:d5:00:b2:18:c3:04:d1:ac:80:c6:22:a0:cc:5c:

f1:c0:4a:83:95:e5:c9:88:ae:31:64:ab:e1:15:42:

de:1a:da:bc:f5:d2:05:05:74:9d:d3:86:94:9b:9d:

74:bb:e5:72:a4:b8:40:27:61:88:d4:ac:20:b0:2b:

1c:1e:d7:9b:43:c5:06:b6:3a:b4:42:f0:5a:22:38:

23:74:99:4a:50:f1:f1:54:11:5a:44:0b:40:cf:83:

8a:73:6c:34:15:98:0a:7d:cf:0e:e5:00:8d:07:40:

f7:7d:fb:3f:64:35:1b:5d:a3:40:a9:51:fa:92:7d:

34:ef:03:fe:e0:59:56:31:25                  

数量:128

 

publicExponent:

01:00:01

数量:3

 

privateExponent:

11:e2:a8:11:ba:36:6a:60:c0:c3:62:5e:fc:2a:05:           

c6:ae:bb:13:d8:22:af:0e:69:69:59:a1:61:c6:a6:           

9d:bc:a6:47:41:e6:58:09:ed:c2:b8:37:3c:45:e1:           

6a:71:9e:c9:c4:0a:e7:03:a2:98:b1:07:61:a3:8d:           

0d:ed:ee:c4:7f:ca:fe:7d:c1:2e:2f:ca:3d:16:81:            

4f:bf:ad:6a:03:ca:d7:80:dc:57:03:fe:cf:1f:37:           

05:8d:58:79:14:01:1f:66:42:e4:f1:b6:9d:f1:01:           

37:12:f4:d8:15:c0:cc:9b:fc:ea:55:cb:2f:ba:46:           

fd:17:11:7e:43:b5:d1:15                                 

数量:128

 

prime1:

00:ed:a0:e8:25:cc:1c:aa:f5:44:e2:78:9e:54:2c:

1d:60:cb:8f:32:b3:68:6d:b3:1d:cd:a9:8c:2a:ca:

02:bc:7b:a7:8b:06:1d:fa:af:4f:8c:26:81:54:12:

ec:7d:92:20:77:85:ef:6e:06:a6:8b:9c:eb:ab:6a:

e6:a1:83:6d:a3                              

数量:64(去掉开头的0)

 

prime2:

00:e5:78:66:5a:84:22:51:78:2d:14:fc:5f:f8:4e:

45:5f:e3:b2:5e:5b:50:a4:f5:55:e0:f3:0e:98:2c:

52:61:c2:50:df:f4:b7:bc:6e:69:3e:99:ff:1c:50:

a8:89:05:7a:2b:25:91:56:a5:a6:8f:8a:ec:80:82:

fa:eb:09:c2:97                              

数量:64(去掉开头的0)

 

exponent1:

00:89:e6:26:d2:48:71:1a:84:db:44:d1:da:8f:de:

49:ee:32:33:17:a9:25:a1:03:a0:f8:08:bc:5e:d8:

7c:5e:05:24:65:79:57:4c:73:10:26:b4:f1:b8:68:

82:f5:1c:27:db:34:ce:8d:7b:2e:8b:36:b5:4c:f4:

ec:82:2e:53:21                              

数量:64(去掉开头的0)

 

exponent2:

6a:16:a6:e3:74:31:55:8f:04:f0:ad:d9:44:b8:13:

14:c8:f5:5e:f0:42:b1:71:07:5a:2f:a4:f0:af:95:

0a:c3:46:96:b3:d1:fa:58:e5:69:5e:d2:f5:e9:48:

71:c8:c9:79:87:2d:d1:6c:56:3c:08:d3:5c:7a:b1:

bc:d6:4f:53                                 

数量:64

 

coefficient:

62:dd:3f:f4:c7:30:c7:77:5e:8c:ae:c8:11:c1:23:

b0:6d:7d:07:54:8f:e7:12:1d:e1:00:ad:70:55:12:

43:f6:6f:a9:d7:94:9d:33:15:66:16:2d:d1:76:13:

33:0d:ae:6f:e3:3f:46:4b:4a:78:14:02:2e:72:66:

59:0c:2d:6a                                 

数量:64

c)        与C#中RSAParameter结构体对应表:

说明

PEM

RSAParameter

 

Modulus

modulus

 

Exponent

Exponent

 

prime1

P

 

exponent1

Q

 

prime2

DP

 

exponent2

DQ

 

coefficient

InverseQ

 

privateExponent

D

 

d)        PEM偏移(1024位,以0为开始字符,十进制)

说明

PEM私钥

PEM公钥

长度

Modulus

11

29

128

PublicExponent

141

159

3

PrivateExponent

147

×

128

Prime1

278

×

64

Prime2

345

×

64

Exponent1

412

×

64

Exponent2

478

×

64

Coefficient

545

×

64

e)         例子程序(C#):

/// <summary>

         /// 用得到的解码值来得到相应的Parameter(BASE64->RSAParameter)

         /// </summary>

         /// <param name="hashKey">源</param>

/// <param name="type">0私钥1公钥</param>

/// <returns></returns>

public RSAParameters getKeyPara(string hashKey,int type)

         {

              RSAParameters rsaP=new RSAParameters();

              byte[] tmpKeyNoB64=Convert.FromBase64String(hashKey);

              int pemModulus=128;

              int pemPublicExponent=3;

              int pemPrivateExponent=128;

              int pemPrime1=64;

              int pemPrime2=64;

              int pemExponent1=64;

              int pemExponent2=64;

              int pemCoefficient=64;

 

             

              byte[] arrPemModulus=new byte[128];

              byte[] arrPemPublicExponent=new byte[3];

              byte[] arrPemPrivateExponent=new byte[128];

              byte[] arrPemPrime1=new byte[64];

              byte[] arrPemPrime2=new byte[64];

              byte[] arrPemExponent1=new byte[64];

              byte[] arrPemExponent2=new byte[64];

              byte[] arrPemCoefficient=new byte[64];

 

              if(type==0)//私钥

              {

                   //Modulus

                   for(int i=0;i<pemModulus;i++)

                   {

                       arrPemModulus[i]=tmpKeyNoB64[11+i];

                   }

                   rsaP.Modulus=arrPemModulus;

 

                   //PublicExponent

                   for(int i=0;i<pemPublicExponent;i++)

                   {

                       arrPemPublicExponent[i]=tmpKeyNoB64[141+i];

                   }

                   rsaP.Exponent=arrPemPublicExponent;

 

                   //PrivateExponent

                   for(int i=0;i<pemPrivateExponent;i++)

                   {

                       arrPemPrivateExponent[i]=tmpKeyNoB64[147+i];

                   }

                   rsaP.D=arrPemPrivateExponent;

 

                   //Prime1

                   for(int i=0;i<pemPrime1;i++)

                  {

                       arrPemPrime1[i]=tmpKeyNoB64[278+i];

                   }

                   rsaP.P=arrPemPrime1;

 

                   //Prime2

                   for(int i=0;i<pemPrime2;i++)

                   {

                       arrPemPrime2[i]=tmpKeyNoB64[345+i];

                   }

                   rsaP.Q=arrPemPrime2;

 

 

                   //Exponent1

                   for(int i=0;i<pemExponent1;i++)

                   {

                       arrPemExponent1[i]=tmpKeyNoB64[412+i];

                   }

                   rsaP.DP=arrPemExponent1;

 

                   //Exponent2

                   for(int i=0;i<pemExponent2;i++)

                   {

                       arrPemExponent2[i]=tmpKeyNoB64[478+i];

                   }

                   rsaP.DQ=arrPemExponent2;

 

                   //Coefficient

                   for(int i=0;i<pemCoefficient;i++)

                   {

                       arrPemCoefficient[i]=tmpKeyNoB64[545+i];

                   }

                   rsaP.InverseQ=arrPemCoefficient;

              }

              else//公钥

              {

                   for(int i=0;i<pemModulus;i++)

                   {

                       arrPemModulus[i]=tmpKeyNoB64[29+i];

                   }

                   rsaP.Modulus=arrPemModulus;

 

                   for(int i=0;i<pemPublicExponent;i++)

                   {

                       arrPemPublicExponent[i]=tmpKeyNoB64[159+i];

                   }

                   rsaP.Exponent=arrPemPublicExponent;

 

              }

 

              return rsaP;

         }

转载于:https://www.cnblogs.com/gllxy/p/3365304.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值