Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

(Erlang) extracting public key from certificate in pem format

I have a certificate in pem format and I want to extract the public key (RSA). I'm already this far:

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

Now, I can do the following:

public_key:pem_entry_decode(Certificate).

This gives me a tuple with all sorts of details on the certificate but I can't see anywhere an entry for the public key. How do I get the public key from this certificate? Should be straight forward but I can't find any function in the public_key-module for that.

like image 231
Jeyhey Avatar asked Feb 21 '16 15:02

Jeyhey


People also ask

Does PEM contain public key?

A PEM file may contain just about anything including a public key, a private key, or both, because a PEM file is not a standard. In effect PEM just means the file contains a base64-encoded bit of data.

What is Privatekey PEM?

pem is an RSA private key generated alongside the certificate.


2 Answers

Ok, here is the complete function in a 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.

Now you can use it as follows:

PublicKey = crypto_helper:get_public_key_from_cert("/usr/admin/myServer/priv/certificate.pem"),
EncryptedMsg = public_key:encrypt_public(<<"Hallo">>, PublicKey),
like image 123
Jeyhey Avatar answered Oct 06 '22 21:10

Jeyhey


public_key:pem_entry_decode(Certificate) returns a Certificate record. To extract the public key from it, you need to load the record definitions. In the Erlang shell, type the following:

rr(public_key).

After loading the record definitions into the shell, return values will contain the field names as well as the field values, which should make things a bit clearer.

In an Erlang module, load the header file like this:

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

Then you can extract the public key info like this:

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

which returns:

#'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,...>>}

Or dig down one level further to get the key itself:

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,...>>
like image 28
legoscia Avatar answered Oct 06 '22 23:10

legoscia