TKey Signature tool released

Today we are publishing another officially supported application, TKey Signature tool (tkey-sign):

TKey Signature tool is a command line tool (tkey-sign) for signing and verifying files using a cryptographic signature done on the Tillitis TKey. It uses the TKey signer (the same device app tkey-ssh-agent uses) for the cryptographic signatures.

How does it work?

tkey-sign first hashes the message file which produces a file digest. The digest is sent to signer on the TKey which signs the digest with the private key and sends the signature back to tkey-sign. For more details, see our note below on cryptography.

As usual on the TKey, the cryptographic key pair used for the signature is based on the TKey’s Compound Device Identifier (CDI) which means the key pair is generated by a combination of the hardware and the integrity of the signer app. Most importantly the private key never leaves the TKey.

The key pair which is generated when tkey-sign is loading signer can be modified by the user by supplying an optional User Supplied Secret, meaning the key pair is then created by a combination of 1) something the user has (the TKey), 2) something the user knows (the USS), and, 3) the integrity of the signer device app.


Store the public key in a file:

$ tkey-sign -G -p

You will need the public key both for signing because the signing operation checks the loaded device app’s public key is what you expect it to be and, of course, for verifying the signature later.

Sign a file:

$ tkey-sign -S -m message.txt -p

This stores the signature in the default file, the same as the message file + “.sig”, in this case “message.txt.sig”.
Note that both -S and -G will automatically load signer. If the app is already loaded you get a warning about it since you’re about to use an already existing key pair:

$ tkey-sign -S -m message.txt -p
WARNING: App already loaded.

It also warns you if the loaded signer‘s public key is different from the expected public key:

$ tkey-sign -S -m message.txt -p
Public key from file not equal to loaded app's

If you want to modify the measured identity of the signer you can provide a User Supplied Secret when it is being loaded. Call tkey-sign when using -S or -G with --uss to be prompted for a phrase or use --uss-file if your USS is stored in a file (use “-” as the file name for stdin). Example signing with USS prompt:

$ tkey-sign -S -m message.txt -p --uss
Enter phrase for the USS:
Repeat the phrase:

Verify a signature over a message file using the default signature file (same as message file + “.sig”), in this case “message.txt.sig”:

$ tkey-sign -V -m message.txt -p
Signature verified

If the verification succeeds the exit code is 0. If the verification fails the exit code is 1 and it outputs an error:

$ tkey-sign -V -m message.txt -p
Error verifying: signature not valid

When verifying you need the message file, the public key file and the signature file but you don’t need any TKey. In fact, you don’t even need the tkey-sign program. You can use signify (originally from OpenBSD, but ported to many others) if you first produce a SHA-512 digest file and verify the signature on the digest. We provide a handy script, signify-verify that does this.

For typical use, you would publish your public key somewhere and distribute the signature together with the signed file.

Reproducible builds and anti-virus

Note that some anti-virus programs, especially on Windows, can mark tkey-sign and many other Go programs as suspicious. More about this in the Go FAQ.

We have attempted to be as transparent as possible and the released binaries, at least for Linux and Windows, are totally reproducible from source. We’re uncertain about macOS because it’s not a statically linked program, but that too should be reproducable, at least if you’re running the same macOS version. This means many people at least have a chance to read the source code and verify that the binaries we release don’t include any malicious code.

A note on the cryptography

The message file is hashed with SHA-512. The cryptographic signature of the digest is done with the Ed25519 elliptic curve algorithm. We only sign the digest of the file, not the entire file.

Many signing algorithms work by signing only a hash digest of the message. Ed25519 typically works differently but internally hashes the message to be signed.

We do not want to send the entire message over to the TKey because:

  1. TKey has limited amount of RAM.
  2. TKey has limited bandwidth.

We might still add a possibility to send an entire message file to be incrementally hashed on the TKey but for large files this will be a nuisance.


Image attribution: Clker-Free-Vector-Images