2015-12-14 11 views
6

मैं अपने एंड्रॉइड एप्लिकेशन में स्ट्रिंग्स को एन्क्रिप्ट और डिक्रिप्ट करने की कोशिश कर रहा हूं लेकिन मुझे एक अवैधकिएक्स अपवाद त्रुटि मिल रही है।एंड्रॉइड डिक्रिप्शन त्रुटि

// उत्पन्न कुंजी विधि

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

// डिक्रिप्ट विधि

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

// टेस्ट

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

} 

// एन्क्रिप्ट विधि

:

यहाँ मेरी कोड है कोड

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

ऐसा लगता है कि एन्क्रिप्शन की तरह ठीक काम करता है के रूप में यह कुछ इस तरह बाहर प्रिंट:

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

मैं कर सकते हैं:

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

लेकिन जब मैं मैं निम्नलिखित त्रुटि मिलती है डिक्रिप्ट करने के लिए कोशिश मुझे नहीं लगता कि मुझे यह अपवाद क्यों मिल रहा है? क्या कोई मदद कर सकता है?

+0

कोई भाग्य? मुझे एंड्रॉइड मार्शमलो में एक ही अपवाद मिल रहा है। – Luis

+0

मैंने इसे एक अलग प्रदाता का उपयोग करके तय किया ... नीचे मेरा जवाब देखें। – Luis

+1

जब तक असममित एन्क्रिप्शन (आरएसए) सार्वजनिक/निजी कुंजी की आवश्यकता के लिए कुछ कारण नहीं है, तो एईएस जैसे सममित एन्क्रिप्शन का उपयोग करें। डेटा एन्क्रिप्शन के लिए सममित एन्क्रिप्शन सामान्य विकल्प है। असममित एन्क्रिप्शन डेटा लंबाई कुंजी आकार तक ही सीमित है और वास्तव में धीमी है और अब और सुरक्षित नहीं है। – zaph

उत्तर

9

एक अलग प्रदाता का उपयोग कर, इस तरह का प्रयास करें:

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

मेरे लिए काम करता है, हालांकि कुछ स्पष्टीकरण बहुत अच्छा होगा। – Waboodoo

8

यह मेरे लिए काम किया:

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

निकाला जा रहा है प्रदाता मेरे लिए काम किया:

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

Java docs से: " यह विधि सबसे पसंदीदा प्रदाता से शुरू होने वाले पंजीकृत सुरक्षा प्रदाताओं की सूची को पार करती है। एक नया सीआई निर्दिष्ट एल्गोरिदम का समर्थन करने वाले पहले प्रदाता से CipherSpi कार्यान्वयन encapsulating फेयर ऑब्जेक्ट वापस आ गया है। "

संबंधित मुद्दे