* Please provide the full stack trace (at least from Signature.initSign down into the framework). * What version of Android is this (e.g., 6.0)? * Are you installing any additional JCA providers (e.g., Security.insertProviderAt or Security.addProvider)? * Please confirm that you're not specifying a provider when invoking Signature.getInstance. (i.e., that you're using the single-arg getInstance, not the one that takes an additional String or Provider argument).
Cheers, Alex On Wednesday, February 17, 2016 at 5:25:34 PM UTC-8, Jacob Taylor wrote: > > 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/a5e8d2e5-d72d-4fd5-8e06-49a4c0b5e0ec%40googlegroups.com. For more options, visit https://groups.google.com/d/optout.

