2017-03-03 38 views
1

我試圖對AndroidKeyStore中的密鑰執行RSA加密和解密。加密成功完成,但是當我嘗試解密時,它會拋出一個InvalidKeyException:密鑰庫操作在Cipher.init()上失敗。InvalidKeyException:在Android設備上進行RSA解密時密鑰庫操作失敗

這裏是我的keygeneration代碼:

KeyPairGenerator kpGenerator = KeyPairGenerator.getInstance("RSA", "AndroidKeyStore"); 
AlgorithmParameterSpec spec = null; 
spec = new KeyGenParameterSpec.Builder(mAlias, 
     KeyProperties.PURPOSE_ENCRYPT | KeyProperties.PURPOSE_DECRYPT) 
     .setDigests(KeyProperties.DIGEST_SHA256, KeyProperties.DIGEST_SHA512) 
     .setEncryptionPaddings(KeyProperties.ENCRYPTION_PADDING_RSA_PKCS1) 
     .build(); 
kpGenerator.initialize(spec); 
KeyPair kp = kpGenerator.generateKeyPair(); 

這裏是我的加密代碼:

KeyStore keyStore = KeyStore.getInstance("AndroidKeyStore"); 
keyStore.load(null); 
KeyStore.PrivateKeyEntry entry = (KeyStore.PrivateKeyEntry) keyStore.getEntry(mAlias, null); 
Cipher cip = null; 
RSAPublicKey pubKey = (RSAPublicKey) entry.getCertificate().getPublicKey(); 
cip = Cipher.getInstance("RSA/ECB/NoPadding"); 
cip.init(Cipher.ENCRYPT_MODE, pubKey); 
byte[] encryptBytes = cip.doFinal(challenge.getBytes()); 
String encryptedStr64 = Base64.encodeToString(encryptBytes, Base64.DEFAULT); 

這裏是我的解密代碼:

KeyStore keyStore = KeyStore.getInstance("AndroidKeyStore"); 
keyStore.load(null); 
KeyStore.PrivateKeyEntry entry = (KeyStore.PrivateKeyEntry) keyStore.getEntry(mAlias, null); 
Cipher cip = null; 
cip = Cipher.getInstance("RSA/ECB/NoPadding"); 
cip.init(Cipher.DECRYPT_MODE, entry.getPrivateKey()); 
byte[] decryptedBytes = cip.doFinal(Base64.decode(encrypted64, Base64.DEFAULT)); 
String plainText = new String(decryptedBytes); 

我知道,關鍵中的填充代碼與我的加密/解密代碼不同。但是,當我將密鑰生成代碼的填充更改爲KeyProperties.ENCRYPTION_PADDING_NONE時,我在kpGenerator.initialize(spec)上得到了一個InvalidAlgorithmParameterException。 使用「RSA/ECB/PKCS1Padding」進行解密,它可以工作。無論在加密填充,它始終工作。

是的,我也意識到使用無填充的安全含義,但對於我的應用程序,我需要一個確定性的密文。

下面是與InvalidKeyException異常堆棧跟蹤:

03-06 09:10:32.710 5058 5058 W System.err: java.security.InvalidKeyException: Keystore operation failed 
03-06 09:10:32.713 5058 5058 W System.err: at android.security.KeyStore.getInvalidKeyException(KeyStore.java:692) 
03-06 09:10:32.713 5058 5058 W System.err: at android.security.KeyStore.getInvalidKeyException(KeyStore.java:712) 
03-06 09:10:32.713 5058 5058 W System.err: at android.security.keystore.KeyStoreCryptoOperationUtils.getInvalidKeyExceptionForInit(KeyStoreCryptoOperationUtils.java:54) 
03-06 09:10:32.713 5058 5058 W System.err: at android.security.keystore.KeyStoreCryptoOperationUtils.getExceptionForCipherInit(KeyStoreCryptoOperationUtils.java:89) 
03-06 09:10:32.713 5058 5058 W System.err: at android.security.keystore.AndroidKeyStoreCipherSpiBase.ensureKeystoreOperationInitialized(AndroidKeyStoreCipherSpiBase.java:263) 
03-06 09:10:32.713 5058 5058 W System.err: at android.security.keystore.AndroidKeyStoreCipherSpiBase.engineInit(AndroidKeyStoreCipherSpiBase.java:108) 
03-06 09:10:32.713 5058 5058 W System.err: at javax.crypto.Cipher.tryTransformWithProvider(Cipher.java:612) 
03-06 09:10:32.713 5058 5058 W System.err: at javax.crypto.Cipher.tryCombinations(Cipher.java:532) 
03-06 09:10:32.714 5058 5058 W System.err: at javax.crypto.Cipher.getSpi(Cipher.java:437) 
03-06 09:10:32.714 5058 5058 W System.err: at javax.crypto.Cipher.init(Cipher.java:815) 
03-06 09:10:32.714 5058 5058 W System.err: at javax.crypto.Cipher.init(Cipher.java:774) 
03-06 09:10:32.714 5058 5058 W System.err: at dfpidentifiers.my.test.app.MainActivity.decrypt(MainActivity.java:950) 
03-06 09:10:32.714 5058 5058 W System.err: at dfpidentifiers.my.test.app.MainActivity.onCreate(MainActivity.java:117) 
03-06 09:10:32.714 5058 5058 W System.err: at android.app.Activity.performCreate(Activity.java:6251) 
03-06 09:10:32.714 5058 5058 W System.err: at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1107) 
03-06 09:10:32.714 5058 5058 W System.err: at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2369) 
03-06 09:10:32.714 5058 5058 W System.err: at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2476) 
03-06 09:10:32.714 5058 5058 W System.err: at android.app.ActivityThread.-wrap11(ActivityThread.java) 
03-06 09:10:32.714 5058 5058 W System.err: at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1344) 
03-06 09:10:32.714 5058 5058 W System.err: at android.os.Handler.dispatchMessage(Handler.java:102) 
03-06 09:10:32.714 5058 5058 W System.err: at android.os.Looper.loop(Looper.java:148) 
03-06 09:10:32.714 5058 5058 W System.err: at android.app.ActivityThread.main(ActivityThread.java:5417) 
03-06 09:10:32.714 5058 5058 W System.err: at java.lang.reflect.Method.invoke(Native Method) 
03-06 09:10:32.714 5058 5058 W System.err: at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:726) 
03-06 09:10:32.714 5058 5058 W System.err: at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:616) 
03-06 09:10:32.714 5058 5058 W System.err: Caused by: android.security.KeyStoreException: Incompatible padding mode 
03-06 09:10:32.714 5058 5058 W System.err: at android.security.KeyStore.getKeyStoreException(KeyStore.java:632) 
03-06 09:10:32.714 5058 5058 W System.err: ... 24 more 

從堆棧跟蹤,這似乎是一個不兼容的填充模式,但如何生成支持不填充一個密鑰?

+0

請問您可以發佈完整的stacktrace嗎? –

+1

請注意,確定性非對稱密碼通常被認爲是不可行區域;攻擊者可以簡單地嘗試加密幾條消息以找到與你的密文相匹配的消息。如果在消息中已經有足夠的隨機字節,那麼我會考慮使用例如擴展它到全模數大小(-1最高有效位)。 HKDF或XOF和RSA加密此值。然後,你可以再次使用HKDF從該值(在加密之前/解密之後)導出一個對稱密鑰,並最終用它來用例如密文對密文進行加密。 AES-GCM。 –

+0

也許你需要傳遞密碼的回調處理程序。如果這是你的問題,請允許我回答這個問題;沒有堆棧跟蹤或密鑰存儲,我們無法驗證任何解決方案。 –

回答

2

InvalidKeyException實際上是由密鑰生成和解密期間的填充差異引起的。不知道爲什麼加密不會拋出相同的異常。

由於IND-CPA是必需的,因此我最初無法在密鑰生成期間使用NoPadding。我必須設置setRandomizedEncryptionRequired(true)來覆蓋這個。

+0

感謝您報告回來! –