From a99b7ff68aa194c260134ab2461af1a14a03e697 Mon Sep 17 00:00:00 2001
From: tmanevik This section describes examples of how to use the
+ This chapter is dedicated to showing some
- examples of how to use the public_key API. Keys and certificates
- used in the following sections are generated only for the purpose
- of testing the public key application. Some shell printouts in the following examples
+ are abbreviated for increased readability. Note that some shell printouts, in the following examples,
- have been abbreviated for increased readability. Public key data (keys, certificates etc) may be stored in PEM format. PEM files
- comes from the Private Enhanced Mail Internet standard and has a
- structure that looks like this: Public-key data (keys, certificates, and so on) can be stored in
+ Privacy Enhanced Mail (PEM) format.
+ The PEM files have the following structure: A file can contain several BEGIN/END blocks. Text lines between
- blocks are ignored. Attributes, if present, are currently ignored except
- for A file can contain several A DSA private key can look as follows: File handling is not done by the Note file handling is not done by the public_key application. This PEM file only has one entry, a private DSA key. The following PEM file has only one entry, a private DSA key: An RSA private key encrypted with a password can look as follows: This PEM file only has one entry a private RSA key. The following PEM file has only one entry, a private RSA key: In this example the password is "abcd1234". In this following example, the password is The following is an example of X509 certificates: This file includes two certificates The following file includes two certificates: Certificates may of course be decoded as usual ... Certificates can be decoded as usual: Parts of certificates can be decoded with
- public_key:der_decode/2 using that parts ASN.1 type.
- Although application specific certificate
- extension requires application specific ASN.1 decode/encode-functions.
- Example, the first value of the rdnSequence above is of ASN.1 type
- 'X520CommonName'. ({2,5,4,3} = ?id-at-commonName) Parts of certificates can be decoded with
+ ... but certificates can also be decode using the pkix_decode_cert/2 that
- can customize and recursively decode standard parts of a certificate. However, certificates can also be decoded using This call is equivalent to public_key:pem_entry_decode(CertEntry1) This call is equivalent to If you have public key data and and want to create a PEM file
- you can do that by calling the functions
- public_key:pem_entry_encode/2 and pem_encode/1 and then saving the
- result to a file. For example assume you have PubKey =
- 'RSAPublicKey'{} then you can create a PEM-"RSA PUBLIC KEY" file
- (ASN.1 type 'RSAPublicKey') or a PEM-"PUBLIC KEY" file
- ('SubjectPublicKeyInfo' ASN.1 type). If you have public-key data and want to create a PEM file
+ this can be done by calling functions
+ The second element of the PEM-entry will be the ASN.1 DER encoded
- key data. The second element of the PEM-entry is the ASN.1 or or: Suppose you have PrivateKey = #'RSAPrivateKey{}' and the
- plaintext Msg = binary() and the corresponding public key
- PublicKey = #'RSAPublicKey'{} then you can do the following.
- Note that you normally will only do one of the encrypt or
- decrypt operations and the peer will do the other.
- Encrypt with the private key Suppose you have the followwing private key and a corresponding public key: Then you can proceed as follows: Encrypt with the private key: Encrypt with the public key Encrypt with the public key: You normally do only one of the encrypt or decrypt operations,
+ and the peer does the other. Suppose you have PrivateKey = #'RSAPrivateKey{}'or
- #'DSAPrivateKey'{} and the plaintext Msg = binary() and the
- corresponding public key PublicKey = #'RSAPublicKey'{} or
- {integer(), #'DssParams'{}} then you can do the following. Note
- that you normally will only do one of the sign or verify operations
- and the peer will do the other. Suppose you have the following private key and a corresponding public key: Then you can proceed as follows: It might be appropriate to calculate the message digest before
- calling sign or verify and then you can use the none as second
- argument. You normally do only one of the sign or verify operations,
+ and the peer does the other. It can be appropriate to calculate the message digest before
+ calling SSH typically uses PEM files for private keys but has its
- own file format for storing public keys. The erlang public_key
- application can be used to parse the content of SSH public key files.<text>
-----BEGIN <SOMETHING>-----
@@ -51,19 +51,20 @@
-----END <SOMETHING>-----
<text>
- 1> {ok, PemBin} = file:read_file("dsa.pem").
{ok,<<"-----BEGIN DSA PRIVATE KEY-----\nMIIBuw"...>>}
- 2> [DSAEntry] = public_key:pem_decode(PemBin).
[{'DSAPrivateKey',<<48,130,1,187,2,1,0,2,129,129,0,183,
179,230,217,37,99,144,157,21,228,204,
@@ -80,21 +81,20 @@
1> {ok, PemBin} = file:read_file("rsa.pem").
{ok,<<"Bag Attribut"...>>}
- 2>[RSAEntry] = public_key:pem_decode(PemBin).
[{'RSAPrivateKey',<<224,108,117,203,152,40,15,77,128,126,
221,195,154,249,85,208,202,251,109,
119,120,57,29,89,19,9,...>>,
- {"DES-EDE3-CBC",<<"kÙeø¼pµL">>}}]
-
-
+ {"DES-EDE3-CBC",<<"kÙeø¼pµL">>}}]
- 3> Key = public_key:pem_entry_decode(RSAEntry, "abcd1234").
#'RSAPrivateKey'{version = 'two-prime',
modulus = 1112355156729921663373...2737107,
@@ -110,11 +110,12 @@
+
+ 1> {ok, PemBin} = file:read_file("cacerts.pem").
{ok,<<"-----BEGIN CERTIFICATE-----\nMIIC7jCCAl"...>>}
- 2> [CertEntry1, CertEntry2] = public_key:pem_decode(PemBin).
[{'Certificate',<<48,130,2,238,48,130,2,87,160,3,2,1,2,2,
9,0,230,145,97,214,191,2,120,150,48,13,
@@ -124,7 +125,7 @@
1,48,13,6,9,42,134,72,134,247,...>>>,
not_encrypted}]
- 2> Cert = public_key:pem_entry_decode(CertEntry1).
#'Certificate'{
tbsCertificate =
@@ -212,22 +213,23 @@
signature =
{0,
<<163,186,7,163,216,152,63,47,154,234,139,73,154,96,120,
- 165,2,52,196,195,109,167,192,...>>}}
-
-
- public_key:der_decode('X520CommonName', <<19,8,101,114,108,97,110,103,67,65>>).
{printableString,"erlangCA"}
- 3>{_, DerCert, _} = CertEntry1.
+
4> public_key:pkix_decode_cert(DerCert, otp).
#'OTPCertificate'{
tbsCertificate =
@@ -316,28 +318,26 @@
signature =
{0,
<<163,186,7,163,216,152,63,47,154,234,139,73,154,96,120,
- 165,2,52,196,195,109,167,192,...>>}}
-
+ 165,2,52,196,195,109,167,192,...>>}}
- 5> public_key:pkix_decode_cert(DerCert, plain).
-#'Certificate'{ ...}
-
+#'Certificate'{ ...}
1> PemEntry = public_key:pem_entry_encode('RSAPublicKey', RSAPubKey).
{'RSAPublicKey', <<48,72,...>>, not_encrypted}
@@ -348,7 +348,7 @@
3> file:write_file("rsa_pub_key.pem", PemBin).
ok
- 1> PemEntry = public_key:pem_entry_encode('SubjectPublicKeyInfo', RSAPubKey).
{'SubjectPublicKeyInfo', <<48,92...>>, not_encrypted}
@@ -363,96 +363,106 @@ ok
+
+ RsaEncrypted = public_key:encrypt_private(Msg, PrivateKey),
Msg = public_key:decrypt_public(RsaEncrypted, PublicKey),
- RsaEncrypted = public_key:encrypt_public(Msg, PublicKey),
Msg = public_key:decrypt_private(RsaEncrypted, PrivateKey),
+
+
+
+ Signature = public_key:sign(Msg, sha, PrivateKey),
true = public_key:verify(Msg, sha, Signature, PublicKey),
- Digest = crypto:sha(Msg),
Signature = public_key:sign(Digest, none, PrivateKey),
-true = public_key:verify(Digest, none, Signature, PublicKey),
-
+true = public_key:verify(Digest, none, Signature, PublicKey),
RFC 4716 SSH files looks confusingly like PEM files, - but there are some differences.
+ but there are some differences:1> {ok, SshBin} = file:read_file("ssh2_rsa_pub").
{ok, <<"---- BEGIN SSH2 PUBLIC KEY ----\nAAAA"...>>}
- This is equivalent to calling public_key:ssh_decode(SshBin, rfc4716_public_key). +
This is equivalent to calling
2> public_key:ssh_decode(SshBin, public_key).
[{#'RSAPublicKey'{modulus = 794430685...91663,
- publicExponent = 35}, []}]
-
+ publicExponent = 35}, []}]
OpenSSH public-key format looks as follows:
1> {ok, SshBin} = file:read_file("openssh_dsa_pub").
{ok,<<"ssh-dss AAAAB3Nza"...>>}
- This is equivalent to calling public_key:ssh_decode(SshBin, openssh_public_key). +
This is equivalent to calling
2> public_key:ssh_decode(SshBin, public_key).
[{{15642692...694280725,
#'Dss-Parms'{p = 17291273936...696123221,
q = 1255626590179665817295475654204371833735706001853,
g = 10454211196...480338645}},
- [{comment,"dhopson@VMUbuntu-DSH"}]}]
-
+ [{comment,"dhopson@VMUbuntu-DSH"}]}]
Known hosts - OpenSSH format looks as follows:
1> {ok, SshBin} = file:read_file("known_hosts").
{ok,<<"hostname.domain.com,192.168.0.1 ssh-rsa AAAAB...>>}
- Returns a list of public keys and their related attributes - each pair of key and attributes corresponds to one entry in - the known hosts file.
+Returns a list of public keys and their related attributes. + Each pair of key and attribute corresponds to one entry in + the known hosts file:
2> public_key:ssh_decode(SshBin, known_hosts).
[{#'RSAPublicKey'{modulus = 1498979460408...72721699,
@@ -461,19 +471,19 @@ true = public_key:verify(Digest, none, Signature, PublicKey),
{#'RSAPublicKey'{modulus = 14989794604088...2721699,
publicExponent = 35},
[{comment,"foo@bar.com"},
- {hostnames,["|1|BWO5qDxk/cFH0wa05JLdHn+j6xQ=|rXQvIxh5cDD3C43k5DPDamawVNA="]}]}]
-
+ {hostnames,["|1|BWO5qDxk/cFH0wa05JLdHn+j6xQ=|rXQvIxh5cDD3C43k5DPDamawVNA="]}]}]
Authorized keys - OpenSSH format looks as follows:
1> {ok, SshBin} = file:read_file("auth_keys").
{ok, <<"command=\"dump /home\",no-pty,no-port-forwarding ssh-rsa AAA...>>}
- Returns a list of public keys and their related attributes - each pair of key and attributes corresponds to one entry in - the authorized key file.
+Returns a list of public keys and their related attributes. + Each pair of key and attribute corresponds to one entry in + the authorized key file:
2> public_key:ssh_decode(SshBin, auth_keys).
[{#'RSAPublicKey'{modulus = 794430685...691663,
@@ -485,16 +495,15 @@ true = public_key:verify(Digest, none, Signature, PublicKey),
#'Dss-Parms'{p = 17291273936185...763696123221,
q = 1255626590179665817295475654204371833735706001853,
g = 10454211195705...60511039590076780999046480338645}},
- [{comment,"dhopson@VMUbuntu-DSH"}]}]
-
+ [{comment,"dhopson@VMUbuntu-DSH"}]}]
If you got a public key
N> SshBin = public_key:ssh_encode([{PubKey, Attributes}], openssh_public_key),
<<"ssh-rsa "...>>
N+1> file:write_file("id_rsa.pub", SshBin).
--
cgit v1.2.3