Load and use Android code signing certificate

This is a step-by-step guide on how to load and use an android code signing key and certificate.

Prerequisites

  • a YubiKey with the PIV application

  • the yubico-piv-tool software, available here or on GitHub or

    brew install yubico-piv-tool
    
  • jarsigner and keytool from the JDK (OpenJDK 8 used here)

Steps

  1. Import the key and cert, do one of the below:

    1. Import the key and cert (PEM format) in slot 9a:

      yubico-piv-tool -s 9a -a import-key -i key.pem
      yubico-piv-tool -s 9a -a import-certificate -i cert.pem
      
    2. Import the key and cert (PKCS12 format) in slot 9a:

      yubico-piv-tool -s 9a -a import-key -a import-cert -i key.p12 -K PKCS12
      
  2. Create a java pkcs11 configuration file:

    • Find out where YKCS11 has been installed. The following command can help with that:

      find /usr/local/ -name libykcs11.so
      
    • Create the file, using the correct path discovered above for the library setting:

      cat > /tmp/pkcs11_java.cfg
      name = YKCS11
      description = SunPKCS11 via YKCS11
      library = /usr/lib/x86_64-linux-gnu/libykcs11.so
      slotListIndex = 0
      
  3. Check that keytool can see the key:

    keytool -providerClass sun.security.pkcs11.SunPKCS11 -providerArg /tmp/pkcs11_java.cfg \
      -keystore NONE -storetype PKCS11 -list
    Enter keystore password:
    
    Keystore type: PKCS11
    Keystore provider: SunPKCS11-YKCS11
    
    Your keystore contains 1 entry
    
    Certificate for PIV Authentication, PrivateKeyEntry,
    Certificate fingerprint (SHA1): 26:D7:CB:71:6D:42:3C:AB:58:69:E0:9D:F0:16:DF:84:7E:1C:5A:9A
    

    Password here is the PIN of the key (default 123456).

    If the keytool command fails, adding the -debug option might help understand the problem. One common issue is that the slots might be indexed differently (starting from 0, for example), requiring the file created in the step above to be configured in another way.

  4. Sign the apk with jarsigner:

    jarsigner -providerClass sun.security.pkcs11.SunPKCS11 -providerArg /tmp/pkcs11_java.cfg \
      -keystore NONE -storetype PKCS11 app.apk "Certificate for PIV Authentication"
    Enter Passphrase for keystore:
    jar signed.
    
  5. Verify the signature with jarsigner:

    jarsigner -verify app.apk