2015-12-14 37 views
6

Android uygulamasında Strings'i şifrelemeye ve şifresini çözmeye çalışıyorum ancak InvalidKeyException hatası alıyorum. Android Şifre Çözme Hatası

private String encryptString(String value){ 
    byte[] encodedBytes = null; 
    try { 
     Cipher cipher = Cipher.getInstance("RSA/ECB/PKCS1Padding", "AndroidOpenSSL"); 
     cipher.init(Cipher.ENCRYPT_MODE, pubKey); 
     encodedBytes = cipher.doFinal(value.getBytes()); 
    } catch (Exception e) { 
     e.printStackTrace(); 
    } 

    return Base64.encodeToString(encodedBytes, Base64.DEFAULT); 
} 

// azalmak Yöntem

private String decryptString(String value){ 
    byte[] decodedBytes = null; 
    try { 
     Cipher c = Cipher.getInstance("RSA/ECB/PKCS1Padding", "AndroidOpenSSL"); 
     c.init(Cipher.DECRYPT_MODE, privKey); 
     decodedBytes = c.doFinal(Base64.decode(value, Base64.DEFAULT)); 
    } catch (Exception e) { 
     e.printStackTrace(); 
     Log.e("Error", "Error = " + e); 
     return "SECURE_FAILURE"; 
    } 

    return new String(decodedBytes); 
} 

// Testi

public void generateKeys() { 
    Calendar cal = Calendar.getInstance(); 
    Date now = cal.getTime(); 
    cal.add(Calendar.YEAR, 25); 
    Date end = cal.getTime(); 

    KeyPairGenerator kpg = null; 
    try { 
     kpg = KeyPairGenerator.getInstance("RSA", "AndroidKeyStore"); 
    } catch (NoSuchAlgorithmException e) { 
     e.printStackTrace(); 
    } catch (NoSuchProviderException e) { 
     e.printStackTrace(); 
    } 
    try { 
     kpg.initialize(new KeyPairGeneratorSpec.Builder(context) 
       .setAlias(KEY_ALIAS) 
       .setStartDate(now) 
       .setEndDate(end) 
       .setSerialNumber(BigInteger.valueOf(1)) 
       .setSubject(new X500Principal("CN=" + KEY_ALIAS)) 
       .build()); 
    } catch (InvalidAlgorithmParameterException e) { 
     e.printStackTrace(); 
    } 

    KeyPair kp = kpg.generateKeyPair(); 

    KeyStore ks = null; 
    try { 
     ks = KeyStore.getInstance("AndroidKeyStore"); 
     ks.load(null); 
     Enumeration<String> aliases = ks.aliases(); 
    } catch (KeyStoreException e) { 
     e.printStackTrace(); 
    } catch (CertificateException e) { 
     e.printStackTrace(); 
    } catch (NoSuchAlgorithmException e) { 
     e.printStackTrace(); 
    } catch (IOException e) { 
     e.printStackTrace(); 
    } 

    KeyStore.Entry entry = null; 
    try { 
     entry = ks.getEntry(KEY_ALIAS, null); 
    } catch (NoSuchAlgorithmException e) { 
     e.printStackTrace(); 
    } catch (UnrecoverableEntryException e) { 
     e.printStackTrace(); 
    } catch (KeyStoreException e) { 
     e.printStackTrace(); 
    } 
    if (!(entry instanceof KeyStore.PrivateKeyEntry)) { 
     Log.e(LOG_TAG, "Not an instance of PrivateKeyEntry."); 
    } 
    else{ 
     privKey = ((KeyStore.PrivateKeyEntry) entry).getPrivateKey(); 
     pubKey = ((KeyStore.PrivateKeyEntry) entry).getCertificate().getPublicKey(); 
    } 

} 

// Şifrele Yöntem

// üret Tuşlar yöntemi: İşte

benim kodudur Kod

generateKeys(); 
    String encrypted = encryptString("Hello World"); 
    Log.e("Encrypt", "encrypted = " + encrypted); 
    String decrypted = decryptString(encrypted); 
    Log.e("Decrypt", "decrypted = " + decrypted); 

şöyle bir şey çıktı olarak şifreleme Tamam çalışır gibi görünüyor:

java.security.InvalidKeyException: Need RSA private or public key

elimden:

encrypted = SbA2iWWKQbDL7NTA9xvtjD/viYDdpx9fLRYTSZ8UQzdBy3QLqzkswBY21ErH7FPza3vZys4E4PZw uxaGkRz0aC0FLqsYlbpcJernGm5+D5lRcBOaZmgkNY9pMf0YP75cBbcJdcmb1rDaH40nCRDnEoXv rGESJRqT6p0NMzlZqdd9KO3tqfExwgservAWxPNtRDBbMgE4I/09418jM5Ock5eayfOuv/STwEy6 Ecd56UjFH63h+gP6ed2aMDhBVeExMxvdloY+VnsAxS5Dkoc2GdaljtjRuPK48HQASoJK8EwAMNpz

Ama aşağıdaki hatayı alıyorum şifrelerini çalıştığınızda Bu istisnayı neden alıyorum? Biri yardım edebilir mi?

+0

Herhangi bir şans? Android Marshmallow'da aynı istisnayı alıyorum. – Luis

+0

Farklı bir sağlayıcı kullanarak onu tamir ettim ... cevabımı aşağıya bakın. – Luis

+1

Asimetrik şifreleme (RSA) genel/özel anahtarlarına gereksinim duyulmasının bir nedeni yoksa, yalnızca AES gibi simetrik şifreleme kullanın. Simetrik şifreleme, veri şifreleme için genel seçenektir. Asimetrik şifreleme veri uzunluğu anahtar büyüklüğüyle sınırlıdır ve gerçekten yavaştır ve daha güvenli değildir. – zaph

cevap

9

bu gibi farklı bir sağlayıcı kullanmayı deneyin:

Cipher.getInstance("RSA/ECB/PKCS1Padding", "AndroidKeyStoreBCWorkaround"); 
+2

Bana göre, bazı açıklamalar harika olurdu. – Waboodoo

8

bu benim için çalıştı:

private Cipher getCipher() { 
    try { 
     if (Build.VERSION.SDK_INT < Build.VERSION_CODES.M) { // below android m 
      return Cipher.getInstance("RSA/ECB/PKCS1Padding", "AndroidOpenSSL"); // error in android 6: InvalidKeyException: Need RSA private or public key 
     } 
     else { // android m and above 
      return Cipher.getInstance("RSA/ECB/PKCS1Padding", "AndroidKeyStoreBCWorkaround"); // error in android 5: NoSuchProviderException: Provider not available: AndroidKeyStoreBCWorkaround 
     } 
    } catch(Exception exception) { 
     throw new RuntimeException("getCipher: Failed to get an instance of Cipher", exception); 
    } 
} 
2

sağlayıcı benim için çalıştı Çıkarma: Java docs itibaren

Cipher.getInstance("RSA/ECB/PKCS1Padding") 

: " Bu yöntem, en çok tercih edilen sağlayıcıdan başlayarak kayıtlı güvenlik sağlayıcılarının listesini değiştirir. Belirtilen algoritmayı destekleyen ilk Sağlayıcıdan CipherSpi uygulamasını kapsülleyen pher nesnesi döndürülür. "