Next: openssl SSL/TLS, Previous: openssl CIPHER, Up: SXEmacs OpenSSL API [Contents][Index]
While keys for symmetric ciphers can be easily stored as strings, keys for asymmetric algorithms are more complex. The openssl API therefore provides a dedicated primitive type, called pkey. Pkey objects can contain key pairs – i.e. pairs of public keys and corresponding private keys, public keys, and also certificates. They are general container object for various subtypes such as RSA, DSA, EC, and DH keys.
However, you cannot directly create such a pkey object nor access nor modify parts of it. Pkey objects are actually meant as transporter objects to simplify those functions which need them.
Return t if object is a pkey, nil otherwise.
Return the size a public key pkey in bits.
Return non-nil if pkey contains private data.
Note: This function is not native OpenSSL.
Return a copy of pkey stripped by the private data.
Note: This function is not native OpenSSL.
The above functions have a generic character because they are
independent from the choice of algorithm, see below.  For each of
these algorithms we provide a constructor function
ossl-algo-generate-key and a subtype predicate, named
ossl-algo-pkey-p.  In case of RSA and DSA we also support
a subkey check.
Note: At the moment we do not provide the creation of DH-keys.
Now the first important asymmetric algorithm is RSA.  As mentioned in
the general introduction OpenSSL can be built without it.  The
following functions therefore exist iff (featurep 'openssl-rsa)
evaluates to t.
Return an RSA public key with of length bits and exponent exp.
Return t iff pkey is of RSA type.
Return t if pkey1 is a subkey of pkey2, nil
otherwise, i.e. if pkey1 has the same public key data as
pkey2 and pkey2 has all private data.
Note: This function is not native OpenSSL.
(setq rsaexmpl (ossl-rsa-generate-key 2048 3)) ⇒ #<OpenSSL RSA private/public key, size 2048> (ossl-rsa-pkey-p rsaexmpl) ⇒ t (ossl-pkey-private-p rsaexmpl) ⇒ t
(setq rsapub (ossl-pkey-get-public rsaexmpl)) ⇒ #<OpenSSL RSA public key, size 2048> (ossl-pkey-private-p rsapub) ⇒ nil (ossl-rsa-subkey-p rsapub rsaexmpl) ⇒ t
Another important asymmetric algorithm is DSA.  The presence of DSA
support in the underlying library can be checked by (featurep
'openssl-dsa).  Nonetheless, it is very unlikely to face an OpenSSL
installation without DSA or RSA.
Return a DSA public key with of length bits seeded with (optional) seed.
Return t if pkey is of DSA type, nil otherwise.
Return t if pkey1 is a subkey of pkey2, nil
otherwise, i.e. if pkey1 has the same public key data as
pkey2 and pkey2 has all private data.
Note: This function is not native OpenSSL.
(setq dsaexmpl (ossl-dsa-generate-key 1024)) ⇒ #<OpenSSL DSA private/public key, size 384> (ossl-dsa-pkey-p dsaexmpl) ⇒ t (ossl-pkey-private-p dsaexmpl) ⇒ t
(setq dsapub (ossl-pkey-get-public dsaexmpl)) ⇒ #<OpenSSL DSA public key, size 384> (ossl-pkey-private-p dsapub) ⇒ nil (ossl-dsa-subkey-p dsapub dsaexmpl) ⇒ t
Elliptic curve cryptography is quite new and is possibly missing on
many systems.  Use (featurep 'openssl-ec) to check for elliptic
curve support.  Another particularity of the ec system is that it is
based on a fixed set of curves which can be referred to by name.  At
the moment we do not support creating custom curves.
Return a list of builtin elliptic curves.
Return a EC public key on curve.
curve may be any symbol from (ossl-ec-available-curves).
Note: At the moment we do not support creating custom curves.
Return t if pkey is of EC type, nil otherwise.
(ossl-ec-available-curves)
  ⇒ (Oakley-EC2N-4 Oakley-EC2N-3 wap-wsg-idm-ecid-wtls12
      wap-wsg-idm-ecid-wtls11 wap-wsg-idm-ecid-wtls10
      wap-wsg-idm-ecid-wtls9 wap-wsg-idm-ecid-wtls8
      wap-wsg-idm-ecid-wtls7 wap-wsg-idm-ecid-wtls6
      wap-wsg-idm-ecid-wtls5 wap-wsg-idm-ecid-wtls4
      wap-wsg-idm-ecid-wtls3 wap-wsg-idm-ecid-wtls1 c2tnb431r1
      c2pnb368w1 c2tnb359v1 c2pnb304w1 c2pnb272w1 c2tnb239v3
      c2tnb239v2 c2tnb239v1 c2pnb208w1 c2tnb191v3 c2tnb191v2
      c2tnb191v1 c2pnb176v1 c2pnb163v3 c2pnb163v2 c2pnb163v1 sect571r1
      sect571k1 sect409r1 sect409k1 sect283r1 sect283k1 sect239k1
      sect233r1 sect233k1 sect193r2 sect193r1 sect163r2 sect163r1
      sect163k1 sect131r2 sect131r1 sect113r2 sect113r1 prime256v1
      prime239v3 prime239v2 prime239v1 prime192v3 prime192v2
      prime192v1 secp521r1 secp384r1 secp256k1 secp224r1 secp224k1
      secp192k1 secp160r2 secp160r1 secp160k1 secp128r2 secp128r1
      secp112r2 secp112r1)
(setq ecexmpl (ossl-ec-generate-key 'secp224r1)) ⇒ #<OpenSSL EC private/public key, size 512> (ossl-ec-pkey-p ecexmpl) => t (ossl-pkey-private-p ecexmpl) ⇒ t
(setq ecpub (ossl-pkey-get-public ecexmpl)) ⇒ #<OpenSSL EC public key, size 512> (ossl-pkey-private-p ecpub) ⇒ nil
Finally, there is the DH key exchange.  Its presence can be checked
by (featurep 'openssl-dh).  At the moment we do not provide
constructor functions.
Return t if pkey is of DH type, nil otherwise.
Once you have a pkey object you can use it for encryption/decryption, and/or signing/verification. Talking in OpenSSL hybrid encryption and decryption is referred to as sealing and opening, respectively.
Return an envelope derived from encrypting string by cipher under pkey with the hybrid technique.
That is, create a random key/iv pair for the symmetric encryption with cipher and encrypt that key/iv asymmetrically with the provided public key.
The envelope returned is a list
(encrypted_string encrypted_key encrypted_iv)
where
encrypted_string is the (symmetrically) encrypted message
encrypted_key is the (asymmetrically) encrypted random key
encrypted_iv is the (asymmetrically) encrypted random iv
Note: You probably want to put a wrapping encoder function
(like base16-encode-string) around it, since this function
returns binary string data.
Return the deciphered message string from an envelope obtained
by ossl-seal.
ossl-seal)
In the following example we reuse the keys generated above.
(let ((envl
       (ossl-seal 'AES-256-CBC "I do not want to tell" rsaexmpl)))
  (setq str (car envl)
        key (nth 1 envl)
        iv (nth 2 envl))
  (mapcar #'base16-encode-string envl))
  ⇒ ("0e6a38b28efea3ca4901b268c141d7ac23ed5f8fa598d23d9846fe3ec1
       47278e"
      "167911a73b0a228b24e78bdd37197ec95b21bed3bbd62d1915d8fac791
       7915fd49fdd9774e7906ca53ed3bf4fb20de8339e628d469a496f7351c
       06fddda49b71c90e73e31c406cfb0f0fb7411d1c9d49842603c45415cc
       3a8f660c728e8f05c6479d004f5068a7969294b4cc81e13dd257df37dc
       886b11266a3ccba576396d200ebb1a3e8f7185fdbc6de40b63964562f9
       1cbe39118a07415c030fd4c3e25bbe2a64b2ab635b2ef9a71a5ddeeaf0
       4a73d7cd04ad334d1de04228db5a9fb9aebfa6a9dc9d76af5ec329b360
       d1cd8da45868450a3bc5c41bba95a0ad74439f7d5edffcdf7dff09c296
       35ae13215be1ae55f5d2b5e97d6a4d523470eef050b07193"
      "ab458ccb46cbc092c31614e997cd176b")
(ossl-open 'AES-256-CBC str rsaexmpl key iv) ⇒ "I do not want to tell"
The above example is nice but does not demonstrate the real power of
hybrid encryption.  In the following example we reuse the public
subkey rsapub of rsaexmpl from above.  Also you will
notice that the random key/iv pair has changed and thus the resulting
encrypted string is not the same.
(let ((envl
       (ossl-seal 'AES-256-CBC "I do not want to tell" rsapub)))
  (setq str (car envl)
        key (nth 1 envl)
        iv (nth 2 envl))
  (mapcar #'base16-encode-string envl))
  ⇒ ("93a5b3f2eb5a2eaee44805150717bb325b4e90be947591cc46b7819d3f
       4ec284"
      "300b9ab5a79524fdcb40fbed6bae7e9c470baa0d230f9b97c9b35de442
       62f82b626ef7668329d34cffc3eeddf535a879e974825e984c7e045c0a
       526b3b58453ae55926af519400f32c4aee7115088068fcb6fc75ce78c5
       b6d61bbaf90f0c4aff1d83efd63c45c62989c29efda187bcbd94edf9f1
       427ec8dce22cd6333e8196120285dc5bb224b9d7e9ecfb23e016475706
       5da6f999560d010adaf0465b108b2a84989ff8bd17778b61875f633a35
       a02c2cc1fdf3a3e50ad4a5fb7ad9a05b1a3a1818a21f3d7c71a33949f6
       437ee64bee60e1ae92ebea43ca524b15344a7fc2712e9758b98f1b2c9d
       c8ad3d074486f0d35fece7bf7b6ce979fa760aa7bd5854b2"
      "6979d574e8bc10dfddefd4cb017186a2")
(ossl-open 'AES-256-CBC str rsaexmpl key iv) ⇒ "I do not want to tell"
;; try with just the public part
(ossl-open 'AES-256-CBC str rsapub key iv)
error→ cannot open, key has no private key data
Also note you cannot use DSA keys for sealing. They are exclusively for signatures.
Signing and verifying works similar to sealing and opening. Instead of a cipher algorithm you need to specify a message digest algorithm. However, in this case the signature step requires a pkey with private data and the verification step can be done with only the public part of the key.
Return a signature obtained by signing string under digest with pkey.
That is, hash the message string with the message digest digest and encrypt the result with the private key pkey.
Note: Due to some relationship between the public key system and the message digest you cannot use every digest algorithm with every private key type. The most certain results will be achieved using RSA keys with RSA-* digests, DSA keys with DSA-* digests.
See ossl-available-digests.
Note: You probably want to put a wrapping encoder function
(like base16-encode-string) around it, since this returns
binary string data.
Return t iff sig is a valid signature of string
under digest obtained by pkey.
That is, hash the message string with the message digest
digest, then decrypt the signature sig with the public key
pkey.  Compare the results and return t iff both hashes
are equal.
ossl-sign)
Again we reuse the keys defined above.
(progn
  (setq sig (ossl-sign 'SHA1 "I owe you a beer" dsaexmpl))
  (base16-encode-string sig))
  ⇒ "302d021500c2e5197d266573216e4daa85e0a7e43424d0f031021451186
      24043517e0cd24f381d0e6c92f96198f297"
(ossl-verify 'SHA1 "I owe you a beer" sig dsapub) ⇒ t
;; we try to fake the signed text
(ossl-verify 'SHA1 "I owe you 10 beer" sig dsapub)
  ⇒ nil
Note that you cannot use all combinations of pkey and digest
algorithm.  Suitable digests can be found in the
(ossl-available-digests) list.  Given a digest dgst there
must be an entry RSA-dgst in order to use an RSA key for
signatures under dgst.  Respectively there must be an entry
DSA-dgst for DSA key pairs and all DSA-suitable digests can
also be used for EC keys.
In order to persistently store generated keys the openssl API provides a simple interface to the PEM routines. PEM is the format for key pairs or public keys.
Return a key (the public part) stored in a PEM structure from file.
Return a key stored in a PEM structure from file. If the (private part of the) key is protected with a password provide (optional) password.
Write pkey (the public part) in a PEM structure to file.
Write pkey in a PEM structure to file. The key itself is protected by (optional) cipher with password.
cipher can be set to nil and the key will not be
encrypted.  password is ignored in this case.
Return pkey as PEM encoded string.
Return pkey as PEM encoded string. The key itself is protected by (optional) cipher with password.
cipher can be set to nil and the key will not be
encrypted.  password is ignored in this case.
(ossl-pem-write-key "/tmp/mykey.pem" dsaexmpl)
(let ((stored (ossl-pem-read-key "/tmp/mykey.pem"))) (ossl-verify 'SHA1 "I owe you a beer" sig stored)) ⇒ t
(ossl-pem-public-key rsapub) ⇒ "-----BEGIN PUBLIC KEY----- MIIBIDANBgkqhkiG9w0BAQEFAAOCAQ0AMIIBCAKCAQEAtGE7JaGUsVIfLUJmzlkR qfB7CJjFlYU7tGmD7C1rBiGz0sjTlPwsMjwwCLP6byRvebVeDxGrxbeyZE3sSB4q oVbevhbwwBMY5+j/8q+3l7KbqoP9CGG40ZbEC6IOqFn8kOmliPdWUlogI1Gr4b7U R4F+TM6m3r3AQoxeqq+rR5kHat2mvBpxm0o8FZ2KW6ZCAkAXoA3NNCXtSUF9zA6A u3acUP4eiFAkS4Q6hIuZli4PzxvUugB5/ekyaa5cRzIEqIhh90mkpqjM9qpR15hk 39qiM/SxXmLlncU534byldSgnoIse3tnia4WRBm2qK3zTr24zaBtTTXfmRJMWQwZ ewIBAw== -----END PUBLIC KEY----- "
(ossl-pem-public-key rsaexmpl) ⇒ "-----BEGIN PUBLIC KEY----- MIIBIDANBgkqhkiG9w0BAQEFAAOCAQ0AMIIBCAKCAQEAtGE7JaGUsVIfLUJmzlkR qfB7CJjFlYU7tGmD7C1rBiGz0sjTlPwsMjwwCLP6byRvebVeDxGrxbeyZE3sSB4q oVbevhbwwBMY5+j/8q+3l7KbqoP9CGG40ZbEC6IOqFn8kOmliPdWUlogI1Gr4b7U R4F+TM6m3r3AQoxeqq+rR5kHat2mvBpxm0o8FZ2KW6ZCAkAXoA3NNCXtSUF9zA6A u3acUP4eiFAkS4Q6hIuZli4PzxvUugB5/ekyaa5cRzIEqIhh90mkpqjM9qpR15hk 39qiM/SxXmLlncU534byldSgnoIse3tnia4WRBm2qK3zTr24zaBtTTXfmRJMWQwZ ewIBAw== -----END PUBLIC KEY----- "
(ossl-pem-key rsaexmpl 'AES-256-CBC "foobar") ⇒ "-----BEGIN ENCRYPTED PRIVATE KEY----- MIIFHzBJBgkqhkiG9w0BBQ0wPDAbBgkqhkiG9w0BBQwwDgQIk4VVj28lKIgCAggA MB0GCWCGSAFlAwQBKgQQ0uzDwfFB2m5ZUCt8K1YSvwSCBNCcQuY1S1c7Blsm7QlH iHji7xWcigj6U7U6IQ0y/a6+U/ku2/IQc4I/sjsYNj1ZKBjkHxuWqVtGvKD/AB/r 2XFYkOpg7X2SvpVXuCkHk/B7l8ifQViqwu3k8r+8jHmLuxa21xysrTLOef8LmCkg ePaOArDKascJngpkUtMM269owh1ZBUSmKqQqR+jnpXw+dummdlr2tA0t3Bl+899q e6L7sZ330XRTnzyQUuZvBpV8bV0AlaI3jlPROu56MKiUiDU0n9lvzYegWGAJjOvS qYW3FPY/B7MczXCFQOmg3XWXWJ/2szRQnWvuM5imhwVF4YbPO30H6KG2sRc5u4Bs vym71CdlD77+YEw2dQ36bgjLE2v9aFIuuqqRlbNO1wUo1D0JFrN0ivGnliA6tCQ2 tADHeEqKeXjCk4GM+rZB9d/kx2RqTgqu+JolaO1+8lxWRMT+aLj5EPN8zHOaRhDL 3farG89PEOUvPRzkn+18laPBJ0o9AvwYC9Bmi072Lq7XtOIH0iELxY2RyQD0PLD2 cLdt5tkQDfuUhrUJuhh3waMDa7qe9lMGnxsmlapZn5FY1kZ6gBO79BBu9sFmsr1x IRDT5PJc2V+BU9fn3Vu6WM3P56x7WfUjycqpvmu7yshW8D/8KRNYbeBIAXuRKCoJ dRIp/c+UWSPDVb68NikRvTRvj0vVrGMsesRkl89uL6liGarGghEV9lwNDQB5XN0q wZ+4LXP4DZQlBK3g9Bq7rL6F3ZuxGdThjQO6IAve6MltfOIN/x/schcoE41g2y0D 0hn8vnDkGwWKFE59qOZ7/iQOOKJisF6MjxnkhlcTvG3ev2mrSsJHdiIoN9u8Zm6o Xca/k7JEs3rkr5MhrjxpGznq6Z5skEWEFFGD5XlXKYsHlP5YDxVXLED1cQHKcydC t2uPsB/Uqj4zl/lBc0/asQ8gyZiR2Fc5DHjUkmQ/5kH4LulvVLJgCC8JRs2AutBu DsqfvEj8uhmCuNYlsrOGrrOo/m2HPQ1DeoJcoL+H8KQG1WjPo0bnaV0Xlf6o+IkI G42pDGVeNSZDc+gqbXTzHDF0snOVDO7nfJ+kWmTFpHhI8Ht5H6SaaAIcgIQcWZgZ vA7e54XQ6HBUARFaPdw8kXyilu3lGunacjfipCdsOaF3WxGgdPmQTfuQOqglYhlc v/WPjyV9WgpEaJKM2Vcwb+CiOeteKnqp9ZLdmb4fZJNP2oIlKLtQSHsmdFGEr7BP 7hxoi/kcD9QpuC9CHn1rZC99ZwWBa+UmK5s+P8LJRfi6a8qhR3gA6H/JGZLFiW0C Vrmir9u33UkroKfn+JTuMZV5e+U7YNFSJhX95nbLTIx44ItyztGlE5+lHMPA+N/p +OQM2F0kzfSZ2F1M3x3iO4VPzfEC6vNBpOOhhssSoL9ThNYlCQOVa+QemEjmVuEs PLluotrTI3Cetk4nanvj4HGb6KjnkU1JdQ6iKSEl2JnYWrmNNoB3N06/h/7DQpiy p/tevEVZQxK2cOklJrgcuNtVXe3c/9OVRKDuu3m1GstbQ4pcqijc55kuEtA0tmvn S5WFFj4/cVucd2K3IOHCttEfgDwVNDDzG2shBsKT1JDY4aDOBD3xe+ggstVkGmRL ocNNE7QyxF/GOgW9iTQr/yOp9A== -----END ENCRYPTED PRIVATE KEY----- "
Next: openssl SSL/TLS, Previous: openssl CIPHER, Up: SXEmacs OpenSSL API [Contents][Index]