声明:本文为作者原创,请勿随意转载,制造网络垃圾
客户使用pfx格式CA证书做服务端签名认证,在测试环境下(windows2003 weblogic9)一切正常,可以正常做服务端签名、签名校验操作,但是在正式环境下(aix weblogic9)下做服务端签名时却不能正常,证书加载的时候就报错了,报错信息如下:
Caused by: com.itrus.cryptorole.CryptoException: java.io.IOException: Private key decryption error: (java.security.InvalidKeyException: Illegal key size)
at com.itrus.cryptorole.bc.SenderBcImpl.initCertWithKey(SenderBcImpl.java:173)
at com.xxsoft.security.pki.adapter.ITrusChinaCertSigner.signMsgData(ITrusChinaCertSigner.java:76)
... 84 more
Caused by: java.io.IOException: Private key decryption error: (java.security.InvalidKeyException: Illegal key size)
at com.ibm.crypto.provider.PKCS12KeyStore.engineLoad(Unknown Source)
at java.security.KeyStore.load(KeyStore.java:1173)
at com.itrus.cryptorole.bc.SenderBcImpl.initCertWithKey(SenderBcImpl.java:150)
... 85 more
1、初步怀疑为正式环境下证书弄错,经过多次检查,及将正式环境证书替换到测试环境验证,均一切正常,排除证书问题,也排除了证书路径设置错误问题已经秘密设置错误问题。
2、通过报错中的at com.ibm.crypto.provider.PKCS12KeyStore.engineLoad信息,怀疑为jdk兼容问题,经检查,发现测试环境下使用的为sun jdk1.5,而正式环境由于是ibm的小型机,安装是是ibm的aix系统,使用的是默认安装的ibm jdk1.5
初步判定为jdk的兼容性问题造成。
3、 经过网上搜索资料,发现也有人碰到类似的问题,很多人回答也都是jdk的兼容性问题,但均没能给出具体的解决方案,或者说是使用ibm的下对pkcs12证书的解析方式来弄,但是由于使用的为CA厂商的签名认证CA和他们的API,无法修改他们的API,只能直接咨询CA厂商的相关技术人员。沟通了老半天他们也没能给出一个合理满意的答复,总是纠结在我们是否在aix系统中将路径配置错误的问题上。最后说下周会派相关技术人员现场支持看一下情况……
4、 经咨询公司安全方面同事,建议使用开源安全框架bouncycastle替换原有的默认的安全签名算法实现,并设置java.security中的相关参数来使设置生效。
5、 解决问题首先需要在测试环境下重现问题,Windows环境下问题重现
首先下载一个ibm的官方的jdk1.5,ibm官方jdk下载地址为http://www.ibm.com/developerworks/java/jdk/,经访问发现只提供一个版本的可以安装在windows环境下的jdk,而且要求安装的机器必须为ibm的机器或者联想的机器,本人测试机器虽为联想的,但是依然安装失败,经网上搜索发现,有些人提供一些将该版本的jdk安装版解包变成可以使用的方法,但是操作步骤较为复杂,暂时放弃;再次搜索ibm的官方网站,发现ibm其实是有提供一个eclipse环境中可以使用的jdk的,下载下来配置到eclipse环境中,编写服务端签名测试程序,问题重现。
下载地址:
https://www14.software.ibm.com/webapp/iwm/web/reg/signup.do?source=idpe&S_TACT=105AGX05&S_CMP=JDK&lang=en_US&S_PKG=win300
6、 参照上述4中提供的方法设置对应的JAVA_HOME/jre/lib/security/java.security文件参数为
security.provider.1 =org.bouncycastle.jce.provider.BouncyCastleProvider
默认使用的第一个实现为.BouncyCastleProvider,经测试,依然报错,但报错信息变为:
Caused by: java.lang.SecurityException: Cannot set up certs for trusted CAs
at javax.crypto.b.<clinit>(Unknown Source)
at java.lang.J9VMInternals.initializeImpl(Native Method)
at java.lang.J9VMInternals.initialize(J9VMInternals.java:192)
... 7 more
Caused by: java.security.PrivilegedActionException: java.security.InvalidKeyException: Public key presented not for certificate signature
at java.security.AccessController.doPrivileged(AccessController.java:246)
... 10 more
Caused by: java.security.InvalidKeyException: Public key presented not for certificate signature
at org.bouncycastle.jce.provider.X509CertificateObject.checkSignature(Unknown Source)
at org.bouncycastle.jce.provider.X509CertificateObject.verify(Unknown Source)
at javax.crypto.b.a(Unknown Source)
at javax.crypto.b.access$500(Unknown Source)
at javax.crypto.b$0.run(Unknown Source)
at java.security.AccessController.doPrivileged(AccessController.java:242)
... 10 more
7、 无意中搜索中发现一篇介绍java安全的文档《关于Java加密扩展的出口限制》(文档地址http://www.blogjava.net/security/archive/2006/03/08/34381.html)中介绍到sun的默认jdk对密码算法的长度有个限制,只有另外下载一个无限制的设置文件才能使用更多长度的算法。突然意识到ibm的jdk中是否就是存在这种限制,而测试环境使用的sun jdk反而去掉该限制了呢?
再次搜索,发现确实存在这种情况,而且ibm也提供一个无限制的实现,替换使用之后即可解除该限制,具体可见:http://www-01.ibm.com/support/docview.wss?uid=swg21201170中的介绍。
立即下载并替换掉JAVA_HOME/jre/lib/security/中现有的两个包。再次测试,服务端签名及签名验证均通过,一切正常。
8、 正式aix环境下使用同样的方式替换对应的文件(先备份,再替换),重新启动系统服务,测试正常。
9、 其实打开对应的两个的两个替换的jar可以发现,里面其实有相关的对签名加密算法的定义的,如下:
解除限制的jar中的文件内容:
从以上可以很明显的看出,原生态的aix系统中ibm的jdk对算法只定义了文件中的几种,其他的应该是全部不支持的。