4

证书概述

证书主要包括颁发者和被办法者的信息,以及被颁发者的公钥,和CA机构对这些信息的认证,
主要内容:

**版本**  
识别用于该证书的 X.509 标准的版本,这可以影响证书中所能指定的信息。迄今为止,已定义的版本有三个。  
**序列号**  
发放证书的实体有责任为证书指定序列号,以使其区别于该实体发放的其它证书。此信息用途很多。例如,如果某一证书被撤消,其序列号将放到证书撤消清单 (CRL) 中。  
**签名算法标识符**  
用于识别 CA 签写证书时所用的算法。  
**签发人姓名**  
签写证书的实体的 X.500 名称。它通常为一个 CA。 使用该证书意味着信任签写该证书的实体(注意:有些情况下(例如根或顶层 CA 证书),签发人会签写自己的证书)。  
**有效期**  
每个证书均只能在一个有限的时间段内有效。该有效期以起始日期和时间及终止日期和时间表示,可以短至几秒或长至一世纪。所选有效期取决于许多因素,例如用于签写证书的私钥的使用频率及愿为证书支付的金钱等。它是在没有危及相关私钥的条件下,实体可以依赖公钥值的预计时间。  
**主体名**  
证书可以识别其公钥的实体名。此名称使用 X.500 标准,因此在Internet中应是唯一的。它是实体的特征名 (DN),例如,
CN=Java Duke,OU=Java Software Division,O=Sun Microsystems Inc,C=US
(这些指主体的通用名、组织单位、组织和国家)。  
**主体公钥信息**  
这是被命名实体的公钥,同时包括指定该密钥所属公钥密码系统的算法标识符及所有相关的密钥参数。

PEM DER 只是编码方式,注意并不指定是证书的编码方式,也可以是密钥的编码方式

各种名词和文件后缀

  1. X.509 - 这是一种证书标准,主要定义了证书中应该包含哪些内容.
  2. 两种编码方式:
  • PEM - Privacy Enhanced Mail,打开看文本格式,以"-----BEGIN..."开头, "-----END..."结尾,内容是BASE64编码.

查看PEM格式证书的信息:openssl x509 -in certificate.pem -text -noout
Apache和*NIX服务器偏向于使用这种编码格式.

  • DER - Distinguished Encoding Rules,打开看是二进制格式,不可读.

查看DER格式证书的信息:openssl x509 -in certificate.der -inform der -text -noout
Java和Windows服务器偏向于使用这种编码格式.

  1. 各种文件拓展名:
  • CRT - CRT应该是certificate的三个字母,其实还是证书的意思,常见于*NIX系统,有可能是PEM编码,也有可能是DER编码,大多数应该是PEM编码
  • CER - 还是certificate,还是证书,常见于Windows系统,同样的,可能是PEM编码,也可能是DER编码,大多数应该是DER编码.
  • KEY - 通常用来存放一个公钥或者私钥,并非X.509证书,编码同样的,可能是PEM,也可能是DER.
  • CSR - Certificate Signing Request,即证书签名请求,这个并不是证书,而是向权威证书颁发机构获得签名证书的申请,其核心内容是一个公钥(当然还附带了一些别的信息),在生成这个申请的时候,同时也会生成一个私钥
  • PFX/P12 - predecessor of PKCS#12,对*nix服务器来说,一般CRT和KEY是分开存放在不同文件中的,但Windows的IIS则将它们存在一个PFX文件中,(因此这个文件包含了证书及私钥)这样会不会不安全?应该不会,PFX通常会有一个"提取密码"
总结起来:crt cer约等于x509证书,key保存公钥或私钥,csr是证书签名请求,pfx包含证书和私钥
  1. PKCS系列

当我发现还有PKCS系列时,我很凌乱,
PKCS系列是 Public-Key Cryptography Standards ,是RSA制定的一系列的标准,注意前面写的什么文件后缀啥的,都不算是标准,只有X509和PKCS可以称为标准,
PKCS中经常使用的就是:PKCS1 PKCS8 PKCS12

  • PKCS#1:定义RSA公开密钥算法加密和签名机制,主要用于组织PKCS#7中所描述的数字签名和数字信封。
  • PKCS#8:描述私有密钥信息格式,该信息包括公开密钥算法的私有密钥以及可选的属性集等。注意pkcs8不只是能表示RSA,所以比PKCS1更具有通用性
  • PKCS#12:描述个人信息交换语法标准。描述了将用户公钥、私钥、证书和其他相关信息打包的语法。
总结:PKCS1,8,12都可以在某些情况下当作文件格式,PKCS1描述基础的密钥格式,PKCS8也描述密钥,但格式和1不同,PKCS12等价于PFX文件,包含证书和私钥

OpenSSL

# 生成PKCS#1的公私钥
openssl genrsa -out pkcs1_private.pem 1024
openssl rsa -in pkcs1_private.pem -RSAPublicKey_out -out pkcs1_public.pem

查看私钥
 openssl rsa -in rsa_private_key.pem -text -noout
查看公钥
openssl rsa -pubin -in  rsa_public_key.pem  -text

# 由PKCS#1的私钥,生成PKCS#8的公私钥
openssl pkcs8 -topk8 -inform PEM -in pkcs1_private.pem -outform PEM -nocrypt -out from_pkcs1_private_to_pkcs8_private.pem

openssl rsa -in pkcs1_private.pem -pubout -out from_pkcs1_private_to_pkcs8_public.pem

# 由PKCS#8的私钥,生成PKCS#1的公私钥
openssl rsa -in from_pkcs1_private_to_pkcs8_private.pem -out from_pkcs8_private_to_pkcs1_private.pem

openssl rsa -in from_pkcs1_private_to_pkcs8_private.pem -RSAPublicKey_out -out from_pkcs8_private_to_pkcs1_public.pem

# 由PKCS1公钥生成PKCS#8公钥:
openssl rsa -RSAPublicKey_in -in pkcs1_public.pem -pubout -out from_pkcs1_public_to_pkcs8_public.pem

# 由PKCS8公钥生成PKCS#1公钥:
openssl rsa -pubin -in from_pkcs1_private_to_pkcs8_public.pem -RSAPublicKey_out -out from_pkcs8_public_to_pkcs1_public.pem

产生证书请求 注意PKCS1 8都可以
openssl req -new -key private_key.pem -out rsaCerReq.csr

产生证书 注意PKCS1 8都可以
openssl x509 -req -days 3650 -in rsaCerReq.csr -signkey private_key.pem -out rsaCert.crt

从证书获得公钥:
openssl x509 -in rsaCert.crt  -noout  -pubkey  > public_key.pem

生成PKCS12
openssl pkcs12 -export -inkey serverprikey.pem -in server.pem -password pass:"123456" -out server_nocret.pfx


从PKCS12获得证书和私钥
openssl pkcs12 -in server_nocret.pfx -nocerts -nodes  -out alicekey.pem

openssl pkcs12 -in server_nocret.pfx  -nokeys  -out cert.pem

查看pkcs12内容 -nodes:因为私钥在在输出前会输出加密结果,所以需要nodes来保证不用打密码和不加密
openssl pkcs12 -in server_nocret.pfx -nocerts -nodes  -out alicekey.pem

RSA

  1. 随机找两个质数 P 和 Q ,定义n= p*q
  2. 计算 n 的欧拉函数 m= φ(n) =(p-1)*(1-1),为什么是这样我就不懂了 ,即表示在小于n的数中有多少个与n构成互质,
  3. 随机选择一个整数 e,条件是1< e < m,且 e 与 m 互质。
  4. 计算d : e*d % m=1 ,虽然是二元一次方程,但通过拓展欧几里得算法可以得出,反正这个算法我也不懂,能算出来就能算出来吧
  5. 公钥 (n,e) 私钥(n,d)

为什么难以破解:
在已知 公钥 N E 的情况下,想要知道 私钥的额D 就需要知道m,而 m=(p-1)(Q-1),想要知道P Q
就只能对 N 进行分解,而大整数的因式分解是难以破解的,所以保证了安全

PKCS的结构

之前我一直奇怪为什么私钥可以转换出公钥,以为是RSA算法的原理所导致,但看起来原理并不满足私钥算出公钥的操作,所以我觉得问题出在PKCS内容上:

PKCS1 的公钥结构:
RSAPublicKey ::= SEQUENCE {
    modulus           INTEGER,  -- n
    publicExponent    INTEGER   -- e
}

PKCS1 的私钥结构:
RSAPrivateKey ::= SEQUENCE {
  version           Version,
  modulus           INTEGER,  -- n
  publicExponent    INTEGER,  -- e
  privateExponent   INTEGER,  -- d
  prime1            INTEGER,  -- p
  prime2            INTEGER,  -- q
  exponent1         INTEGER,  -- d mod (p-1)
  exponent2         INTEGER,  -- d mod (q-1)
  coefficient       INTEGER,  -- (inverse of q) mod p
  otherPrimeInfos   OtherPrimeInfos OPTIONAL
}

PKCS1 公钥:
PublicKeyInfo ::= SEQUENCE {
  algorithm       AlgorithmIdentifier,
  PublicKey       BIT STRING
}

AlgorithmIdentifier ::= SEQUENCE {
  algorithm       OBJECT IDENTIFIER,
  parameters      ANY DEFINED BY algorithm OPTIONAL
}


PKCS8私钥
PrivateKeyInfo ::= SEQUENCE {
  version         Version,
  algorithm       AlgorithmIdentifier,
  PrivateKey      BIT STRING
}

AlgorithmIdentifier ::= SEQUENCE {
  algorithm       OBJECT IDENTIFIER,
  parameters      ANY DEFINED BY algorithm OPTIONAL
}

可以看出PKCS1 的私钥包含了密钥产生的所有元素,所以能算出公钥就不奇怪了,至于PKCS8 看起来不包含,但为什么也可以,我想应该只是结构不同,内容应该都是有的

参考

https://blog.csdn.net/xy01090...
注意这个文章的漫画有一个错误的地方,证书并不是CA私钥对公司公钥加密的结果
而应该是如下面这个文章的说法,证书=s_KeyPub + s_Info + ca_Info + enc_s_Hash
s_KeyPub:公司公钥
s_Info:公司信息
ca_Info:ca机构
enc_s_Hash:ca对公司的认证,=ca_pri(hash(s_KeyPub + s_Info + ca_Info))

证书在通讯中如何加签和验签,

https://zhuanlan.zhihu.com/p/...

阐述PKCS1 PKCS8的区别,以及PKCS的结构

https://www.shangyang.me/2017...

描述PKCS

https://qsiofttt.iteye.com/bl...

密钥之间转换:

https://xuanxuanblingbling.gi...

RSA:

https://www.zhihu.com/questio...

没有感情的杀手
321 声望7 粉丝

搬砖工程师