2015-11-17 44 views
23

我試圖加密和使用密鑰庫解密應用程序的用戶名,在Android M和舊版本中使用KeyStore加密和解密用戶名?

使用KeyPairGeneratorSpec建立在舊版本像18到22的關鍵,

KeyPairGeneratorSpec作爲一直Android中的23版depricated M, 但Android M支持KeyGenParameterSpec。

這個KeyGenParameterSpec支持向後可比性嗎?或者我該怎麼做?

我嘗試了一些這樣的事情,有沒有更好的解決方案。 這工作正常,現在關閉!

在加密和解密Ciper.getInstance的時候,我需要做到這一點。 是否有任何單個參數「RSA/ECB/OAEPWithSHA-256AndMGF1Padding」或「RSA/ECB/PKCS1Padding」我可以通過版本

if(android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.M){ 
      c = Cipher.getInstance("RSA/ECB/OAEPWithSHA-256AndMGF1Padding"); 
     }else{ 
      c = Cipher.getInstance("RSA/ECB/PKCS1Padding"); 
     } 

下面的代碼工作正常,現在關閉,讓我知道如何改善這一點。

密鑰生成器:

genkey(){ 
KeyPairGenerator generator = KeyPairGenerator .getInstance(KeyProperties.KEY_ALGORITHM_RSA, "AndroidKeyStore"); 
      if(android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.M){ 
       TCLog.e(TAG,"Current version is 23(MashMello)"); 
       //Api level 23 

       KeyGenParameterSpec spec = new KeyGenParameterSpec.Builder(
          keyName, 
          KeyProperties.PURPOSE_DECRYPT | KeyProperties.PURPOSE_ENCRYPT) 
          .setDigests(KeyProperties.DIGEST_SHA256, KeyProperties.DIGEST_SHA512) 
          .setEncryptionPaddings(KeyProperties.ENCRYPTION_PADDING_RSA_OAEP) 
          .build(); 
       generator.initialize(spec); 
      }else{ 
       TCLog.e(TAG,"Current version is < 23(MashMello)"); 
       //api level 17+ 4.4.3 
       KeyPairGeneratorSpec spec = new KeyPairGeneratorSpec.Builder(getActivity()) 
         .setAlias(keyName) 
         .setSubject(new X500Principal("CN=Sample Name, O=Android Authority")) 
         .setSerialNumber(BigInteger.ONE) 
         .setStartDate(start.getTime()) 
         .setEndDate(end.getTime()) 
         .build(); 
       generator.initialize(spec); 
      } 
      KeyPair keyPair = generator.generateKeyPair(); 
} 

加密代碼:

doEncription(){ 
try { 
     KeyStore.PrivateKeyEntry privateKeyEntry = (KeyStore.PrivateKeyEntry) ks.getEntry(keyName, null); 
     PublicKey publicKey = (PublicKey) privateKeyEntry.getCertificate().getPublicKey(); 
     Cipher c; 
     if(android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.M){ 
      c = Cipher.getInstance("RSA/ECB/OAEPWithSHA-256AndMGF1Padding"); 
     }else{ 
      c = Cipher.getInstance("RSA/ECB/PKCS1Padding"); 
     } 

     c.init(Cipher.ENCRYPT_MODE, publicKey); 
     encodedUser = c.doFinal(userName.getBytes()); 
     encodedPassword = c.doFinal(userPassword.getBytes()); 

     userName = Base64.encodeToString(encodedUser, Base64.DEFAULT); 
     userPassword = Base64.encodeToString(encodedPassword, Base64.DEFAULT); 
     // Log.e("MainActivity","AES Encription Error.!"); 
    } catch (Exception e) { 
     Log.e("MainActivity", "AES Encription Error.!"); 
    } 
} 

解密代碼:

doDecryption(){ 
    try { 
     KeyStore.PrivateKeyEntry privateKeyEntry = (KeyStore.PrivateKeyEntry) ks.getEntry(keyName, null); 
     PrivateKey privateKey = (PrivateKey) privateKeyEntry.getPrivateKey(); 

     Cipher c; 
     if(android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.M){ 
      c = Cipher.getInstance("RSA/ECB/OAEPWithSHA-256AndMGF1Padding"); 
     }else{ 
      c = Cipher.getInstance("RSA/ECB/PKCS1Padding"); 
     } 
     c.init(Cipher.DECRYPT_MODE, privateKey); 
     decodedUser = c.doFinal(encodedUser); 
     decodedPassword = c.doFinal(encodedPassword); 

    } catch (Exception e) { 
     Log.e("MainActivity", "AES Decryption Error.!"); 
    } 

} 
+0

@ nikolay-elenkov請你快看看這段代碼?加密敏感數據安全嗎? – deviant

+1

你能告訴我一個鏈接哪裏可以找到完整的代碼或你在哪裏得到代碼? –

回答

3

的暗號轉變取決於什麼參數你給KeyGenParameterSpecKeyPairGeneratorSpec。 如果你想使用這兩種情況下"RSA/ECB/PKCS1Padding"(版本的Android M及以下)改變

spec.setEncryptionPaddings(KeyProperties.ENCRYPTION_PADDING_RSA_OAEP) 

spec.setEncryptionPaddings(KeyProperties.ENCRYPTION_PADDING_RSA_PKCS1) 

您可以檢查哪些算法可以用下面的代碼:

Provider[] providers = Security.getProviders(); 
    for (Provider p : providers) { 
     Log.d(TAG, "provider: " + p.getName()); 
     Set<Provider.Service> services = p.getServices(); 
     for (Provider.Service s : services) { 
      Log.d(TAG, "--> algorithm: " + s.getAlgorithm()); 
     } 
    } 

我通過聲明一個接口IKeyStoreHandler來避免寫很多if-else,它提供了所有必要的方法(添加/刪除鍵,列出所有密鑰的別名,私人/公共密鑰,解密/加密文本)並在兩種情況下實施。