Ideally the OpenPGP card could be used for both jarsigner and OpenPGP signing. That means a card that can do both PKCS#11 and GnuPG. Otherwise there would have to be a PKCS#11 card for Java and an OpenPGP card for GnuPG. OpenSC now seems to provide PKCS#11 access to the OpenPGP card. Via OpenSC, keytool
can see the key/certificate on the OpenPGP card via opensc 0.13, but jarsigner
does not cooperate.
opensc
and OpenPGP
support:openssl pkcs7 -inform DER -in $SOMECERTFILE -print_certs -noout -text
openssl pkcs7 -inform DER -in $SOMECERTFILE -print_certs -out ExtractedX509Cert.PEM
openssl x509 -inform DER -in ExtractedX509Cert.PEM -noout -fingerprint
Here is the https://androidobservatory.org import code for displaying cert info. It should run in isolation of the Observatory code, but it's largely untested & undocumented.
The default way to generate APK signing keys is with Java's keytool
. It is widely used and not too hard to use. We recommend using at least OpenJDK 7, since it includes much improved versions of keytool
and jarsigner
. If you are willing to get your hands dirty, it is probably better to generate your key with openssl
then import it with keytool
(see below).
keytool -genkey -v -keystore test.keystore -alias testkey -keyalg RSA -keysize 4096 -sigalg SHA1withRSA -dname "cn=Test,ou=Test,c=CA" -validity 10000
-keypass
or -storepass
)-keysize 2048
is the minimum, but -keysize 4096
is better-keysize 8192
is overkill and might not work on older Android versionsSHA256withRSA
and other better hashes supported on Android 4.3 and above only! 1SHA1withDSA
should work, but we haven't tested itOn Debian/Ubuntu/Mint/etc., you can keep OpenJDK 6 as the default JRE and JDK for compatibility while using keytool
and maybe jarsigner
from OpenJDK 7. Use sudo update-alternatives --config FOO
, where FOO
is: java javac jar jarsigner keytool
An alternate way to generate the key is to use openssl
. When it comes to generating, openssl
has a better security track record than Java. Also, it is a less common combination so that exploits that might work with Java/keytool
/jarsigner
might not work with a key generated with openssl
then imported using keytool
. The downside is that there might also be weaknesses exposed by this trick, but that seems less likely than Java/keytool
having problems. Additionally, we recommend generating your key using /dev/random
because this is a long-lived key and therefore more sensitive. This does make generating the key take a lot longer.
openssl genrsa -out secretkey.pem -aes128 -rand /dev/random 4096 openssl req -new -key secretkey.pem -out request.pem openssl x509 -req -days 9999 -in request.pem -signkey secretkey.pem -out certificate.pem openssl pkcs12 -export -out certificate.p12 -in certificate.pem -inkey secretkey.pem keytool -importkeystore \ -srckeystore certificate.p12 -srcstoretype PKCS12 \ -destkeystore certificate.jkr -deststoretype JKS
This should be possible with using GnuPG's gpgsm
instead of openssl
, but that requires GnuPG 2.1, which is not easily installable, and still in beta. So we'll save that HOWTO for later. You can follow the progress of all this work in our git repo: https://github.com/guardianproject/smartcard-apk-signing