证书颁发机构根证书到期和更新

2004年,我在Linux上build立了一个使用OpenSSL的小型authentication机构,以及OpenVPN提供的简单pipe理脚本。 根据我当时find的指南,我将根CA证书的有效期设置为10年。 从那时起,我已经为OpenVPN隧道,网站和电子邮件服务器签了许多证书,这些证书的有效期也是10年(这可能是错误的,但当时我不太清楚)。

我发现了许多关于build立一个CA的指南,但是关于它的pipe理的信息却很less,特别是当根CA证书到期时要做什么,这在2014年会发生一些。所以我有以下问题:

  • 在根CA证书到期后有效期延长的证书是否会在后者过期后立即失效,还是继续有效(因为在CA证书的有效期内签名)?
  • 需要进行哪些操作来更新根CA证书,并确保平稳过渡到期?
    • 我可以用不同的有效期重新签署当前的根CA证书,并将新签名的证书上传到客户端,以便客户端证书保持有效?
    • 还是我需要用新的根CA证书签名来replace所有的客户端证书?
  • 何时更新根CA证书? 接近到期还是到期前的合理时间?
  • 如果更新根CA证书成为主要工作,那么我现在可以做些什么来确保在下一次更新时顺利过渡(当然,将有效期限定为100年)?

这种情况稍微复杂一些,因为我只能通过OpenVPN隧道访问某些客户端,而使用当前CA证书签名的证书,所以如果我必须更换所有客户端证书,则需要复制把新的文件传给客户端,重新启动隧道,交叉手指,希望事后出现。

在根CA上保留相同的私钥允许所有证书继续对新根进行成功validation; 所有你需要的是相信新的根。

证书签名关系基于来自私钥的签名; 在生成一个新的公共证书的同时保留相同的私钥(以及隐含的相同的公钥),新的有效期以及根据需要改变的任何其他新的属性,保持信任关系到位。 CRL也可以继续从旧证书到新证书,像证书一样由私钥签名。


所以,我们来validation!

build立一个根CA:

openssl req -new -x509 -keyout root.key -out origroot.pem -days 3650 -nodes 

从中生成一个子证书:

 openssl genrsa -out cert.key 1024 openssl req -new -key cert.key -out cert.csr 

签署孩子证书:

 openssl x509 -req -in cert.csr -CA origroot.pem -CAkey root.key -create_serial -out cert.pem rm cert.csr 

所有在那里设置,正常的证书关系。 让我们来validation这个信任:

 # openssl verify -CAfile origroot.pem -verbose cert.pem cert.pem: OK 

好吧,现在让我们说10年过去了。 我们从同一个根私钥生成一个新的公共证书。

 openssl req -new -key root.key -out newcsr.csr openssl x509 -req -days 3650 -in newcsr.csr -signkey root.key -out newroot.pem rm newcsr.csr 

而且..工作吗?

 # openssl verify -CAfile newroot.pem -verbose cert.pem cert.pem: OK 

但为什么? 他们是不同的文件,对吧?

 # sha1sum newroot.pem 62577e00309e5eacf210d0538cd79c3cdc834020 newroot.pem # sha1sum origroot.pem c1d65a6cdfa6fc0e0a800be5edd3ab3b603e1899 origroot.pem 

是的,但是,这并不意味着新的公钥密码不符合证书上的签名。 不同的序列号,相同的模数:

 # openssl x509 -noout -text -in origroot.pem Serial Number: c0:67:16:c0:8a:6b:59:1d ... RSA Public Key: (1024 bit) Modulus (1024 bit): 00:bd:56:b5:26:06:c1:f6:4c:f4:7c:14:2c:0d:dd: 3c:eb:8f:0a:c0:9d:d8:b4:8c:b5:d9:c7:87:4e:25: 8f:7c:92:4d:8f:b3:cc:e9:56:8d:db:f7:fd:d3:57: 1f:17:13:25:e7:3f:79:68:9f:b5:20:c9:ef:2f:3d: 4b:8d:23:fe:52:98:15:53:3a:91:e1:14:05:a7:7a: 9b:20:a9:b2:98:6e:67:36:04:dd:a6:cb:6c:3e:23: 6b:73:5b:f1:dd:9e:70:2b:f7:6e:bd:dc:d1:39:98: 1f:84:2a:ca:6c:ad:99:8a:fa:05:41:68:f8:e4:10: d7:a3:66:0a:45:bd:0e:cd:9d # openssl x509 -noout -text -in newroot.pem Serial Number: 9a:a4:7b:e9:2b:0e:2c:32 ... RSA Public Key: (1024 bit) Modulus (1024 bit): 00:bd:56:b5:26:06:c1:f6:4c:f4:7c:14:2c:0d:dd: 3c:eb:8f:0a:c0:9d:d8:b4:8c:b5:d9:c7:87:4e:25: 8f:7c:92:4d:8f:b3:cc:e9:56:8d:db:f7:fd:d3:57: 1f:17:13:25:e7:3f:79:68:9f:b5:20:c9:ef:2f:3d: 4b:8d:23:fe:52:98:15:53:3a:91:e1:14:05:a7:7a: 9b:20:a9:b2:98:6e:67:36:04:dd:a6:cb:6c:3e:23: 6b:73:5b:f1:dd:9e:70:2b:f7:6e:bd:dc:d1:39:98: 1f:84:2a:ca:6c:ad:99:8a:fa:05:41:68:f8:e4:10: d7:a3:66:0a:45:bd:0e:cd:9d 

让我们进一步来validation它在真实世界证书validation中的工作。

启动一个Apache实例,让我们一起去(debian文件结构,根据需要进行调整):

 # cp cert.pem /etc/ssl/certs/ # cp origroot.pem /etc/ssl/certs/ # cp newroot.pem /etc/ssl/certs/ # cp cert.key /etc/ssl/private/ 

我们将在一个监听443的VirtualHost上设置这些指令 – 请记住, cert.pem生成并签名时, newroot.pem根证书不存在。

 SSLEngine on SSLCertificateFile /etc/ssl/certs/cert.pem SSLCertificateKeyFile /etc/ssl/private/cert.key SSLCertificateChainFile /etc/ssl/certs/newroot.pem 

让我们看看openssl如何看待它:

 # openssl s_client -showcerts -CAfile newroot.pem -connect localhost:443 Certificate chain 0 s:/C=AU/ST=Some-State/O=Internet Widgits Pty Ltd/CN=server.lan i:/C=AU/ST=Some-State/O=Internet Widgits Pty Ltd/CN=root -----BEGIN CERTIFICATE----- ... -----END CERTIFICATE----- 1 s:/C=AU/ST=Some-State/O=Internet Widgits Pty Ltd/CN=root i:/C=AU/ST=Some-State/O=Internet Widgits Pty Ltd/CN=root -----BEGIN CERTIFICATE----- MIICHzCCAYgCCQCapHvpKw4sMjANBgkqhkiG9w0BAQUFADBUMQswCQYDVQQGEwJB ... -----END CERTIFICATE----- (this should match the actual contents of newroot.pem) ... Verify return code: 0 (ok) 

好的,如何使用MS的encryptionAPI的浏览器? 相信根,首先,这是很好的,新的根序列号:

newroot

而且,我们也应该和老根一起工作。 切换Apache的configuration:

 SSLEngine on SSLCertificateFile /etc/ssl/certs/cert.pem SSLCertificateKeyFile /etc/ssl/private/cert.key SSLCertificateChainFile /etc/ssl/certs/origroot.pem 

在Apache上进行完全重新启动,重新加载将无法正确切换证书。

 # openssl s_client -showcerts -CAfile origroot.pem -connect localhost:443 Certificate chain 0 s:/C=AU/ST=Some-State/O=Internet Widgits Pty Ltd/CN=server.lan i:/C=AU/ST=Some-State/O=Internet Widgits Pty Ltd/CN=root -----BEGIN CERTIFICATE----- ... -----END CERTIFICATE----- 1 s:/C=AU/ST=Some-State/O=Internet Widgits Pty Ltd/CN=root i:/C=AU/ST=Some-State/O=Internet Widgits Pty Ltd/CN=root -----BEGIN CERTIFICATE----- MIIC3jCCAkegAwIBAgIJAMBnFsCKa1kdMA0GCSqGSIb3DQEBBQUAMFQxCzAJBgNV ... -----END CERTIFICATE----- (this should match the actual contents of origroot.pem) ... Verify return code: 0 (ok) 

而且,通过MSencryptionAPI浏览器,Apache提供了旧的根,但是新的根仍然在计算机的可信根存储中。 它会自动find它并validation对可信(新)根的证书,尽pipeApache呈现不同的链(旧的根)。 从受信任的根中剥离新的根并添加原始根证书后,一切正常:

oldroot


就是这样了! 保持相同的私钥,当你更新时,交换新的受信任的根,它几乎所有的工作 。 祝你好运!

我注意到在原来的CA密钥的更新证书中可能会丢失CA扩展。 这对我来说更合适(它创build了一个./renewedselfsignedca.conf ,其中定义了v3 CA扩展, ca.keyca.crt被假定为原始CA密钥和证书):

 openssl x509 -x509toreq -in ca.crt -signkey ca.key -out renewedselfsignedca.csr echo -e "[ v3_ca ]\nbasicConstraints= CA:TRUE\nsubjectKeyIdentifier= hash\nauthorityKeyIdentifier= keyid:always,issuer:always\n" > renewedselfsignedca.conf openssl x509 -req -days 1095 -in renewedselfsignedca.csr -signkey ca.key -out renewedselfsignedca.crt -extfile ./renewedselfsignedca.conf -extensions v3_ca 

基本模式来延长根的有效期(您需要公开的X.509和关联的私钥):

从公共X.509和私钥生成CSR:

 openssl x509 -x509toreq -in XXX.crt -signkey XXX.key -out XXX.csr 

用私钥重新签署CSR:

 openssl x509 -in XXX.csr -out XXX.crt -signkey XXX.key -req -days 365 

当你的根证书到期时,你签署的证书也是如此。 你将不得不生成一个新的根证书,并签署新的证书。 如果你不想每隔几年重复一次这个过程,唯一真正的select就是延长十年或二十年根本证书的有效date:我为自己使用而生成的根20年。

你不能“更新”根证书。 你所能做的就是生成一个新的。

生成一个新的根目录至less要在一到两年之后才能生效,所以如果出现问题,你就有时间转换,而不是在时间墙上。 这样,你总是可以暂时切换回旧的证书,直到你解决了新的问题。

就VPN隧道而言,我会设置几个testing台服务器来进行试验,以便您在使用客户端计算机之前准确理解要执行的操作。

@Bianconiglio加上-set_serial为我工作。 我的服务器只有局域网,所以我并不担心副作用,我现在有时间去做一个“适当”的解决scheme。

我使用了下面的可configuration脚本。 只需设置variablesCACRT,CAKEY和NEWCA。

 # WF 2017-06-30 # https://serverfault.com/a/501513/162693 CACRT=SnakeOilCA.crt CAKEY=SnakeOilCA.key NEWCA=SnakeOilCA2017 serial=`openssl x509 -in $CACRT -serial -noout | cut -f2 -d=` echo $serial openssl x509 -x509toreq -in $CACRT -signkey $CAKEY -out $NEWCA.csr echo -e "[ v3_ca ]\nbasicConstraints= CA:TRUE\nsubjectKeyIdentifier= hash\nauthorityKeyIdentifier= keyid:always,issuer:always\n" > $NEWCA.conf openssl x509 -req -days 3650 -in $NEWCA.csr -set_serial 0x$serial -signkey $CAKEY -out $NEWCA.crt -extfile ./$NEWCA.conf -extensions v3_ca openssl x509 -in $NEWCA.crt -enddate -serial -noout