Chuyển đổi PEM sang DER
Định dạng DER là định dạng nhị phân được tạo ra sau khi mã hóa ASN.1 cho chứng chỉ, khóa riêng và khóa công khai. Ta có thể chuyển đổi từ định dạng PEM sang DER như sau:
import base64
# Chuyển đổi PEM sang DER
def pem_to_der(pem: bytes) -> bytes:
return base64.b64decode(b''.join([line for line in pem.split(b'\n') if line.strip() != b''][1:-1]))
# Ví dụ sử dụng
pem_data = b"""-----BEGIN EC PRIVATE KEY-----
MHcCAQEEILb9XVRPCaPgtmBLTfusYmTDBzACWEIMP7G47ttUSgcZoAoGCCqGSM49
AwEHoUQDQgAEIL5WxHjk/yCczEPlMxcLSSYqsOs4uhGzlq0FQnIx4uJrvDaIq6ht
+tdT2VAnfDTNbyhkJWWfCCpe9meVIQj6hQ==
-----END EC PRIVATE KEY-----"""
der_data = pem_to_der(pem_data)
Giới thiệu pyasn1-modules
Ta có thể sử dụng thư viện pyasn1 kết hợp pyasn1-modules để phân tích các tệp định dạng DER như chứng chỉ, khóa riêng hoặc khóa công khai. pyasn1-modules chứa các tiêu chuẩn RFC phổ biến, với các mối quan hệ tương ứng như sau:
| Tên | Định dạng PEM tương ứng | Mô-đun pyasn1-modules |
|---|---|---|
| Chứng chỉ X.509 | -----BEGIN CERTIFICATE----- ... -----END CERTIFICATE----- | rfc5280.Certificate() |
| Khóa riêng RSA định dạng PKCS#1 | -----BEGIN RSA PRIVATE KEY----- ... -----END RSA PRIVATE KEY----- | rfc2437.RSAPrivateKey() |
| Khóa riêng EC định dạng PKCS#13 | -----BEGIN EC PRIVATE KEY---- - ... -----END EC PRIVATE KEY----- | rfc5915.ECPrivateKey() |
| Khóa riêng định dạng PKCS#8 | -----BEGIN PRIVATE KEY----- ... -----END PRIVATE KEY----- | rfc5208.PrivateKeyInfo() |
| Khóa công khai RSA định dạng PKCS#1 | -----BEGIN RSA PUBLIC KEY---- - ... -----END RSA PUBLIC KEY----- | rfc2437.RSAPublicKey() |
| Khóa công khai tiêu chuẩn X.509 | -----BEGIN PUBLIC KEY----- ... -----END PUBLIC KEY----- | rfc5280.SubjectPublicKeyInfo() |
Cài đặt pyasn1 và pyasn1-modules:
pip install pyasn1 pyasn1-modules
Phân tích chứng chỉ X.509 bằng pyasn1
import base64
from pyasn1_modules import rfc5280
from pyasn1.codec.der import decoder
cert_pem = b"""-----BEGIN CERTIFICATE-----
MIICeDCCAh6gAwIBAgIDCQiGMAoGCCqGSM49BAMCMIGKMQswCQYDVQQGEwJDTjEQ
MA4GA1UECBMHQmVpamluZzEQMA4GA1UEBxMHQmVpamluZzEfMB0GA1UEChMWd3gt
b3JnMS5jaGFpbm1ha2VyLm9yZzESMBAGA1UECxMJcm9vdC1jZXJ0MSIwIAYDVQQD
ExljYS53eC1vcmcxLmNoYWlubWFrZXIub3JnMB4XDTIyMDYxMDA3MTczNloXDTI3
MDYwOTA3MTczNlowgZExCzAJBgNVBAYTAkNOMRAwDgYDVQQIEwdCZWlqaW5nMRAw
DgYDVQQHEwdCZWlqaW5nMR8wHQYDVQQKExZ3eC1vcmcxLmNoYWlubWFrZXIub3Jn
MQ8wDQYDVQQLEwZjbGllbnQxLDAqBgNVBAMTI2NsaWVudDEuc2lnbi53eC1vcmcx
LmNoYWlubWFrZXIub3JnMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEKQK43j7b
gR5l7w6lksM39GPKouVG1APdU2dRSElnGleAwSE6462wcCec/z/X9oLltEH+N7J+
PU6QqNlfdBhdHaNqMGgwDgYDVR0PAQH/BAQDAgbAMCkGA1UdDgQiBCAQI/im5dGN
IruXfy+9prPBpczEAv2pS33Sgf+XZdr8azArBgNVHSMEJDAigCBRi9kSGe5qMbTj
pim5j+50x7ezC5oDQVzXHSLlNIF6czAKBggqhkjOPQQDAgNIADBFAiEApxk8gCH0
uvnkjjO+uI80fWUBmHIkJ2GRIUD1tvyf0FACIDhPPc0j2DjsAg61hlD5682/jwqV
ne776zZIIkR4uZ2r
-----END CERTIFICATE-----"""
cert_der = base64.b64decode(b''.join([line for line in cert_pem.split(b'\n') if line.strip() != b''][1:-1]))
cert_asn1, _ = decoder.decode(cert_der, asn1Spec=rfc5280.Certificate())
print(cert_asn1)
Kết quả chạy chương trình:
Certificate:
tbsCertificate=TBSCertificate:
version=v3
serialNumber=592006
signature=AlgorithmIdentifier:
algorithm=1.2.840.10045.4.3.2
issuer=Name:
rdnSequence=RDNSequence:
RelativeDistinguishedName:
AttributeTypeAndValue:
type=2.5.4.6
value=0x1302434e
RelativeDistinguishedName:
AttributeTypeAndValue:
type=2.5.4.8
value=0x13074265696a696e67
RelativeDistinguishedName:
AttributeTypeAndValue:
type=2.5.4.7
value=0x13074265696a696e67
RelativeDistinguishedName:
AttributeTypeAndValue:
type=2.5.4.10
value=0x131677782d6f7267312e636861696e6d616b65722e6f7267
RelativeDistinguishedName:
AttributeTypeAndValue:
type=2.5.4.11
value=0x1309726f6f742d63657274
RelativeDistinguishedName:
AttributeTypeAndValue:
type=2.5.4.3
value=0x131963612e77782d6f7267312e636861696e6d616b65722e6f7267
validity=Validity:
notBefore=Time:
utcTime=220610071736Z
notAfter=Time:
utcTime=270609071736Z
subject=Name:
rdnSequence=RDNSequence:
RelativeDistinguishedName:
AttributeTypeAndValue:
type=2.5.4.6
value=0x1302434e
RelativeDistinguishedName:
AttributeTypeAndValue:
type=2.5.4.8
value=0x13074265696a696e67
RelativeDistinguishedName:
AttributeTypeAndValue:
type=2.5.4.7
value=0x13074265696a696e67
RelativeDistinguishedName:
AttributeTypeAndValue:
type=2.5.4.10
value=0x131677782d6f7267312e636861696e6d616b65722e6f7267
RelativeDistinguishedName:
AttributeTypeAndValue:
type=2.5.4.11
value=0x1306636c69656e74
RelativeDistinguishedName:
AttributeTypeAndValue:
type=2.5.4.3
value=0x1323636c69656e74312e7369676e2e77782d6f7267312e636861696e6d616b65722e6f7267
subjectPublicKeyInfo=SubjectPublicKeyInfo:
algorithm=AlgorithmIdentifier:
algorithm=1.2.840.10045.2.1
parameters=0x06082a8648ce3d030107
subjectPublicKey=55779132873014641108130266260472839497975468217640857856750433988938929633576622657740176654462346264703467078471547264813561565822596758191598956130622749
extensions=Extensions:
Extension:
extnID=2.5.29.15
critical=True
extnValue=0x030206c0
Extension:
extnID=2.5.29.14
extnValue=0x04201023f8a6e5d18d22bb977f2fbda6b3c1a5ccc402fda94b7dd281ff9765dafc6b
Extension:
extnID=2.5.29.35
extnValue=0x30228020518bd91219ee6a31b4e3a629b98fee74c7b7b30b9a03415cd71d22e534817a73
signatureAlgorithm=AlgorithmIdentifier:
algorithm=1.2.840.10045.4.3.2
signature=182167519797223616245780807420810240526974425761200836157439988500509352020551959734678505313271993580132937884358276032972632671108045842029750887163059365127858740108715
Phân tích khóa riêng RSA định dạng PKCS#1 bằng pyasn1
import base64
from pyasn1_modules import rfc2437
from pyasn1.codec.der import decoder
private_key_pem = b"""-----BEGIN RSA PRIVATE KEY-----
MIIEpQIBAAKCAQEA57b1SHQKXl47qa/35WaX3UNI/UTBIPxcJjJIW84hYBOMDWGw
BQHE1n+l+b9FctQXRIpB/DBPasRvg8YfUSN05Rexv3/s+Z/nIXXlVaatwBV+tCb9
7iqKurYJpMuxJmOhe68ENgFGZkUfAMvByHfPVfzKg2y8gZmsxyfPnZ0dPZpm/xSz
dceNI49iWLFvCARkKEjuO0rjL8tqk3cxY5uTDSov68UEbyhQOYTodLlByY9uwzQO
F74TUWV7ZiEfDoFwaiJi7Q+60wQm9oPS/XeoE97IfA9tEKe7kKmBQZxoI8vyStPU
Q1WEFn+wtcB67pS9dEpTRWBgmQYtLtkq4lcHRQIDAQABAoIBAQCcJrKzaefW4oAo
gTp4sKOk64QTkbLozMg4wWf73jSlr2aRWgSpyyBgQNOUM67UjFNF0DpZfiD23Xwc
/HX8Uv2iqU4StF35dyXmabHr/5BVwuaI90Hmr2qgGq7zDIXMThXz6OTYlBFiODCF
c8qakwr5cory+GMsn2hNKeoC2G9tJAirf+5Bj5xDx5JTwtggUr5NUR37fyeAa2Wh
atqY5cb2k3MEqr6p1zZZ5GLNADvgzXWK+XeDNA/x8AqwHM6ETpljwBd8Rx5EHwjd
6tj7K1oBW43s5lMBe4K0cOgLAGpK48Ck0DZ++8CovqQSQUe7OsIY1MX5ZSrwpKuh
vyjiDMehAoGBAP7rtxozJkhXP899UZsB9q5QuRMLTZruFNFEgjRRsEc+Qr6O25qf
cEzE3yO2EpAmSMS570eK596SvjO6Jd1GM/e/AUnGlOJ3fEOt58ICNWV9V3RdhFwi
Nmmqj3yXhiSsQU695+1NwFViajaXTDjXP/LskJP2hLpolIrkwOanKryZAoGBAOiy
F4zP/RdbhM1CjkyJXHaG8Uru/jimOuKSHhpHnANeNQrMylM4IYH33/GFIIS7hsJg
9ohH5XMnslp1CjbEvjDXuurJx5TFBMFCPy3LppQDKZBLnWyNGBsSDu6/oq+/ozIA
KVTEGlQvqZDQCaxXwvxHFB1w+xlHXAdsY0TVL7+NAoGAVXwEHeQTLWUcv969c+aX
q2LkfU9oCdFW58o6g4L1Qx7M0Qwk9lgLF6NZVKdk2DQOaPIVHH+nO8snvz7oHajC
Go1RyESwfrUk1alGs5d8AnmizyHhFehfKNYKYfSKBlhBWj9yu/A71CY5ie74n4MH
LdZIsWWUotIZJe6KBY7/VNkCgYEAscHaW6dHH+C5wlNlgPItwB21lhib+4qA0TPt
6wVpGOmOe4GVzZzDfBVu7YFVJhBbEYIg0lqZ3S4mARQHiW8iGw2xrEoYPH2E9F03
BjTcO5Vu2tvollPyZjuVTKz4CmnKsReOe0KTGlyOnCFQQmeIfE+P/i2go97vXnxe
GOcCYsECgYEAhB0srmyo49HErxPBzVKN1bVz1GczVtUUVx0tJLhvdM43vTZeXMnl
EstwZWXf3UB5FRsmHSZoBhRmkNzFQ54pM/hlGaGrirgYowMfe5j0Zd0jZBQqpApW
YET1/PeQXaF1V9k8wmmZHuLdgo8tw90x0GVCcmxs3UHlGsEJ0ggnCOk=
-----END RSA PRIVATE KEY-----"""
private_key_der = base64.b64decode(b"".join([line for line in private_key_pem.split(b"\n") if line.strip() != b''][1:-1]))
private_key_asn1, _ = decoder.decode(private_key_der, asn1Spec=rfc2437.RSAPrivateKey())
print(private_key_asn1)
Kết quả chạy chương trình:
RSAPrivateKey:
version=0
modulus=29251268466961495515231372053385573035557384464172735010401614432483825817069065134216395234281996254699424021256355341131983291857177682722346666485636608978170690388127041330853005158984937654841701450083007946451017278020077371099290901323186077610409089863566614014876287906018236397588473477911080707564663343710640573037793994443721208516459214603050807450018876235614286592128971472399939405937824179326202712715422179853542382632375121164999622864151600512254702385441589120043203914553310287472567550480071947761578908479979477695682249475708285623845365952983861483247840983904791189780312972719365050271557
publicExponent=65537
privateExponent=19712258294449768061250797972714250470961317803075954678035114536989001132350508287725515289410018227700383934247630096603354472814932822030798488263700517807054160870830687708883881972726395341960781612568717609213256299247092742948261022886896152061640255944343187939133790917638820978981261442420966468553309333300831019860719226985672896951420320512362483168228723053579083209171274606579718510320975038655697547301178385870610542263045282099094618903834479420547657350795038030554807361588336209946728670621034426088896430152818286774372468243737595530907990335033759644709589989333890062536967115311619827877793
prime1=179011447260068655973124186182614568979533154120320070113226307098867181415537548658298491022619534789937302538473860746108091719620047075412832650019339010689809055924802197544449368830521374894873231868641326454768801343430962780662734215543338611513801337035057715177833684998244785547570241642848471137433
prime2=163404457729818349624425585059376297638550566587001375236662658903455722737484101678581659602043971868350768323052069253427654248129269653305480600170973654074078888238525688298133917251945706616440907845196427203153244396250721179435943398060774062957241903685529550129728817507810911682415235634930964742029
exponent1=60029213672193247361358472919653331438167754521907841080280979463689275462246802674266840673270206388428705889620215109285098978013790295197336209308863900360558671011175029303055736130557826206030624178359254032019377559616434518373207651479255270537845979889519865212982756232455340524878331333214533014745
exponent2=124825377600220117728874414306614812471983697233801316048160266038155657157474465819865300613649227270352821540889555443544899557171426155043495746936228771801649228081443307733917885061894957902337574352837541106530113179637397273712270477448076547414305791630870369374471573610495528975516675417354834961089
coefficient=92773579829798681364932858735394964473766250124853828149170174032722412637938403258313692804149389727272097569239655966328782774259608204560835938769655914373875441609947759091235368799025836346621444197945955486577885636949863610961921831595069239745885167171853656756901878283745710333645530928800135055593