2012-04-26 193 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