การรักษาไพรเวตคีย์เดียวกันบนรูท CA ของคุณจะทำให้ใบรับรองทั้งหมดสามารถตรวจสอบกับรูทใหม่ได้สำเร็จ สิ่งที่คุณต้องการก็คือเชื่อใจในรูทใหม่
ความสัมพันธ์การลงนามใบรับรองขึ้นอยู่กับลายเซ็นจากคีย์ส่วนตัว การรักษารหัสส่วนตัวเดียวกัน (และโดยนัยคือรหัสสาธารณะเดียวกัน) ในขณะที่สร้างใบรับรองสาธารณะใหม่ด้วยช่วงเวลาที่มีผลบังคับใช้ใหม่และคุณลักษณะใหม่อื่น ๆ ที่เปลี่ยนไปตามที่จำเป็น CRL ก็สามารถดำเนินการต่อจากใบรับรองเก่าไปสู่ใบรับรองใหม่เช่นใบรับรองที่ลงนามโดยคีย์ส่วนตัว
ดังนั้นเรามาตรวจสอบ!
สร้างรูท 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
ตั้งค่าทั้งหมดแล้วความสัมพันธ์ของใบรับรองปกติ ตรวจสอบความน่าเชื่อถือกันเถอะ:
# 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
ไปอีกหน่อยเพื่อตรวจสอบว่ามันทำงานในการตรวจสอบใบรับรองโลกแห่งความจริง
เปิดใช้งานอินสแตนซ์ Apache และปล่อยให้เป็นไป (โครงสร้างไฟล์เดเบียนปรับตามต้องการ):
# cp cert.pem /etc/ssl/certs/
# cp origroot.pem /etc/ssl/certs/
# cp newroot.pem /etc/ssl/certs/
# cp cert.key /etc/ssl/private/
เราจะตั้งค่าคำสั่งเหล่านี้เป็นการVirtualHost
ฟังใน 443 - จำไว้ว่าnewroot.pem
ใบรับรองหลักไม่ได้มีอยู่เมื่อcert.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)
ตกลงแล้วเบราว์เซอร์ที่ใช้ crypto API ของ MS ล่ะ ต้องเชื่อใจรูทก่อนแล้วทุกอย่างก็ดีด้วยหมายเลขซีเรียลใหม่:
และเราก็ควรจะทำงานกับรากเก่าเช่นกัน สลับการกำหนดค่าของ Apache ไปรอบ ๆ :
SSLEngine on
SSLCertificateFile /etc/ssl/certs/cert.pem
SSLCertificateKeyFile /etc/ssl/private/cert.key
SSLCertificateChainFile /etc/ssl/certs/origroot.pem
ทำการรีสตาร์ทแบบเต็มบน Apache การโหลดซ้ำจะไม่เปลี่ยน certs อย่างถูกต้อง
# 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)
และด้วยเบราว์เซอร์ MS crypto API ทำให้ Apache แสดงรูทเก่า แต่รูทใหม่ยังอยู่ในที่เก็บรากที่เชื่อถือได้ของคอมพิวเตอร์ มันจะค้นหาโดยอัตโนมัติและตรวจสอบใบรับรองกับรากที่เชื่อถือได้ (ใหม่) แม้จะมี Apache แสดงห่วงโซ่ที่แตกต่าง (รูทเก่า) หลังจากลอกรูทใหม่ออกจากรูทที่ไว้ใจได้และเพิ่มรูทใบรับรองดั้งเดิมแล้วทั้งหมดก็ทำได้ดี:
นั่นแหล่ะ! เก็บคีย์ส่วนตัวเดิมไว้เมื่อคุณต่ออายุเปลี่ยนเป็นรูทที่เชื่อถือได้ใหม่และมันก็ใช้ได้ดีทีเดียว โชคดี!