2016-02-21 2 views
3

J'ai un certificat au format pem et je veux extraire la clé publique (RSA). Je suis déjà loin:(Erlang) extraction de la clé publique du certificat au format pem

{ok, PemBin} = file:read_file("/path/to/certificate.pem"). 
[Certificate] = public_key:pem_decode(PemBin). 

Maintenant, je peux faire ce qui suit:

public_key:pem_entry_decode(Certificate). 

Cela me donne un tuple avec toutes sortes de détails sur le certificat, mais je ne vois nulle part une entrée pour la clé publique. Comment puis-je obtenir la clé publique de ce certificat? Devrait être simple mais je ne trouve aucune fonction dans le module public_key pour cela.

Répondre

4

Ok, voici la fonction complète d'un module:

-module(crypto_helper). 
-include_lib("public_key/include/public_key.hrl"). 
-export([get_public_key_from_cert/1]). 

get_public_key_from_cert(PathToCert) -> 
    {ok, PemBin} = file:read_file(PathToCert), 
    PemEntries = public_key:pem_decode(PemBin), 
    {value, CertEntry} = lists:keysearch(‘Certificate’, 1, PemEntries) 
    {_, DerCert, _} = CertEntry, 
    Decoded = public_key:pkix_decode_cert(DerCert, otp), 
    PublicKey = Decoded#'OTPCertificate'.tbsCertificate#'OTPTBSCertificate'.subjectPublicKeyInfo#'OTPSubjectPublicKeyInfo'.subjectPublicKey, 
    PublicKey. 

Maintenant, vous pouvez l'utiliser comme suit:

PublicKey = crypto_helper:get_public_key_from_cert("/usr/admin/myServer/priv/certificate.pem"), 
EncryptedMsg = public_key:encrypt_public(<<"Hallo">>, PublicKey), 
3

public_key:pem_entry_decode(Certificate) renvoie un enregistrement Certificate. Pour en extraire la clé publique, vous devez charger les définitions d'enregistrement. Dans le shell Erlang, tapez:

rr(public_key). 

Après avoir chargé les définitions d'enregistrement dans la coquille, renvoient des valeurs contiennent les noms de champs, ainsi que les valeurs de champ, ce qui devrait rendre les choses un peu plus clair.

Dans un module Erlang, chargez le fichier d'en-tête comme ceci:

-include_lib("public_key/include/public_key.hrl"). 

Ensuite, vous pouvez extraire l'information clé publique comme ceci:

DecodedCertificate = public_key:pem_entry_decode(Certificate). 
DecodedCertificate#'Certificate'.tbsCertificate#'TBSCertificate'.subjectPublicKeyInfo. 

qui retourne:

#'SubjectPublicKeyInfo'{ 
    algorithm = 
     #'AlgorithmIdentifier'{ 
      algorithm = {1,2,840,113549,1,1,1}, 
      parameters = <<5,0>>}, 
    subjectPublicKey = 
     <<48,130,2,10,2,130,2,1,0,195,76,200,181,90,146,51,183, 
      39,91,176,28,95,117,241,28,140,...>>} 

Ou décomprimez un niveau plus loin pour obtenir la clé elle-même:

DecodedCertificate#'Certificate'.tbsCertificate 
    #'TBSCertificate'.subjectPublicKeyInfo 
    #'SubjectPublicKeyInfo'.subjectPublicKey. 
<<48,130,2,10,2,130,2,1,0,195,76,200,181,90,146,51,183,39, 
    91,176,28,95,117,241,28,140,212,223,132,...>> 
+0

Merci, ça m'a beaucoup aidé. Il ne manque que la dernière étape où vous décodez la clé publique et obtenez le type rsa_public_key() que vous devez utiliser dans public_key: decrypt_public/2. – Jeyhey

+0

Il est possible que subjectPublicKey pourrait être '{0, Keyder} = DecodedCertificate # 'Certificate'.tbsCertificate #' TBSCertificate'.subjectPublicKeyInfo # 'SubjectPublicKeyInfo'.subjectPublicKey.' Où Keyder est Der encodée, si la clé est de type RSA 'RsaPublicKey = clé publique: der_decode ('RSAPublicKey', KeyDer) .' Maintenant RsaPublicKey est de type rsa_public_key() –