2013-12-12 17 views
9

Voglio generare una coppia di chiavi RSA nel Keystore Android. Poiché Android 4.3 dovrebbe essere possibile generare chiavi RSA nel sistema Android Keystore.Esponente privato KeyStore Android non estraibile

ho generare la chiave RSA da (funziona bene)

 Calendar notBefore = Calendar.getInstance(); 
     Calendar notAfter = Calendar.getInstance(); 
     notAfter.add(1, Calendar.YEAR); 
     KeyPairGeneratorSpec spec = new KeyPairGeneratorSpec.Builder(ctx) 
       .setAlias("key") 
       .setSubject(
         new X500Principal(String.format("CN=%s, OU=%s", 
           "key", ctx.getPackageName()))) 
       .setSerialNumber(BigInteger.ONE) 
       .setStartDate(notBefore.getTime()) 
       .setEndDate(notAfter.getTime()).build(); 
      KeyPairGenerator kpg; 
      kpg = KeyPairGenerator.getInstance("RSA", "AndroidKeyStore"); 
      kpg.initialize(spec); 
      KeyPair kp = kpg.genKeyPair(); 
      publicKey = kp.getPublic(); 
      privateKey = kp.getPrivate(); 

mia crittografia RSA assomiglia (funziona anche):

public static byte[] RSAEncrypt(final byte[] plain) 
     throws NoSuchAlgorithmException, NoSuchPaddingException, 
     InvalidKeyException, IllegalBlockSizeException, BadPaddingException { 

    Cipher cipher = Cipher.getInstance("RSA"); 
    System.out.println("RSA Encryption key: " + publicKey.getAlgorithm()); 
    System.out.println("RSA Encryption key: " + publicKey.getEncoded()); 

    cipher.init(Cipher.ENCRYPT_MODE, publicKey); 
    byte[] encryptedBytes = cipher.doFinal(plain); 
    return encryptedBytes; 
} 

decrittazione:

public static byte[] RSADecrypt(final byte[] encryptedBytes) 
     throws NoSuchAlgorithmException, NoSuchPaddingException, 
     InvalidKeyException, IllegalBlockSizeException, BadPaddingException { 

    Cipher cipher1 = Cipher.getInstance("RSA"); 

    System.out.println("RSA Encryption key: " + privateKey.getAlgorithm()); 
    System.out.println("RSA Encryption key: " + privateKey.getEncoded()); 

    cipher1.init(Cipher.DECRYPT_MODE, privateKey); 
    byte[] decryptedBytes = cipher1.doFinal(encryptedBytes); 
    return decryptedBytes; 
} 

Nel decrittazione funzione ottengo il seguente messaggio di errore (quando il privateKey è codificato, e in cipher1.init()):

12-12 21:49:40.338: E/AndroidRuntime(20423): FATAL EXCEPTION: main 
12-12 21:49:40.338: E/AndroidRuntime(20423): java.lang.UnsupportedOperationException: private exponent cannot be extracted 
12-12 21:49:40.338: E/AndroidRuntime(20423): at org.apache.harmony.xnet.provider.jsse.OpenSSLRSAPrivateKey.getPrivateExponent(OpenSSLRSAPrivateKey.java:143) 

Non capisco. Non è possibile generare una chiave RSA nel KeyStore di Android? Qualcuno può fornirmi un esempio di generazione di una chiave RSA nel KeyStore di Android e decifrare con la chiave privata.

Molte grazie in anticipo!

risposta

14

Secondo the code, penso che il provider OpenSSL impedisca l'esportazione dell'esponente privato quando la chiave è stata generata nel dispositivo.

@Override 
public final BigInteger getPrivateExponent() { 
    if (key.isEngineBased()) { 
     throw new UnsupportedOperationException("private exponent cannot be extracted"); 
    } 

    ensureReadParams(); 
    return privateExponent; 
} 

Così, probabilmente è necessario specificare che si desidera utilizzare lo stesso provider di crittografia durante il recupero l'istanza di cifratura. Questo provider supports these RSA ciphers:

  • RSA/BCE/NoPadding
  • RSA/BCE/PKCS1Padding

È necessario creare un'istanza della cifra in questo modo:

Cipher cipher1 = Cipher.getInstance("RSA/ECB/PKCS1Padding", "AndroidOpenSSL"); 
+1

'BigInteodeger' dovrebbe be 'BigInteger', ma non posso modificarlo poiché la modifica è inferiore a 6 caratteri. :( –

+1

Grazie Mark. Ho aggiornato il post. – Jcs

+2

C'è un modo per far funzionare questo lavoro usando SpongyCastle per la compatibilità con le versioni precedenti? – zubietaroberto