RSA体系 c++/java相互进行加签验签--转
在web開(kāi)發(fā)中,采用RSA公鑰密鑰體系自制ukey,文件證書登陸時(shí),普遍的做法為:在瀏覽器端采用c++ activex控件,使用 c++的第三庫(kù)openssl進(jìn)行RAS加簽操作,在服務(wù)器端采用java對(duì)客戶端的簽名進(jìn)行驗(yàn)簽操作。這就涉及到c++ openssl和java之間交互加簽驗(yàn)簽對(duì)客戶端身份進(jìn)行驗(yàn)證的過(guò)程。
? ? ? ?如果你通過(guò)搜索查到我這邊文章,相信你一定發(fā)現(xiàn),采用openssl加簽后的 數(shù)據(jù),在java端卻驗(yàn)簽不成功,使用openssl驗(yàn)簽可以通過(guò)。問(wèn)題在于openssl的公鑰發(fā)在服務(wù)端轉(zhuǎn)換成java RSA 公鑰時(shí)有問(wèn)題,openssl的公鑰格式里附加了它自己的一些額外信息。所以在服務(wù)端java構(gòu)造自己的pubkey時(shí)必須先剔除openssl的特有信息。
? ? ? ?例如如果我么采用openssl生成 modulus?size?為1024, exponent為65537 的公鑰秘鑰對(duì)---RSA_generate_key(1024, 65537, NULL, NULL);那么我們?cè)趈ava端通過(guò)openssl的公鑰構(gòu)造java格式的公鑰時(shí),我們就必須采用如下方式獲得modulus ,然后采用java的方式構(gòu)造公鑰,進(jìn)行驗(yàn)簽操作。
?
private static byte[] getModulus(byte[] pkData, int begin){
byte[] modData = new byte[128] ;
byte[] ss = {pkData[0],pkData[1],pkData[2],pkData[3]};
for(int i = 0, y = begin; i < 128; i++,y++){
modData[i] = pkData[y];
}
return modData;
}
?
/**
?* 從openssl中提起相關(guān)的128為的公鑰數(shù)據(jù)
?* @param b64Str
?* @return
?*/
private static byte[] get128PkData(String b64Str){
String pk = b64Str.replace("-----BEGIN RSA PUBLIC KEY-----", "");//剔除前面的信息
pk = pk.replace("-----END RSA PUBLIC KEY-----", "");// 剔除后面的信息
byte[] pkData = Base64.decode(pk);
return getModulus(pkData, 7);//下標(biāo)從7開(kāi)始,獲得128 bytes的modulus
}
/** 如果你問(wèn)我里邊到底加了一些什么信息,我也不知道,我是從下標(biāo)1開(kāi)始不斷測(cè)試,才得出應(yīng)該從下標(biāo)7開(kāi)始獲取modulus值 ***/
?
/**
?* 由1024位的公鑰轉(zhuǎn)換成x509格式的公鑰
?* @param modData
?* @return
?* @throws Exception
?*/
private static PublicKey getPublicKey(byte[] modData) throws Exception{
KeyFactory keyf = KeyFactory.getInstance("RSA");
RSAPublicKeySpec pubKeySpec = new RSAPublicKeySpec(new BigInteger(modData), new BigInteger("65537"));
RSAPublicKey pk = (RSAPublicKey) keyf.generatePublic(pubKeySpec);
// 解密由base64編碼的公鑰,并構(gòu)造X509EncodedKeySpec對(duì)象
java.security.spec.X509EncodedKeySpec bobPubKeySpec = new java.security.spec.X509EncodedKeySpec(
pk.getEncoded());
return keyf.generatePublic(bobPubKeySpec);
}
至于openssl我就不再做介紹,網(wǎng)上有很多資料,而且它本身的文檔也很齊全
在后面附上一些相關(guān)的類, ?SignProvider.java 端負(fù)責(zé)公鑰轉(zhuǎn)換和加簽驗(yàn)簽 ? ? Base64.java負(fù)責(zé)64為編碼 ? ?fcOpenSslRef.rar---Openssl相關(guān)類
注:本人對(duì)c++也不熟,所以上面的一些c++代碼只做參考。
原文:http://www.chlusoft.com/tech/347.jhtml
轉(zhuǎn)載于:https://www.cnblogs.com/davidwang456/p/3922508.html
總結(jié)
以上是生活随笔為你收集整理的RSA体系 c++/java相互进行加签验签--转的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: 在浏览器地址栏按回车、F5、Ctrl+F
- 下一篇: RSA加密解密及数字签名Java实现--