Structure des clés PEM
En gros, une clé en PEM contient un header et une chaine en base64.
-----BEGIN PUBLIC KEY-----
MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDMYfnvWtC8Id5bPKae5yXSxQTt
+Zpul6AnnZWfI2TtIarvjHBFUtXRo96y7hoL4VWOPKGCsRqMFDkrbeUjRrx8iL91
4/srnyf6sh9c8Zk04xEOpK1ypvBz+Ks4uZObtjnnitf0NBGdjMKxveTq+VE7BWUI
yQjtQ8mbDOsiLLvh7wIDAQAB
-----END PUBLIC KEY-----
Le header indique parfois ce que ça peut contenir (-----BEGIN RSA PUBLIC KEY-----, -----BEGIN CERTIFICATE-----), mais avec ces headers c’est une clé PKCS#8. La chaine base64 contient du DER, un encodage pour une structure de données ASN.1.
Une clé PKCS#8 a cette structure :
PublicKeyInfo ::= SEQUENCE {
algorithm AlgorithmIdentifier,
PublicKey BIT STRING
}
AlgorithmIdentifier ::= SEQUENCE {
algorithm OBJECT IDENTIFIER,
parameters ANY DEFINED BY algorithm OPTIONAL
}
C’est une structure générique qui contient l’algorithme de la clé et ses paramètres, et la clé elle-même. L’OBJECT IDENTIFIER (ou OID) est un identifiant unique. L’OID pour une clé RSA est 1.2.840.113549.1.1.1 (1.2.840.113549 est l’identifiant pour RSA Security LLC.)
Docs sur l’ASN.1 et DER :
- https://letsencrypt.org/docs/a-warm-welcome-to-asn1-and-der/
- https://luca.ntop.org/Teaching/Appunti/asn1.html
- https://www.oss.com/asn1/resources/asn1-made-simple/introduction.html
Une clé au format JWK (JSON Web Key), c’est un format différent encodé en JSON. Par exemple :
{
"kty":"RSA",
"n": "0vx7agoebGcQSuuPiLJXZptN9nndrQmbXEps2aiAFbWhM78LhWx
4cbbfAAtVT86zwu1RK7aPFFxuhDR1L6tSoc_BJECPebWKRXjBZCiFV4n3oknjhMs
tn64tZ_2W-5JsGY4Hc5n9yBXArwl93lqt7_RN5w6Cf0h4QyQ5v-65YGjQR0_FDW2
QvzqY368QQMicAtaSqzs8KJZgnYb9c7d0zgdAZHzu6qMQvRL5hajrn1n91CbOpbI
SD08qNLyrdkt-bFTWhAI4vMQFh6WeZu0fM4lFd2NcRwr3XPksINHaQ-G_xBniIqb
w0Ls1jF44-csFCur-kEgU8awapJzKnqDKgw",
"e":"AQAB",
"alg":"RS256",
"kid":"2011-04-29"
}
Doc sur JWK vs PEM : https://support.auth0.com/center/s/article/Difference-between-JWK-and-PEM
Choisir l’un ou l’autre dépend principalement de ce qui est le plus ergonomique pour l’application et les libs disponible.