[CONTACT]

[ABOUT]

[POLICY]

large amounts dd cryptocurrency ea

Found at: gopher.blog.benjojo.co.uk:70/tls-https-server-from-a-yubikey

 Yubikey/Smartcard backed TLS servers
 ===
 ![](https://blog.benjojo.co.uk/asset/yKe0pA6tYk)

large

amounts

cryptocurrency

theft

 It has become clear that storing secrets in computers is
hard. The best demo to the world that storing secrets on
“online” computers is hard and sometimes devastating, is the large
amounts of cryptocurrency theft due to critical keys being in
memory of systems directly or indirectly connected to the
internet.

Yubikeys

 For the last one and a half years, I’ve had a set of
Yubikeys on my keychain. A Yubikey is a USB stick that acts like
a two factor token, but can also act as a smart card.
 Smart cards are neat, since they allow you to store
sensitive cryptographic keys on another removable device, and they
come with a guarantee that once they are programmed with a key
they will not give it back to a system (they can be
overwritten though)
 This allows someone to separate a cryptographic key from
the system it lives on. This is useful for things like SSH,
since it means you can have a key that moves on your person,
rather than a per machine key in the case that you use multiple
machines to access systems.
 Under the hood, all these smart cards are doing are the
operations that require the private key, like data signing and
decryption.
 I figured that we could also retrofit them to provide for
other roles where keys would normally be in memory (and
stealable), Like TLS/HTTPS servers!
 To start with, I took a spare yubikey I had never setup
and used the GPG tooling on Linux to setup the card and
generate keys.
 ```
 ben@eshwil:~$ gpg2 --card-status
 Reader ...........: 1050:0407:X:0
 Application ID ...: D2760001240102010006069118380000
 Version ..........: 2.1
 Manufacturer .....: Yubico
 Serial number ....: 0xxxxxxx
 Name of cardholder: [not set]
 Language prefs ...: [not set]
 Sex ..............: unspecified
 URL of public key : [not set]
 Login data .......: [not set]
 Signature PIN ....: not forced
 Key attributes ...: rsa2048 rsa2048 rsa2048
 Max. PIN lengths .: 127 127 127
 PIN retry counter : 3 0 3
 Signature counter : 0
 Signature key ....: [none]
 Encryption key....: [none]
 Authentication key: [none]
 General key info..: [none]
 ```
 Here we see that the system is able to query the card
and is empty and ready to program a key on to it.
 ```
 ben@eshwil:~$ gpg2 --card-edit
 gpg/card> admin
 Admin commands are allowed
 gpg/card> generate
 Make off-card backup of encryption key? (Y/n) n
 Please note that the factory settings of the PINs are
    PIN = '123456'     Admin PIN = '12345678'
 You should change them using the command --change-pin
 What keysize do you want for the Signature key? (2048)
 What keysize do you want for the Encryption key? (2048)
 What keysize do you want for the Authentication key? (2048)
 Please specify how long the key should be valid.
          0 = key does not expire
         = key expires in n days
       w = key expires in n weeks
       m = key expires in n months
       y = key expires in n years
 Key is valid for? (0) 91
 Key expires at Tue 31 Jul 2018 11:52:47 EDT
 Is this correct? (y/N) Y
 You need a user ID to identify your key; the software
constructs the user ID
 from the Real Name, Comment and Email Address in this
form:
     "Heinrich Heine (Der Dichter)
"
 Real name: yubitls.benjojo.co.uk
 E-mail address:
 Comment:
 You selected this USER-ID:
     "yubitls.benjojo.co.uk"
 Change (N)ame, (C)omment, (E)-mail or (O)kay/(Q)uit? O
 gpg: /home/ben/.gnupg/trustdb.gpg: trustdb created
 gpg: key 3FCD18FAB4FC1CF9 marked as ultimately trusted
 gpg: directory '/home/ben/.gnupg/openpgp-revocs.d' created
 gpg: revocation certificate stored as
'/home/ben/.gnupg/openpgp-revocs.d/8236069819F168BB781D31B53FCD18FAB4FC1CF9.rev'
 public and secret key created and signed.
 ```
 Above we used the smart card itself to generate keys. We
could have generated keys locally on the system and then uploaded
keys to the card, however that would mean that at some point
the keys that we are trying to secure would have been visible
to a system connected to the internet. This is not optimal
since if I had malware on my laptop while I did this, the keys
could have been copied without me knowing.
 Generation on the card ensures that the system provisioning
the smart card never sees the sensitive key material, all of
the generation is done on the card itself.
 ```
 gpg/card> list
 Reader ...........: 1050:0407:X:0
 Application ID ...: D2760001240102010006069118380000
 Version ..........: 2.1
 Manufacturer .....: Yubico
 Serial number ....: 0xxxxxxx
 Name of cardholder: [not set]
 Language prefs ...: [not set]
 Sex ..............: unspecified
 URL of public key : [not set]
 Login data .......: [not set]
 Signature PIN ....: not forced
 Key attributes ...: rsa2048 rsa2048 rsa2048
 Max. PIN lengths .: 127 127 127
 PIN retry counter : 3 0 3
 Signature counter : 4
 Signature key ....: 8236 0698 19F1 68BB 781D  31B5 3FCD
18FA B4FC 1CF9
       created ....: 2018-05-01 15:53:07
 Encryption key....: 2E4F E811 2814 EA33 FA1E  C23F 99F1
667F C9BE 44A3
       created ....: 2018-05-01 15:53:07
 Authentication key: 1A1A 6594 F7D6 5EA2 0E1C  C0AE 5786
AF8D 1462 E84D
       created ....: 2018-05-01 15:53:07
 General key info..: pub  rsa2048/3FCD18FAB4FC1CF9 2018-05-01
yubitls.benjojo.co.uk
 sec>  rsa2048/3FCD18FAB4FC1CF9  created: 2018-05-01  expires:
2018-07-31
card-no: 0006 06911838
 ssb>  rsa2048/5786AF8D1462E84D  created: 2018-05-01  expires:
2018-07-31
card-no: 0006 06911838
 ssb>  rsa2048/99F1667FC9BE44A3  created: 2018-05-01  expires:
2018-07-31
card-no: 0006 06911838
 ```
 Now that we have our key setup, it's worth going through
where the key will be needed to serve as a HTTP/TLS server.
 ![](https://blog.benjojo.co.uk/asset/JNFBfZcoYH)
 To start a TLS connection, the client states who it is
expecting to see to the server, as well as some information about
what the clients capabilities and requirements are. The server
then replies with a certificate and a signature to prove it has
the key for that certificate, plus information on what the
clients capabilities are as well.
 Assuming all is well, the two systems figure out a
solution to connect, and then begin communicating with encryption
enabled.

unless some other creative solutions are involved

 This means that for every fresh connection the server must
do operations that involve the sensitive private key. In almost
every case this means it has to be accessible in memory for a
server to function (unless some other creative solutions are
involved). However here we want to move this operation to a external
bit of hardware.

golang

 Where most programming languages/runtimes link to OpenSSL,
golang is different in that it has its own internal TLS stack
internally. This is useful for us, since we want to make a "fake
private key" that has the function calls of a regular private key,
but actually does other logic with those function calls.
 ![](https://blog.benjojo.co.uk/asset/cK4HFF80jp)

implemented a library

 Lucky for us, someone has already implemented a library
that implements a `crypto.PrivateKey` but where the backend is a
GPG Agent. This is especially useful in our case since the
Yubikey works with a GPG agent.
 ![](https://blog.benjojo.co.uk/asset/ysD8DsT1T8)
 Now that we have a chain that works, we can create a
Certificate Signing Request file for the domain we are going to use:
 ```
 $ ./yubiTLS -csr.cn yubitls.benjojo.co.uk -signcsr
 You appear to have not selected a key to use, or the key
you selected
 Does not exist in the agent at this time, Do you see
your key in this list?
 2018/05/02 15:39:33 Key: 09A25C1D64EF0E7170F9C3A0FAF9080B02216FD5
- {Keygrip:09A25C1D64EF0E7170F9C3A0FAF9080B02216FD5 Type:1
SerialNo:D2760001240102010006069118380000 CardID:OPENPGP.3 Cached:false Protection:2
Fingerprint:fe:96:e4:c2:68:f7:2f:75:a7:94:8d:1f:24:20:28:be TimeToLive: conn: publicKey:{N:0xc42000c340 E:65537}}
 $ ./yubiTLS -csr.cn yubitls.benjojo.co.uk -signcsr -keyid
09A25C1D64EF0E7170F9C3A0FAF9080B02216FD5
 $ ls *.csr
 yubitls.benjojo.co.uk.csr
 ```

Let's Encrypt

SSL For Free

 We can then use Let's Encrypt via SSL For Free to get
this CSR signed.
 ![](https://blog.benjojo.co.uk/asset/k5tiMHeNNQ)
 After verifying the domain, we tell the site we have a
CSR:
 
 
 
 After that, we obtain a SSL certificate for the key on
our Yubikey!
 ![](https://blog.benjojo.co.uk/asset/fiZWs612n8)
 Then we can provide these certificates to the server, and
run the HTTPS demo server!
 ```
 $ ./yubiTLS -keyid 09A25C1D64EF0E7170F9C3A0FAF9080B02216FD5
-crtpath cert.crt -cacrtpath bundle.crt
 2018/05/02 15:49:57 Listening
 ```
 The first time you visit it, it may ask for the PIN to
unlock the Yubikey, it was amusing when this happened for the
first time, because I knew at that point it worked :)
 ![](https://blog.benjojo.co.uk/asset/Mav2Q3q4XR)
 After we enter the pin, we get content served from a
HTTPS server backed by a key contained on a USB stick!
 ![](https://blog.benjojo.co.uk/asset/WHOauS3sM9)
 If you want to try this out for yourself on a **blank
yubikey** you can find the code on my github here:
https://github.com/benjojo/yubiTLS

Twitter

RSS

 And if you enjoyed this, you will be glad to know that I
am going to be at Recurse Center in NY for the next 7
weeks! Meaning you can follow my Twitter or RSS to keep up with
the other silly (or sometimes sensible) things I will do!
 Until next time!