Hey Alex, When I input PrivateKey object from entry.getPrivateKey() to s.initSign(), the following exception occurs:
java.security.InvalidKeyException: Supplied key (android.security.keystore.AndroidKeyStoreRSAPrivateKey) is not a RSAPrivateKey instance. This is the new code: Signature s = Signature.getInstance(algorithmText); KeyStore.Entry entry = ks.getEntry(keyAlias, null); PrivateKey privateKey = ((KeyStore.PrivateKeyEntry) entry).getPrivateKey(); s.initSign(privateKey); // <--- excepts here For the time being, algorithmText is set to "SHA512withRSA". Cheers, Jake On Thursday, February 18, 2016 at 6:06:15 AM UTC+11, Alex Klyubin wrote: > > Short answer: Drop the cast to RSAPrivateKey. Use entry.getPrivateKey() > instead. > > Longer answer: RSAPrivateKey interface is for private keys which expose > their key material in a structured way (e.g., expose their private > exponent). Android Keystore keys by definition do not expose their key > material. Thus, Android Keystore private keys are not instances of > RSAPrivateKey. They are instance of PrivateKey and RSAKey (this one lets > you obtain the modulus). Signature.initSign happily takes a PrivateKey > instance. Thus, drop the cast to RSAPrivateKey and it'll work just fine. > > On Wednesday, February 17, 2016 at 6:43:04 AM UTC-8, Jacob Taylor wrote: >> >> Hey devs, >> >> I'm working on a proof of concept app for generating an RSA keypair in an >> app, generating a X509 CSR based on the new keypair, then exporting it to >> be signed by some CA. >> As a part o f the CSR generation process the whole CSR must be signed by >> the key itself. >> >> I've been following along with the Keystore page on the documentation >> site ( >> http://developer.android.com/training/articles/keystore.html#SigningAndVerifyingData) >> >> and reached a snag. >> The generation of the CSR is handled by spongycastle, which in turn uses >> a custom build class (called keystoreContentSigner) to sign the completed >> CSR with the keys stored in the keystore. >> According to the above referenced documentation, the call to >> ks.getEntry(keyAlias, null) should return an object typecasted to the >> Keystore.Entry class, which you then cast into a PrivateKeyEntry which you >> then call against using its .getPrivateKey method. >> >> On my test phone (Nexus 6P) this flow doesn't work. It excepts during the >> call to initSign, and reports the type of the object return from >> ks.getEntry as android.security.keystore.AndroidKeyStoreRSAPrivateKey, >> which isn't referenced anywhere I can find. >> >> This type can't be casted to anything usable in the current format, is >> there some new way to perform cryptographic operations in Marshmallow, or >> is there something I'm missing? >> >> KeystoreContentSigner class: >> >> package au.com.taylornetworks.tapid; >> >> >> import org.spongycastle.asn1.x509.AlgorithmIdentifier; >> import org.spongycastle.operator.ContentSigner; >> import org.spongycastle.operator.DefaultSignatureAlgorithmIdentifierFinder; >> >> import java.io.ByteArrayOutputStream; >> import java.io.OutputStream; >> import java.security.KeyStore; >> import java.security.Signature; >> import java.security.interfaces.RSAPrivateKey; >> >> >> public class keystoreContentSigner implements ContentSigner{ >> >> private AlgorithmIdentifier algorithmIdentifier; >> private String algorithmText; >> private ByteArrayOutputStream dataStream; >> private String keyAlias; >> >> public keystoreContentSigner(String keyAlias) >> { >> algorithmText = "SHA512withRSA"; >> algorithmIdentifier = new >> DefaultSignatureAlgorithmIdentifierFinder().find(algorithmText); >> dataStream = new ByteArrayOutputStream(); >> this.keyAlias = keyAlias; >> } >> >> public void setAlgorithm(String algorithmText) >> { >> this.algorithmText = algorithmText; >> algorithmIdentifier = new >> DefaultSignatureAlgorithmIdentifierFinder().find(algorithmText); >> } >> >> @Override >> public OutputStream getOutputStream() >> { >> return dataStream; >> } >> >> @Override >> public AlgorithmIdentifier getAlgorithmIdentifier() >> { >> return algorithmIdentifier; >> } >> >> public byte[] getSignature() >> { >> byte[] data; >> byte[] signature = null; >> KeyStore ks; >> >> try { >> ks = KeyStore.getInstance("AndroidKeyStore"); >> ks.load(null); >> >> data = dataStream.toByteArray(); >> dataStream.flush(); >> >> Signature s = Signature.getInstance(algorithmText); >> KeyStore.Entry entry = ks.getEntry(keyAlias, null); >> >> s.initSign((RSAPrivateKey) entry); >> s.update(data); >> signature = s.sign(); >> } catch (Exception e) { >> e.printStackTrace(); >> } >> >> return signature; >> } >> >> } >> >> >> PkiManager class: >> Enter >> >> package au.com.taylornetworks.tapid; >> >> import android.security.keystore.*; >> >> import java.io.IOException; >> import java.security.*; >> import java.security.cert.CertificateException; >> import org.spongycastle.asn1.misc.MiscObjectIdentifiers; >> import org.spongycastle.asn1.misc.NetscapeCertType; >> import org.spongycastle.asn1.x500.X500Name; >> import org.spongycastle.asn1.x509.BasicConstraints; >> import org.spongycastle.asn1.x509.ExtendedKeyUsage; >> import org.spongycastle.asn1.x509.Extension; >> import org.spongycastle.asn1.x509.ExtensionsGenerator; >> >> ... > > -- You received this message because you are subscribed to the Google Groups "Android Developers" group. To unsubscribe from this group and stop receiving emails from it, send an email to [email protected]. To post to this group, send email to [email protected]. Visit this group at https://groups.google.com/group/android-developers. To view this discussion on the web visit https://groups.google.com/d/msgid/android-developers/dc23c181-5ce3-4ce5-a5bc-b8b35738c0a2%40googlegroups.com. For more options, visit https://groups.google.com/d/optout.

