From a99b7ff68aa194c260134ab2461af1a14a03e697 Mon Sep 17 00:00:00 2001 From: tmanevik Date: Thu, 23 Apr 2015 15:06:05 +0200 Subject: Editorial changes --- lib/public_key/doc/src/using_public_key.xml | 221 +++++++++++++++------------- 1 file changed, 115 insertions(+), 106 deletions(-) (limited to 'lib/public_key/doc/src/using_public_key.xml') diff --git a/lib/public_key/doc/src/using_public_key.xml b/lib/public_key/doc/src/using_public_key.xml index 450bd7e35f..69b8c0dcb9 100644 --- a/lib/public_key/doc/src/using_public_key.xml +++ b/lib/public_key/doc/src/using_public_key.xml @@ -22,27 +22,27 @@ Getting Started + + + + using_public_key.xml -
- General information +

This section describes examples of how to use the + public_key API. Keys and certificates used in the following + sections are generated only for testing the public_key + application.

-

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.

- -
- +
- PEM files -

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:

+ PEM Files +

Public-key data (keys, certificates, and so on) can be stored in + Privacy Enhanced Mail (PEM) format. + The PEM files have the following structure:

<text> -----BEGIN <SOMETHING>----- @@ -51,19 +51,20 @@ -----END <SOMETHING>----- <text> -

A file can contain several BEGIN/END blocks. Text lines between - blocks are ignored. Attributes, if present, are currently ignored except - for Proc-Type and DEK-Info that are used when the DER data is - encrypted.

+

A file can contain several BEGIN/END blocks. Text lines between + blocks are ignored. Attributes, if present, are ignored except + for Proc-Type and DEK-Info, which are used when DER + data is encrypted.

- DSA private key + DSA Private Key +

A DSA private key can look as follows:

+

File handling is not done by the public_key application.

-

Note file handling is not done by the public_key application.

1> {ok, PemBin} = file:read_file("dsa.pem"). {ok,<<"-----BEGIN DSA PRIVATE KEY-----\nMIIBuw"...>>} -

This PEM file only has one entry, a private DSA key.

+

The following PEM file has only one entry, a private DSA key:

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 @@
- RSA private key encrypted with a password. + RSA Private Key with Password +

An RSA private key encrypted with a password can look as follows:

1> {ok, PemBin} = file:read_file("rsa.pem"). {ok,<<"Bag Attribut"...>>} -

This PEM file only has one entry a private RSA key.

+

The following PEM file has only one entry, a private RSA key:

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">>}}]
-

In this example the password is "abcd1234".

+

In this following example, the password is "abcd1234":

3> Key = public_key:pem_entry_decode(RSAEntry, "abcd1234"). #'RSAPrivateKey'{version = 'two-prime', modulus = 1112355156729921663373...2737107, @@ -110,11 +110,12 @@
X509 Certificates +

The following is an example of X509 certificates:

1> {ok, PemBin} = file:read_file("cacerts.pem"). {ok,<<"-----BEGIN CERTIFICATE-----\nMIIC7jCCAl"...>>} -

This file includes two certificates

+

The following file includes two certificates:

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}] -

Certificates may of course be decoded as usual ...

+

Certificates can be decoded as usual:

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

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)

+ 165,2,52,196,195,109,167,192,...>>}}
+ +

Parts of certificates can be decoded with + public_key:der_decode/2, using the ASN.1 type of that part. + However, an application-specific certificate extension requires + application-specific ASN.1 decode/encode-functions. + In the recent example, the first value of rdnSequence is + of ASN.1 type 'X520CommonName'. ({2,5,4,3} = ?id-at-commonName):

public_key:der_decode('X520CommonName', <<19,8,101,114,108,97,110,103,67,65>>). {printableString,"erlangCA"} -

... 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 pkix_decode_cert/2, + which can customize and recursively decode standard parts of a certificate:

+ 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,...>>}} -

This call is equivalent to public_key:pem_entry_decode(CertEntry1)

+

This call is equivalent to public_key:pem_entry_decode(CertEntry1):

5> public_key:pkix_decode_cert(DerCert, plain). -#'Certificate'{ ...} - +#'Certificate'{ ...}
- Encoding public key data to PEM format + Encoding Public-Key Data to PEM Format -

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 + public_key:pem_entry_encode/2 and pem_encode/1 and + saving the result to a file. For example, assume that 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).

-

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 DER encoded + key data:

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 -

or

+

or:

1> PemEntry = public_key:pem_entry_encode('SubjectPublicKeyInfo', RSAPubKey). {'SubjectPublicKeyInfo', <<48,92...>>, not_encrypted} @@ -363,96 +363,106 @@ ok
- RSA public key cryptography -

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

+ RSA Public-Key Cryptography +

Suppose you have the followwing private key and a corresponding public key:

+ + PrivateKey = #'RSAPrivateKey{}' and + the plaintext Msg = binary() + PublicKey = #'RSAPublicKey'{} + + +

Then you can proceed as follows:

+ +

Encrypt with the private key:

RsaEncrypted = public_key:encrypt_private(Msg, PrivateKey), Msg = public_key:decrypt_public(RsaEncrypted, PublicKey), -

Encrypt with the public key

+

Encrypt with the public key:

RsaEncrypted = public_key:encrypt_public(Msg, PublicKey), Msg = public_key:decrypt_private(RsaEncrypted, PrivateKey), + +

You normally do only one of the encrypt or decrypt operations, + and the peer does the other.

+
- Digital signatures + Digital Signatures -

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:

+ + + PrivateKey = #'RSAPrivateKey{}' or + #'DSAPrivateKey'{} and the plaintext Msg = binary() + PublicKey = #'RSAPublicKey'{} or + {integer(), #'DssParams'{}} + +

Then you can proceed as follows:

Signature = public_key:sign(Msg, sha, PrivateKey), true = public_key:verify(Msg, sha, Signature, PublicKey), -

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 sign or verify, and then use none as + second argument:

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),
- SSH files + SSH Files

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.

+ own file format for storing public keys. The public_key + application can be used to parse the content of SSH public-key files.

- RFC 4716 SSH public key files + RFC 4716 SSH Public-Key Files

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 public_key:ssh_decode(SshBin, rfc4716_public_key):

2> public_key:ssh_decode(SshBin, public_key). [{#'RSAPublicKey'{modulus = 794430685...91663, - publicExponent = 35}, []}] - + publicExponent = 35}, []}]
- Openssh public key format + OpenSSH Public-Key Format +

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 public_key:ssh_decode(SshBin, openssh_public_key):

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 - + Known Hosts - OpenSSH Format +

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 + Authorized Keys - OpenSSH Format +

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"}]}]
- Creating an SSH file from public key data + Creating an SSH File from Public-Key Data

If you got a public key PubKey and a related list of attributes Attributes as returned - by ssh_decode/2 you can create a new ssh file for example

+ by ssh_decode/2, you can create a new SSH file, for example:

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