Java与.Net环境下RSA加密解密交互不成功的问题解决【续】

在前面《一篇文章》中提到了 Java和.Net环境下RSA加解密不能互通的情况,最后通过重写.Net下面RSA算法来解决了问题;本文将就这个问题再深入一点,看是否能有其他方式可以解决;

首先来看下Java对Security领域的支持情况
Jdk提供了非常强大的API集合,以及对常用算法、协议的通用实现;主要包括四个方面:
1、加解密,该部分对常用算法及其加密标准提供了支持,体现为JCA【Java Cryptographic Architecture】和JCE【Java Cryptographic Extension】,通过这两个组件,用户可以实现自己的加解密算法,并可以在JVM中进行插拔,使用非常灵活;比如业界著名的bouncycastle实现就是通过JCE来提供的;有一点需要注意:通过java.security进行插拔时用到的自定义jar包一定是要经过数字签名的,否则jvm会拒绝执行;
2、PKI,这部分主要是提供对PKI体系的支持,比如X.509证书、CRLs【Certificate Revocations Lists】、OCSP【On-Line Certificate Status Protocol】、LDAP【Lightweight Directory Access Protocol】等等;
3、安全通信,这部分主要是提供对底层安全通信协议的支持,比如SSL/TLS上层的HTTPS等,通过JSSE【Java Secure Socket Extension】、JGSS【Java Generic Security Services】、JSASL【Java Simple Authentication and Security Layer】等组件来实现;
4、鉴别和访问控制,这部分实现对多种鉴别机制实现SSO,以及对各类资源实现权限控制,主要组件有:JAAS【Java Authentication and Authorization Service】、Policy……
具体的各组件的内容可以从Java SE Security首页http://java.sun.com/javase/technologies/security/index.jsp查看;以上内容体现在JDK中的package主要有:java.security.*、javax.crypto.*、javax.security.*;
其支持的各类标准算法可以到http://java.sun.com/javase/6/docs/technotes/guides/security/StandardNames.html查看;

.Net对Security的支持相对来说要弱一些,他没有分类这么详细,也没有提供类似JCA/JCE这类可扩展组件,对各类标准算法的支持也较少;他主要通过System.Security这个命名空间来提供支持,而我们最常用到的应该是:
System.Security.Cryptography,该命名空间提供加密服务,包括安全的数据编码和解码,以及许多其他操作,例如散列法、随机数字生成和消息身份验证。
System.Security.Cryptography.X509Certificates,该命名空间提供对Authenticode X.509 v.3 证书的公共语言运行库实现。

回到上次我们遇到的问题,.Net环境下每次用RSA算法加密都会得到不同的结果,这是因为每次都添加了一些随机数,其实这些随机数的生成也是遵循算法标准的,更专业的说是随机填充算法,比如NoPadding、ISO10126Padding、OAEPPadding、PKCS1Padding、PKCS5Padding、SSL3Padding,而最常见的应该是OAEPPadding【Optimal Asymmetric Encryption Padding】、PKCS1Padding;.Net的实现用的是PKCS1Padding,而且只有这一种实现,也不能通过参数指定用哪种填充算法;另外,通过RSACryptoServiceProvider.KeyExchangeAlgorithm查看到的结果是RSA-PKCS1-KeyEx,由于无法看到源码,不知道最后的KeyEx代表什么意思?
反观Java的实现,主要通过Cipher.getInstance实现,传入的参数是描述为产生某种输出而在给定的输入上执行的操作(或一组操作)的字符串。必须包括加密算法的名称,后面可能跟有一个反馈模式和填充方案。这样的实现就比较灵活,我们可以通过参数指定不同的反馈模式和填充方案;比如Cipher.getInstance("RSA/ECB/PKCS1Padding"),或者Cipher.getInstance("RSA")均可,但用其加密的效果也会不一样;
用.Net的与Java对照下,应该KeyEx对应于反馈模式,但是我用Java中所有可能的反馈模式【NONE、CBC 、CFB/CFBx、CTR、CTS、ECB、OFB/OFBx、PCBC】来进行测试,发现还是没有一种能够实现双方加解密互通!
上次一位网友说.Net/C++两者可以互通,这是完全可能的,我不熟悉C++,但只要他和.Net采用相同的加密规则(包括加密算法、反馈模式、填充方案)就可以互通,这个规则适合于所有的语言之间;

虽然双方的加解密不能互通,但是数字签名和验证却没有问题,用默认实现类即可;因为数字签名是不能采用填充算法来进行加密的,这样就失去了对原始数据签名的意义了;

另外,还有一个小细节,.Net对X.509证书的支持是v3版本,而Java支持的却是v1版本(用keytool生成的jks文件都是对应v1版本的),虽然目前我在使用证书上没有发现任何问题,但我想应该是我们没有用到证书的一些细节地方;

评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值