使用 openssl x509 -text
解析带有 Unicode 字符的证书时,你会看到如下格式的输出。
Subject: C = TR, L = Gebze - Kocaeli, O = T\C3\BCrkiye Bilimsel ve Teknolojik Ara\C5\9Ft\C4\B1rma Kurumu - T\C3\9CB\C4\B0TAK, OU = Ulusal Elektronik ve Kriptoloji Ara\C5\9Ft\C4\B1rma Enstit\C3\BCs\C3\BC - UEKAE, OU = Kamu Sertifikasyon Merkezi, CN = T\C3\9CB\C4\B0TAK UEKAE K\C3\B6k Sertifika Hizmet Sa\C4\9Flay\C4\B1c\C4\B1s\C4\B1 - S\C3\BCr\C3\BCm 3
你可能会好奇这种 \C3
的转义方式是什么,查阅 OpenSSL 的 man 手册可以发现默认的显示格式为 oneline,相当于 RFC 2253 格式。
oneline
Display the name in one line, using a format that is more readable RFC 2253. It is equivalent to esc\_2253, esc\_ctrl, esc\_msb, utf8, dump\_nostr, dump\_der, use\_quote, sep\_comma\_plus\_space, space\_eq and sname options.
https://www.openssl.org/docs/man3.0/man1/openssl-namedisplay-options.html
从而找到对应的 RFC 文档
Lightweight Directory Access Protocol (v3): UTF-8 String Representation of Distinguished Names
https://datatracker.ietf.org/doc/html/rfc2253
还有其继任者 RFC 4514,这里就不展开了。那么要如何将这种 escape 的格式转为正常的 UTF-8 字符串呢?
参考 https://www.python-ldap.org/en/python-ldap-3.4.0/reference/ldap-dn.html,只需要安装 python-ldap
包后执行
import ldap.dn
s = r'C = TR, L = Gebze - Kocaeli, O = T\C3\BCrkiye Bilimsel ve Teknolojik Ara\C5\9Ft\C4\B1rma Kurumu - T\C3\9CB\C4\B0TAK, OU = Ulusal Elektronik ve Kriptoloji Ara\C5\9Ft\C4\B1rma Enstit\C3\BCs\C3\BC - UEKAE, OU = Kamu Sertifikasyon Merkezi, CN = T\C3\9CB\C4\B0TAK UEKAE K\C3\B6k Sertifika Hizmet Sa\C4\9Flay\C4\B1c\C4\B1s\C4\B1 - S\C3\BCr\C3\BCm 3'
ldap.dn.str2dn(s)
# Output:
# [[('C', 'TR', 1)], [('L', 'Gebze - Kocaeli', 1)], [('O', 'Türkiye Bilimsel ve Teknolojik Araştırma Kurumu - TÜBİTAK', 4)], [('OU', 'Ulusal Elektronik ve Kriptoloji Araştırma Enstitüsü - UEKAE', 4)], [('OU', 'Kamu Sertifikasyon Merkezi', 1)], [('CN', 'TÜBİTAK UEKAE Kök Sertifika Hizmet Sağlayıcısı - Sürüm 3', 4)]]
就能获得原始字符串了。
以上示例使用的证书:
-----BEGIN CERTIFICATE-----
MIIFFzCCA/+gAwIBAgIBETANBgkqhkiG9w0BAQUFADCCASsxCzAJBgNVBAYTAlRS
MRgwFgYDVQQHDA9HZWJ6ZSAtIEtvY2FlbGkxRzBFBgNVBAoMPlTDvHJraXllIEJp
bGltc2VsIHZlIFRla25vbG9qaWsgQXJhxZ90xLFybWEgS3VydW11IC0gVMOcQsSw
VEFLMUgwRgYDVQQLDD9VbHVzYWwgRWxla3Ryb25payB2ZSBLcmlwdG9sb2ppIEFy
YcWfdMSxcm1hIEVuc3RpdMO8c8O8IC0gVUVLQUUxIzAhBgNVBAsMGkthbXUgU2Vy
dGlmaWthc3lvbiBNZXJrZXppMUowSAYDVQQDDEFUw5xCxLBUQUsgVUVLQUUgS8O2
ayBTZXJ0aWZpa2EgSGl6bWV0IFNhxJ9sYXnEsWPEsXPEsSAtIFPDvHLDvG0gMzAe
Fw0wNzA4MjQxMTM3MDdaFw0xNzA4MjExMTM3MDdaMIIBKzELMAkGA1UEBhMCVFIx
GDAWBgNVBAcMD0dlYnplIC0gS29jYWVsaTFHMEUGA1UECgw+VMO8cmtpeWUgQmls
aW1zZWwgdmUgVGVrbm9sb2ppayBBcmHFn3TEsXJtYSBLdXJ1bXUgLSBUw5xCxLBU
QUsxSDBGBgNVBAsMP1VsdXNhbCBFbGVrdHJvbmlrIHZlIEtyaXB0b2xvamkgQXJh
xZ90xLFybWEgRW5zdGl0w7xzw7wgLSBVRUtBRTEjMCEGA1UECwwaS2FtdSBTZXJ0
aWZpa2FzeW9uIE1lcmtlemkxSjBIBgNVBAMMQVTDnELEsFRBSyBVRUtBRSBLw7Zr
IFNlcnRpZmlrYSBIaXptZXQgU2HEn2xhecSxY8Sxc8SxIC0gU8O8csO8bSAzMIIB
IjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAim1L/xCIOsP2fpTo6iBkcK4h
gb46ezzb8R1Sf1n68yJMlaCQvEhOEav7t7WNeoMojCZG2E6VQIdhn8WebYGHV2yK
O7Rm6sxA/OOqbLLLAdsyv9Lrhc+hDVXDWzhXcLh1xnnRFDDtG1hba+818qEhTsXO
fJlfbLm4IpNQp81McGq+agV/E5wrHur+R84EpW+sky58K5+eeROR6Oqeyjh1jmKw
lZMq5d/pXpduIF9fhHpEORlAHLpVK/swsoHvhOPc7Jg4OQOFCKlUAwUp8MmPi+oL
hmUZEdPpCSPeaJMDyTYcIW7OjGbxmTDY17PDHfiBLqi9ggtm/oLL4eAagsNAgQID
AQABo0IwQDAdBgNVHQ4EFgQUvYiHyY/2pAoLquvF/pEjnatKijIwDgYDVR0PAQH/
BAQDAgEGMA8GA1UdEwEB/wQFMAMBAf8wDQYJKoZIhvcNAQEFBQADggEBAB18+kmP
NOm3JpIWmgV050vQbTlswyb2zrgxvMTfvCr4N5EY3ATIZJkrGG2AA1nJrvhY0D7t
wyOfaTyGOBye79oneNGEN3GKPEs5z35FBtYt2IpNeBLWrcLTy9LQQfMmNkqblWwM
7uXRQydmwYj3erMgbOqwaSvHIOgMA8RBBZniP+Rr+KCGgceExh/VS4ESshYhLBOh
gLJeDEoTniDYYkCrkOpkSi+sDQESeUWoL4cZaMjihccwsnX5OD+ywJO0a+IDRM5n
oN+J1q2MdqMTw5RhK2vZbMEHCiIHhWyFJEapvj+LeISCfiQMnf2BN+MlqO02TpUs
yZyQ2uypQjyttgI=
-----END CERTIFICATE-----