2013-12-12 8 views
9

Я хочу создать пару ключей RSA в Keystore Android. Поскольку Android 4.3 должен быть способен генерировать ключи RSA в системе Keystore системы Android.Невозможно извлечь скрытый экспонент Android KeyStore

сгенерировать свой ключ RSA путем (работает отлично)

 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(); 

мой RSA шифрования выглядит (работает также):

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; 
} 

дешифрования:

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; 
} 

В расшифровке функция i получает следующее сообщение об ошибке (когда закодировано privateKey и в 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) 

Я не понимаю. Невозможно создать ключ RSA в Android KeyStore? Может ли кто-нибудь предоставить мне пример создания ключа RSA в Android KeyStore и дешифрования с помощью закрытого ключа.

Большое спасибо заранее!

ответ

14

Согласно the code, я думаю, что поставщик OpenSSL предотвращает экспорт частного экспонента, когда ключ был сгенерирован в устройство.

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

    ensureReadParams(); 
    return privateExponent; 
} 

Таким образом, вы, вероятно, нужно указать, что вы хотите использовать один и тот же поставщик криптографических при получении шифра экземпляра. Этот провайдер supports these RSA ciphers:

  • RSA/ЕЦБ/NoPadding
  • RSA/ЕЦБ/PKCS1Padding

Вы должны создать экземпляр шифра таким образом:

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

'BigInteodeger' должен «BigInteger», но я не могу его отредактировать, так как изменение составляет менее 6 символов. :( –

+1

Спасибо, Марк. Я обновил сообщение. – Jcs

+2

Есть ли способ сделать эту работу с помощью SpongyCastle для обратной совместимости? – zubietaroberto