Jump to Navigation

Me on Twitter

  • @Fyrd Do you know of a tool to list features used on a given website in order to obtain the minimum browsers requirements to make it work ? 15 weeks 3 days ago
  • Quelqu'un aurait une place disponible pour #devoxx pour un collègue ? 22 weeks 4 days ago
  • Favorite tool of the day : https://t.co/1wGUhgh5rc @AtomEditor It also displays @PlantUML diagrams ! 30 weeks 4 days ago
  • With typeset you can do weird things like : myvar=hello echo $myvar # prints 'HELLO' in caps https://t.co/bLNDQrmokn 33 weeks 4 days ago
  • I've just stared at a 22mn intro to this #game ! Zachtronics | TIS-100 - https://t.co/36Tlp5HBB6 34 weeks 6 days ago
  • RT @nicoespeon: Six Tiny But Awesome #ES6 Features by @davidwalshblog https://t.co/kYNcYMrhVe 36 weeks 10 hours ago
  • If u ever build Jenkins jobs with maven use the following delimiters 2 avoid variable clash : @maven_var@ + $jenkins_var vs ${var} for both 39 weeks 4 days ago
  • Easy in 2016 : run Java app in JVM in docker container in snap on snappy in the cloud on a VM on a bare metal... https://t.co/2fNFiqElQT 1 year 7 weeks ago
  • First real consistent theme since years. Great ! https://t.co/0JjA7JDcmb 1 year 8 weeks ago
  • @nic0b0 Sample : symmetric encryption https://t.co/iJARAimPTT 1 year 9 weeks ago

A paper backup for your private key

This article focuses on Android and Java keystores, but it applies as well to any key that can be printed as plain text.

Before printing a private key, make sure that it is what you need : for instance you would rather print a revocation certificate for an OpenPGP key since you can still sign content with a new key. This is not the case for Android, which requires the same key for every release of an application.

Securing a private key

Talking about digital security, there are several techniques to keep a private key secure :

  • choose strong algorithms with long enough keys
  • choose a strong password (and don't tell it)
  • keep it in a safe place (don't copy it on all your USB keys or your phone)
  • be paranoid
  • ...
Anyway, there is always a risk that you loose access to your key : whether it was deleted or you've lost the password. Because of this you should keep a copy in a safe place.
There are many ways to keep a backup key. This article takes the Android case to explain how to print a private key to paper so that you can restore it even if your hard disk crashed or if you forgot the password.

The Android case

Android keychainAndroid requires developers to sign their applications with a digital certificate and that each future release be signed with the same certificate.

Since all releases of an application are signed with the same certificate, the system knows when an update is available for a given application and the end user is seamlessly notified.

Sadly, bad things happen when the developer (you) looses access to the certificate : he (you) will not be able to release updates for the application without it. Never. Ever.

Android does not currently support multiple certificates per application so the best you could do would be to release a new app with the same name, in the hope your users will find a way to it by themselves...

As years go on, you will have a new computer, wipe USB keys, reinstall OS, ...
So many dangerous operations for your digital certificates, hidden among millions of files !
If, like me, you are anxious at the idea of losing your certificates or passwords, just print a paper copy !
Although it is not invulnerable, paper should be less prone to mass erasing than a simple electronic file.

The idea is simple, not new, and you just need to know two commands to get a printable hard copy of your certificate.

Let's start.

Java keystores

Note : Although this article focuses on command line, you can choose the easy way and use a graphical tool to export / import all data.

Android uses jarsigner to sign apks (application files). Therefore, your key must live within a "JKS" file (Java keystore).

To deal with JKS you use the keytool command, which is included with the JDK (JDK 6+ is required to run commands from this article).

Here is a reminder of the Android recommended way to generate a certificate for signing applications :

keytool -genkeypair -keystore mykeys.jks -alias foo -keyalg RSA -keysize 2048 -validity 10000        

With this command, your JKS will be named mykeys.jks and your certificate aliased as "foo".

It is important to note than -genkeypair will not only generate a private & public key pair, but also wrap it in a self-signed X509 certificate. The alias you chose will then link to two main distincts components : the private key and the certificate.

Data in an Android keystoreFig. 1 -  A typical Java keystore with signing material for an Android application

A note about passwords

Java keystores support two kind of passwords : the one for the keystore itself, and one for each key (alias) it contains.

In this article, we use openssl to create keys and therefore give them passwords, while the keystore password is always set in the keytool command.

During creation, if you do not provide a password for a key, keytool will give it the same as the keystore. When reading a key, keytool will try the keystore password first, so you will only be prompted once if they are the same.

Still, keytool does require passwords on both keystore and keys (even if they are the same) and according to the documentation, they must be at least 6 characters long.

Therefore, although openssl allows keys without passwords, make sure to put one that's compatible with keytool (not empty and same as the keystore if you choose so) or you will get cryptic errors like division by zero or Error outputting keys and certificates with :

139832027854496:error:06065064:digital envelope routines:EVP_DecryptFinal_ex:bad decrypt:evp_enc.c:539:
139832027854496:error:23077074:PKCS12 routines:PKCS12_pbe_crypt:pkcs12 cipherfinal error:p12_decr.c:104:
139832027854496:error:2306A075:PKCS12 routines:PKCS12_item_decrypt_d2i:pkcs12 pbe crypt error:p12_decr.c:130:

Exporting keypair and certificate

Since JDK 6, keytool provides the -importkeystore command to import / export full data between keystores. Before that, only public parts could be exported. Unfortunately it is still not able to export private data to plain text : you will need to use another tool to achieve this : openssl.

keytool -importkeystore -srcstoretype jks -srcalias foo -deststoretype pkcs12 -srckeystore mykeys.jks -destkeystore foo.p12
openssl pkcs12 -in foo.p12 -out foo.pem -nodes

The first command exports all key/certificate data to a binary PKCS12 file. Make sure to give this file the same password as the exported key (see the note about passwords).

The second command converts the binary PKCS12 to readable text (also called PEM, or ASCII-armored).
By default the private key is still printed encrypted with a symmetric algorithm, so even if you get this key data, you will need the password to unlock it. The option -nodes bypasses this by allowing the key to be printed unencrypted.

You end up with two Base64-encoded elements in the file "foo.pem" : the private key and the certificate :

Key printed to paper

Bag Attributes
    friendlyName: foo
    localKeyID: 54 69 6D 65 20 31 33 33 39 35 32 31 39 38 37 38 35 37
Key Attributes: <No Attributes>

... (cut) ...
Bag Attributes
    friendlyName: foo
    localKeyID: 54 69 6D 65 20 31 33 33 39 35 32 31 39 38 37 38 35 37
subject=/C=FR/ST=France/L=Paris/O=nicobo.net/OU=IT/CN=M. Nicobo
issuer=/C=FR/ST=France/L=Paris/O=nicobo.net/OU=IT/CN=M. Nicobo

... (cut) ...


=> Print them down and keep the papers in a place safe from dangers like fire, unauthorized people, ....

You can remove the unnecessary text outside of BEGIN / END blocks (in grey above). On MS Windows, you may need to convert line breaks - which follow the Unix convention - to read the text.

One more advice before printing : make sure to use a font that does display all characters as different symbols or you might not be able to recover the key later. Check especially i,I,l,1 ( (upper & lower 'i', 'L' and one) and o,O,0 ('o' and zero) characters.

Restoring the certificate

When the big day has come and you want to restore your digital certificate from a piece of paper, simply type the key data back into a text file (let's call it "foo-restored.pem") then run the following commands :

openssl pkcs12 -export -in foo-restored.pem -out foo-restored.p12
keytool -importkeystore -srckeystore foo-restored.p12 -srcstoretype pkcs12 -destkeystore restored.jks -deststoretype jks -srcalias 1 -destalias foorestored

You could try an OCR software to scan the text from a photo or image. I have not been successful with this yet.

This time, the first line converts back the PEM data to binary PKCS12.
Don't miss the -export option, that was not used for the opposite transformation.

The second line imports back the key and certificate into your JKS keystore. If it already exists, it will be updated.
We did not specify an alias (-name) for the key on the openssl command so we use -srcalias 1 to target it. You can choose whatever alias you want for the restored key in your keystore (here "foorestored").

Remember : the new password the openssl command asks for will be the password for the key. The new password the keytool command asks for will be the password for the keystore.

Your keystore "restored.jks" now contains an exact copy of your lost key : signing with it will produce identical results as signing with the original key.

Note - If you want to compare two signed jar, compare their content, not the jar themselves : all files must be binary equal (except the name of the key files if you changed it).



Post new comment

The content of this field is kept private and will not be shown publicly.
  • Web page addresses and e-mail addresses turn into links automatically.
  • E-Mail addresses are hidden with reCAPTCHA Mailhide.
  • Allowed HTML tags: <a> <em> <strong> <cite> <code> <ul> <ol> <li> <dl> <dt> <dd>
  • You can enable syntax highlighting of source code with the following tags: <code>, <blockcode>, <drupal5>, <drupal6>, <java>, <javascript>, <php>, <python>. The supported tag styles are: <foo>, [foo].
  • Twitter-style #hashtags are linked to search.twitter.com.

More information about formatting options

By submitting this form, you accept the Mollom privacy policy.