Hi Alex,

How silly of me, I thought I already commented out the BouncyCastle JCA 
provider. That's done now, and yes, this is running on Android 6 and I'm 
using the single arg getInstance for Signature.

Now I get another error, stack trace below:

java.security.InvalidKeyException: Keystore operation failed
                                                                            
            at android.security.KeyStore.getInvalidKeyException(KeyStore.
java:692)
                                                                            
            at android.security.KeyStore.getInvalidKeyException(KeyStore.
java:712)
                                                                            
            at android.security.keystore.KeyStoreCryptoOperationUtils.
getInvalidKeyExceptionForInit(KeyStoreCryptoOperationUtils.java:54)
                                                                            
            at android.security.keystore.AndroidKeyStoreSignatureSpiBase.
ensureKeystoreOperationInitialized(AndroidKeyStoreSignatureSpiBase.java:219)
                                                                            
            at android.security.keystore.AndroidKeyStoreSignatureSpiBase.
engineInitSign(AndroidKeyStoreSignatureSpiBase.java:99)
                                                                            
            at android.security.keystore.AndroidKeyStoreSignatureSpiBase.
engineInitSign(AndroidKeyStoreSignatureSpiBase.java:77)
                                                                            
            at java.security.Signature$SignatureImpl.engineInitSign(
Signature.java:706)
                                                                            
            at java.security.Signature.initSign(Signature.java:357)
                                                                            
            at au.com.taylornetworks.tapid.keystoreContentSigner.
getSignature(keystoreContentSigner.java:69)
                                                                            
            at org.spongycastle.pkcs.PKCS10CertificationRequestBuilder.build
(PKCS10CertificationRequestBuilder.java:149)
                                                                            
            at au.com.taylornetworks.tapid.pkiManager.generateCSR(pkiManager
.java:78)
                                                                            
            at au.com.taylornetworks.tapid.MainActivity.createAndShowCSR(
MainActivity.java:42)
                                                                            
            at java.lang.reflect.Method.invoke(Native Method)
                                                                            
            at android.support.v7.app.
AppCompatViewInflater$DeclaredOnClickListener.onClick(AppCompatViewInflater.
java:270)
                                                                            
            at android.view.View.performClick(View.java:5204)
                                                                            
            at android.view.View$PerformClick.run(View.java:21153)
                                                                            
            at android.os.Handler.handleCallback(Handler.java:739)
                                                                            
            at android.os.Handler.dispatchMessage(Handler.java:95)
                                                                            
            at android.os.Looper.loop(Looper.java:148)
                                                                            
            at android.app.ActivityThread.main(ActivityThread.java:5417)
                                                                            
            at java.lang.reflect.Method.invoke(Native Method)
                                                                            
            at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(
ZygoteInit.java:726)
                                                                            
            at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:616)
                                                                            
         Caused by: android.security.KeyStoreException: Incompatible 
padding mode
                                                                            
            at android.security.KeyStore.getKeyStoreException(KeyStore.java:
632)
                                                                            
            at android.security.KeyStore.getInvalidKeyException(KeyStore.
java:712) 
                                                                            
            at android.security.keystore.KeyStoreCryptoOperationUtils.
getInvalidKeyExceptionForInit(KeyStoreCryptoOperationUtils.java:54) 
                                                                            
            at android.security.keystore.AndroidKeyStoreSignatureSpiBase.
ensureKeystoreOperationInitialized(AndroidKeyStoreSignatureSpiBase.java:219) 
                                                                            
            at android.security.keystore.AndroidKeyStoreSignatureSpiBase.
engineInitSign(AndroidKeyStoreSignatureSpiBase.java:99) 
                                                                            
            at android.security.keystore.AndroidKeyStoreSignatureSpiBase.
engineInitSign(AndroidKeyStoreSignatureSpiBase.java:77) 
                                                                            
            at java.security.Signature$SignatureImpl.engineInitSign(
Signature.java:706) 
                                                                            
            at java.security.Signature.initSign(Signature.java:357) 
                                                                            
            at au.com.taylornetworks.tapid.keystoreContentSigner.
getSignature(keystoreContentSigner.java:69) 
                                                                            
            at org.spongycastle.pkcs.PKCS10CertificationRequestBuilder.build
(PKCS10CertificationRequestBuilder.java:149) 
                                                                            
            at au.com.taylornetworks.tapid.pkiManager.generateCSR(pkiManager
.java:78) 
                                                                            
            at au.com.taylornetworks.tapid.MainActivity.createAndShowCSR(
MainActivity.java:42) 
                                                                            
            at java.lang.reflect.Method.invoke(Native Method) 
                                                                            
            at android.support.v7.app.
AppCompatViewInflater$DeclaredOnClickListener.onClick(AppCompatViewInflater.
java:270) 
                                                                            
            at android.view.View.performClick(View.java:5204) 
                                                                            
            at android.view.View$PerformClick.run(View.java:21153) 
                                                                            
            at android.os.Handler.handleCallback(Handler.java:739) 
                                                                            
            at android.os.Handler.dispatchMessage(Handler.java:95) 
                                                                            
            at android.os.Looper.loop(Looper.java:148) 
                                                                            
            at android.app.ActivityThread.main(ActivityThread.java:5417) 
                                                                            
            at java.lang.reflect.Method.invoke(Native Method) 
                                                                            
            at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(
ZygoteInit.java:726) 
                                                                            
            at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:616) 



On Thursday, February 18, 2016 at 1:06:27 PM UTC+11, Alex Klyubin wrote:
>
> P. S. Typo: bcProviderIndex = i; should be bcProviderIndex = i + 1; 
> Security.insertProviderAt uses a 1-based indexing scheme...
>
> Alex
>
> On Wednesday, February 17, 2016 at 6:02:04 PM UTC-8, Alex Klyubin wrote:
>>
>> Oh, I didn't notice the PkiManager class in OP. It does install Bouncy 
>> Castle as the highest-priority JCA Provider. Unfortunately, Bouncy Castle 
>> JCA Provider has a bug (http://www.bouncycastle.org/jira/browse/BJA-543 
>> <https://www.google.com/url?q=http://www.bouncycastle.org/jira/browse/BJA-543&sa=D&usg=AFQjCNEErNOODYZHHZomGgR1y7NLq2yegw>)
>>  
>> where is advertises to JCA that it can handle any keys, even those that it 
>> actually can't handle, such as Android Keystore keys which don't expose 
>> private/secret key material. Here are some options to work around this 
>> issue:
>> 1. Don't install the Bouncy Castle JCA Provider if you don't need to. For 
>> example, you don't need it for crypto operations involving Android Keystore 
>> keys.
>> 2. If you must install the Bouncy Castle JCA Provider, install it below 
>> Android Keystore JCA provider. The best way to achieve that is to find the 
>> index at which the platform-bundled Bouncy Castle provider is installed, 
>> and then invoke Security.insertProviderAt with that same index and your 
>> Bouncy Castle Provider. This will install your Bouncy Castle provider just 
>> above the preinstalled Bouncy Castle provider which is itself installed at 
>> the correct spot for Android Keystore stuff to work. For example:
>>
>>   Provider[] providers = Security.getProviders();
>>   int bcProviderIndex = -1;
>>   for (int i = 0; i < providers.length; i++) {
>>     Provider provider = providers[i];
>>     if ("BC".equals(provider.getName())) {
>>       bcProviderIndex = i;
>>       break;
>>     }
>>   }
>>   Security.insertProviderAt(new BouncyCastleProvider(), 
>> bcProviderPosition);
>>
>> Alex
>>
>> On Wednesday, February 17, 2016 at 5:41:40 PM UTC-8, Alex Klyubin wrote:
>>>
>>> * 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/67ade4d5-9572-4206-92ba-4e2f63ac8472%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Reply via email to