Android 与 .net 互通的RSA加密

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

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

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

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

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

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

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

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

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

Cipher cipher = Cipher.getInstance("RSA");
cipher.init(Cipher.ENCRYPT_MODE, pubKey);
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
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 7
    评论
评论 7
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值