2013-11-20 136 views
19

在創建加密/解密消息並通過互聯網發送消息的簡單消息android應用程序的過程中,我決定使用RSA公鑰/私鑰加密。問題是如何存儲私鑰,這樣即使手機被惡意植入,密鑰也會保持安全?據我瞭解,KeyStore用於證書,不能用於此?我應該使用AES將私鑰加密爲文本文件嗎?我對安全性的經驗很少,所以請隨時糾正我的想法,並發表您的意見!存儲RSA私鑰Android

親切的問候。

+3

@LokiSinclair你可以把公鑰放在任何你喜歡的地方,並顯示給任何你喜歡的人,這就是爲什麼它是公開的。因此用私鑰存儲它很好。您只需將私鑰保存在安全的地方。 – Peanut

+0

@LokiSinclair對不起,但這是錯誤的。私鑰最好存儲在應該能夠解密消息的設備上。備份可以在線進行,但這會帶來安全風險。而且,將公鑰存儲在與私鑰相同的地方沒有任何風險。 – joakimb

回答

8

我認爲KeyStore可能適合您的使用。它能夠存儲RSA密鑰並使用AES對它們進行加密,所以即使擁有root訪問權限,也不能在沒有密碼或暴力破解的情況下提取它們。

有一個很好的文章在這裏關於使用密鑰庫:http://nelenkov.blogspot.fr/2012/05/storing-application-secrets-in-androids.html

+0

感謝您的回覆,您鏈接的博客非常有用!有一篇關於基於密碼的加密的文章,我發現它比依賴於KeyStore更加適合和可取,至少對於我的應用程序而言。再次感謝你! – user32981

3

你能堅持在Android上使用您的SharedPreference RSA公鑰/私鑰。 爲了在手機被惡意植根時保持密鑰安全,您可以執行以下步驟:

1:當您想要ecrypt任何數據時生成密鑰對。
2:提示用戶輸入密碼。
3:使用該密碼生成對稱密鑰來加密您的私鑰。
4:您可以使用公鑰加密數據並使用私鑰解密。
5:您可以爲步驟2中提示的密碼保留會話。在該會話期間,您可以使用對稱密鑰(由密碼生成)來加密/解密私鑰。

下面的代碼片段顯示瞭如何存儲&獲取公鑰

public void setPublicKey(PublicKey publicKey, String key, Context context) { 

    byte[] pubKey = publicKey.getEncoded(); 
    String pubKeyString = Base64.encodeBytes(pubKey); 
    this.setString(key, pubKeyString, context); 
} 

public PublicKey getPublicKey(String key,Context context) { 

    PublicKey pKey = null; 
    try { 

     String pubString = this.getString(key, context); 

     if(pubString!=null) { 
      byte[] binCpk = Base64.decode(pubString); 
      KeyFactory keyFactory = KeyFactory.getInstance("RSA"); 
      X509EncodedKeySpec publicKeySpec = new X509EncodedKeySpec(binCpk); 
      pKey = keyFactory.generatePublic(publicKeySpec); 
     } 
     }catch(Exception e){ 
    } 
    return pKey; 
} 

下面的代碼片段展示瞭如何存儲&獲取私鑰。

public void setPrivateKey(PrivateKey privateKey, String key, Context context) { 

    byte[] priKey = privateKey.getEncoded(); 
    String priKeyString = Base64.encodeBytes(priKey); 
    this.setString(key, priKeyString, context); 
} 

public PrivateKey getPrivateKey(String key, Context context) { 

    PrivateKey privateKey = null; 

    try { 
     String privateString = this.getString(key, context); 
     if(privateString!=null){ 
      byte[] binCpk = Base64.decode(privateString); 
      KeyFactory keyFactory = KeyFactory.getInstance("RSA"); 
      PKCS8EncodedKeySpec privateKeySpec = new PKCS8EncodedKeySpec(binCpk); 
      privateKey = keyFactory.generatePrivate(privateKeySpec); 
     } 
    } 
    catch(Exception e){ 
    } 
    return privateKey; 
} 
+4

請不要對私鑰執行此操作。很難得到正確的結果。可以使用內置的keystore API(可用於Android 4.3+)或使用常規的'KeyStore'(BKS/JKS)來存儲您的密鑰和證書。該格式具有完整性保護和加密功能,並且可以通過密碼進行保護。 –

+0

我正確的說我只是在set方法中編碼密鑰? – Karoly

2

文件系統中的密鑰庫(P12,JKS,AKS)都不足以保存RSA私鑰。只有智能卡或安全令牌可以提供高級別的安全性。閱讀本書:「Android安全內部」。在本書中,您將找到有關Android安全和JCA提供商的良好說明。

+2

有趣的是,「Android安全內部」作者自己推薦使用「常規'KeyStore'(BKS/JKS)來存儲你的密鑰和證書」。請閱讀之前回答的評論。 仍然建議有效。非常好的書籍和博客,來自Nikolay Elenkov。 – jfuentes