Using Android keystore in the Javascript app with jsrsasign
Scenario: you have an Android keystore (generated using keytool command, for instance), and you need to use it in an Javascript app. In my case, I had a signature generated using command line tools like openssl, and I wanted to verify it in the browser.
Solution: extract public and private keys. Use private key to sign some value in the command line, and public key to verify the signature - in the browser.
The following steps would give an overview of how it can work:
Step 0: Generate Android keystore
All the examples belowe assume the password "keystore" is used whenever prompted.
keytool -v \ -genkey \ -keystore kamituel.keystore \ -alias kamituel \ -keyalg RSA \ -keysize 2048 \ -validity 10000
Step 1: Convert JKS to PKCS12 structure
keytool \ -importkeystore \ -srckeystore kamituel.keystore \ -destkeystore kamituel.p12 \ -deststoretype PKCS12 \ -srcalias kamituel \ -deststorepass keystore \ -destkeypass keystore
Step 2: Export private key from the PKCS12 file
openssl pkcs12 \ -in kamituel.p12 \ -nodes \ -nocerts \ -out kamituel-private-key.pem
Step 3: Export certificate from the PKCS12 file
openssl pkcs12 \ -in kamituel.p12 \ -nokeys \ -out kamituel.pem
Step 4: Export public key from the PKCS12 file
openssl x509 \ -pubkey \ -noout \ -in kamituel.pem > kamituel-public.pem
Step 5: Sign the desired value
echo -n "some value" > value
openssl dgst \ -sha1 \ -sign kamituel-private-key.pem < value | xxd -p -c 256
Note: There is another command which could be used to sign a value (openssl rsautl -sign). It generates an invalid output (it's a raw signature, without a digest algorithm info in it), though, and will not work. See this excellent Stack Overflow answer for a great explanation.
Step 6: Verify it in the browser
vthis excear value = 'some value' // signed value , signature = '......' // ouput of command in step 5 , pubkey = '.......' // kamituel-public.pem , sig = new KJUR.crypto.Signature({"alg": "SHA1withRSA", "prov": "cryptojs/jsrsa"}) , key = KEYUTIL.getKey(pubkey) ; sig.initVerifyByPublicKey(key); sig.updateString(value); // Should be true. var isValid = sig.verify(signature);
Please refer to the Gist for the full example.