分享

Android 与 .net 互通的RSA加密

 时间要去哪 2014-07-07

.net 用于RSA加密的公钥是形似这样的字符串:

<RSAKeyValue><Modulus>sYbL…nGb=</Modulus><Exponent>AQAB</Exponent></RSAKeyValue>

这样的公钥,是Java无法直接使用的。所以从网上找到用于转换这个公钥的类RsaHelper。(下载RsaHelper)然后:

  1. PublicKey pubKey = RsaHelper.decodePublicKeyFromXml(Global.RSA_PUBLIC_KEY);  
  2. encryptedString = RsaHelper.encryptDataFromStr(plaintString,pubKey);  

这样,RSA加密就完成了,而且加密后的结果给到.net也能成功解密(Java工程用的jdk1.6)。 

然后我把Java工程里的代码拷贝到Android工程(android2.3)里,加密后的内容.net端竟然无法解密!!! 

难道Android工程与Java工程,用同样的代码同样的公钥加密同样的字符串,结果是不一样的?

我试了一下,在Android工程里,每次加密同一个字符串,加密结果都是一致的。但在Java工程里,即使加密同一个字符串,每次出来的结果都不一样。

跟踪一下RsaHelper的代码,关键的几句如下:

  1. Cipher cipher = Cipher.getInstance("RSA");  
  2. cipher.init(Cipher.ENCRYPT_MODE, pubKey);  
  3. return cipher.doFinal(data);  

问题一定就出在这个Cipher类里了。

通过网络搜索,找到了以下内容:(内容来自http://blog.csdn.net/sfdev/article/details/2188563

.Net环境下每次用RSA算法加密都会得到不同的结果,这是因为每次都添加了一些随机数,其实这些随机数的生成也是遵循算法标准的,更专业的说是随机填充算法,比如NoPadding、ISO10126Padding、OAEPPadding、PKCS1Padding、PKCS5Padding、SSL3Padding。 

Java主要通过Cipher.getInstance实现RSA,传入的参数是描述为产生某种输出而在给定的输入上执行的操作(或一组操作)的字符串。必须包括加密算法的名称,后面可能跟有一个反馈模式和填充方案。这样的实现就比较灵活,我们可以通过参数指定不同的反馈模式和填充方案;比如Cipher.getInstance("RSA/ECB/PKCS1Padding"),或者Cipher.getInstance("RSA")均可,但用其加密的效果也会不一样; 

看到这里,显而易见的一个方法就是在Android工程里getInstance的时候,指定一下随机填充算法。

所以把Cipher cipher = Cipher.getInstance("RSA");改成

Cipher cipher = Cipher.getInstance("RSA/ECB/PKCS1Padding");

试一下,成功了!  

    本站是提供个人知识管理的网络存储空间,所有内容均由用户发布,不代表本站观点。请注意甄别内容中的联系方式、诱导购买等信息,谨防诈骗。如发现有害或侵权内容,请点击一键举报。
    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多