2012-04-26 244 views
4

我的Android項目中有一些解密問題。用公鑰解密RSA

我得到一個用私鑰簽名的字符串,我必須用公鑰驗證(解密)它。 我想獲得完全相同的結果,如果我用一個PHP函數 - openssl_public_decrypt(http://php.net/manual/pl/function.openssl-public-decrypt.php

我必須做這在我的Java項目,這樣我就可以使用Java庫(如BouncyCastle的,什麼否則,有什麼建議?)

任何想法如何解決這個問題?

好的,這是我的代碼。 我得到的公鑰這樣

PEMReader reader = new PEMReader(new InputStreamReader(ctx 
       .getAssets().open("pubkey.pem"))); 
     Object obj; 
     while ((obj = reader.readObject()) != null) { 
      if (obj instanceof RSAPublicKey) { 
       pubKey = (RSAPublicKey) obj; 
       return pubKey; 
      } 
     } 

,我總是得到沒有任何問題的公鑰。

Cipher c = Cipher.getInstance("RSA/NONE/NoPadding", "SC"); 
c.init(Cipher.DECRYPT_MODE, pubKey); 
byte[] result = c.doFinal(data_to_decrypt.getBytes()); 

而作爲一個結果(字節轉換爲字符串之後)我得到022c06571c6a263b389fcd93159cb311abb880bddf51b7c916dd1ae...

其中PHP函數返回 sd8dsa348acvcx87|00454|OK|15000|CDE,這是一個正確的輸出。

+2

在公鑰加密中:你使用私鑰簽名和解密/解密;您使用公鑰驗證(簽名)並加密/加密。你想要做什麼? – Bruno 2012-04-26 11:09:49

+0

就像我說的我想用公鑰解密數據 – Mike 2012-04-26 11:12:53

+3

你*不能*用公鑰解密數據,它沒有任何意義(儘管PHP的命名選擇很差)。 「*我得到一個用私鑰加密的字符串*」:這實際上沒有意義。它最好籤名。當然,使用RSA它或多或少會有相同的操作(但對於DSA來說情況並非如此)。問題在於消息的簽名幾乎肯定會涉及散列,因此獲得原始消息是不可能的。 – Bruno 2012-04-26 11:15:40

回答

5

Java已經得到了Java加密擴展框架,它只是爲這些東西而設計的。

BouncyCastle是此框架的加密提供程序。這意味着,它爲您的Java加密擴展提供了加密算法的實現。

你會發現這種情況的基礎類包java.securityjavax.crypto

要使用公鑰解密你的消息,你可以嘗試以下方法:

// Use RSA/NONE/NoPadding as algorithm and BouncyCastle as crypto provider 
Cipher asymmetricCipher = Cipher.getInstance("RSA/NONE/NoPadding", "BC"); 

// asume, that publicKeyBytes contains a byte array representing 
// your public key 
X509EncodedKeySpec publicKeySpec = new X509EncodedKeySpec(publicKeyBytes); 

KeyFactory keyFactory; 
keyFactory = KeyFactory.getInstance(publicKeySpec.getFormat()); 
Key key = keyFactory.generatePublic(publicKeySpec); 

// initialize your cipher 
asymmetricCipher.init(Cipher.DECRYPT_MODE, key); 
// asuming, cipherText is a byte array containing your encrypted message 
byte[] plainText = asymmetricCipher.doFinal(cipherText); 

請注意,這個例子基本上是非常並且缺少幾個try catch塊。此外,不應使用不帶填充的非對稱密碼,因爲這會使您容易受到重播攻擊。您也可能遇到密鑰長度問題。在一些Java軟件包中,允許的最大密鑰長度受到限制。這可以通過使用無限強度策略文件來解決。

我希望這可以幫助您開始使用Java加密技術。

+0

謝謝您的回答。我以前有一個類似的解決方案,它的工作原理,但我得到的結果是某事像這樣:022c06571c6a263b389fcd93159cb311abb880bddf51b7c916dd1ae ...其中PHP函數返回解密的字符串,其中一個問題與? – Mike 2012-04-26 12:10:41

+0

該方法返回一個字節數組。你把結果轉換爲String嗎? 還有我剛剛認識到,我沒有分配的doFinal方法給一個變量的結果......要編輯答案... – Francis 2012-04-26 12:24:42

+0

我的結果轉換爲字符串,並從我以前的評論輸出轉換爲String從字節數組 – Mike 2012-04-26 12:59:21