基本环境:
客户的单点登录服务器是使用 .net 开发的。 所以私钥,公钥 都有他们生成。
我们的程序是 java 开发的,需要使用公钥 对齐发过来的数据进行签名认证。
问题就出来了,验证就是不成功。经过很久很久的纠结,最终找到答案。
明文: date = URLDecoder.decode(date,"GB2312");
摘要: signDate = URLDecoder.decode(signDate,"GB2312").replaceAll(" ", "+");
//对明文进行 sha-1 摘要计算 这就死关键的关键啊,
主要原因是 .net 的byte 与 java的byte 是不一样的。 这里需要进行16进制的转换,百思不得其解。
MessageDigest medt = MessageDigest.getInstance("SHA-1");
medt.update(date.getBytes());
byte[] pp = medt.digest();
StringBuffer buf = new StringBuffer("");
for(int i=0;i<pp.length;i++){
if((pp[i]&0xff)<0x10){
buf.append("0");
}
buf.append(Long.toString(pp[i]&0xFF,16));
}
date = buf.toString().toUpperCase();
//构建证书
CertificateFactory factory = CertificateFactory.getInstance("X.509");
Certificate cert = factory.generateCertificate(new FileInputStream(publicKeyPath));
X509Certificate x509 = (X509Certificate) cert;
PublicKey publicKey = x509.getPublicKey();
// 对摘要进行 签名验证
Signature signature = Signature.getInstance("SHA1withRSA");
signature.initVerify(publicKey);
signature.update(date.getBytes());
return signature.verify(decryptBASE64(signDate));
验证成功了,就以为解密就有思路了 呵呵!!!!
这个但是我纠结了很久, 某某银行的内部都在为这个纠结。 学会了才知道 原来如此简单。