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.

Reply via email to