您好,欢迎来到三六零分类信息网!老站,搜索引擎当天收录,欢迎发信息

PHP,C# 跟JAVARSA签名及验签

2025/12/12 2:49:25发布27次查看
php,c# 和javarsa签名及验签
这个功能网上搜了好多资料。贡献一下,转载须注明并对卓二妹的无私奉献表示感谢。
1)签名算法使用sha1withrsa。
2)签名后的数据位base64编码的密文字符串。
3)三个环境进行签名的私钥的格式不同,需要openssl工具进行转换。
――――――――――――――――――――――――――――――――――――――――――
java签名:
1)从包含公私钥的pfx证书中取得.key私钥:
f:\openssl-0.9.8k_win32\bin>openssl pkcs12 -in f:\certs\zhuo.pfx -out f:\certs\zhuo.pementer import password:(输入导出时的密码)mac verified okenter pem pass phrase:(长度至少为4位的pem证书密码)verifying - enter pem pass phrase:(确认一次pem证书密码) f:\openssl-0.9.8k_win32\bin>openssl pkcs8 -topk8 -inform pem -outform der -in f:\certs\zhuo.pem -out f:\certs\zhuo_der.key -nocryptenter pass phrase for f:\certs\zhuo.pem:(输入pem证书密码)
该步骤生成的.key文件即为java签名所需私钥文件。
2)生成公钥:直接从ie中导出x.509格式二进制编码的cer为后缀的公钥证书即可。
?
?
3)签名验签:
?
//签名:/** * * 函数功能说明: 签名数据 * created by zhuoyueping 2013-8-17 * modified by zhuoyueping 2013-8-17 * 修改内容说明: * @param @param content:签名原文 * @param @param keyfile:私钥文件.key路径 * @param @return * @param @throws exception * @return string :base64签名 * @throws */ public string sign(string content, string keyfile) throws exception { file file = new file(keyfile); //keyfile key文件的地址 fileinputstream in; in = new fileinputstream(file); bytearrayoutputstream bout = new bytearrayoutputstream(); byte[] tmpbuf = new byte[1024]; int count = 0; while ((count = in.read(tmpbuf)) != -1) { bout.write(tmpbuf, 0, count); tmpbuf = new byte[1024]; } in.close(); keyfactory keyfactory = keyfactory.getinstance(rsa); encodedkeyspec privatekeyspec = new pkcs8encodedkeyspec(bout .tobytearray()); rsaprivatekey privatekey = (rsaprivatekey) keyfactory .generateprivate(privatekeyspec); signature dsa = signature.getinstance(sha1withrsa); //采用sha1withrsa加密 dsa.initsign(privatekey); dsa.update(content.getbytes(utf-8)); //voucher需要加密的string必须变成byte类型的 byte[] sig = dsa.sign(); string rtnvalue = new string(base64.encode(sig)); return rtnvalue; } /** * * 验证签名 *
* * @param data 原文字节 * @param sign 数据签名[base64] * @param certificatepath 证书存储路径 * @return * @throws exception */public static boolean verifysign(byte[] data, string sign, string certificatepath) throws exception { // 获得证书 x509certificate x509certificate = (x509certificate) getcertificate(certificatepath); return verifysign(data,sign,x509certificate); }private static boolean verifysign(byte[] data, string sign, x509certificate x509certificate)throws exception { publickey publickey = x509certificate.getpublickey(); signature signature = signature.getinstance(x509certificate .getsigalgname()); signature.initverify(publickey); signature.update(data); return signature.verify(base64.decode(sign.getbytes())); }
?
c#签名:
1)从包含公私钥的pfx证书中取得.key私钥:
f:\openssl-0.9.8k_win32\bin> openssl rsa -in d:\\certs\\zhuo.pfx -nocerts -nodes -out d:\\certs\\zhuo.key该步骤生成的.key文件即为c#签名所需私钥文件。
?
2)公钥生成:于java方式相同,都是二进制格式的x509证书3)签名及验签:
using system;using system.text;using system.security.cryptography;using system.web;using system.io;using system.security.cryptography.x509certificates; namespace safe{ public class safeutil { /// /// 验证签名 /// /// 原文:utf8编码 /// 签名:base64编码的字节 /// 公钥路径 /// 验签结果 public bool verify(string originalstring, string signaturestring,string publickeypath) { //将base64签名数据转码为字节 byte[] signedbase64 = convert.frombase64string(signaturestring); byte[] orgin = encoding.utf8.getbytes(originalstring); x509certificate2 x509_cer1 = new x509certificate2(publickeypath); rsacryptoserviceprovider orsa = new rsacryptoserviceprovider(); orsa.fromxmlstring(x509_cer1.publickey.key.toxmlstring(false)); bool bverify = orsa.verifydata(orgin, sha1, signedbase64); return bverify; } /// /// 验证签名 /// /// 原文:utf8编码 /// 证书路径:d:/certs/mycert.key /// 验签 public string sign(string data, string privatekeypath) { rsacryptoserviceprovider rsacsp = loadcertificatefile(privatekeypath); byte[] databytes = encoding.utf8.getbytes(data); byte[] signaturebytes = rsacsp.signdata(databytes, sha1); return convert.tobase64string(signaturebytes); } private byte[] getpem(string type, byte[] data) { string pem = encoding.utf8.getstring(data); string header = string.format(-----begin {0}-----, type); string footer = string.format(-----end {0}-----, type); int start = pem.indexof(header) + header.length; int end = pem.indexof(footer, start); string base64 = pem.substring(start, (end - start)); return convert.frombase64string(base64); } private rsacryptoserviceprovider loadcertificatefile(string filename) { using (system.io.filestream fs = system.io.file.openread(filename)) { byte[] data = new byte[fs.length]; byte[] res = null; fs.read(data, 0, data.length); if (data[0] != 0x30) { res = getpem(rsa private key, data); } try { rsacryptoserviceprovider rsa = decodersaprivatekey(res); return rsa; } catch (exception ex) { } return null; } } private rsacryptoserviceprovider decodersaprivatekey(byte[] privkey) { byte[] modulus, e, d, p, q, dp, dq, iq; // --------- set up stream to decode the asn.1 encoded rsa private key ------ memorystream mem = new memorystream(privkey); binaryreader binr = new binaryreader(mem); //wrap memory stream with binaryreader for easy reading byte bt = 0; ushort twobytes = 0; int elems = 0; try { twobytes = binr.readuint16(); if (twobytes == 0x8130) //data read as little endian order (actual data order for sequence is 30 81) binr.readbyte(); //advance 1 byte else if (twobytes == 0x8230) binr.readint16(); //advance 2 bytes else return null; twobytes = binr.readuint16(); if (twobytes != 0x0102) //version number return null; bt = binr.readbyte(); if (bt != 0x00) return null; //------ all private key components are integer sequences ---- elems = getintegersize(binr); modulus = binr.readbytes(elems); elems = getintegersize(binr); e = binr.readbytes(elems); elems = getintegersize(binr); d = binr.readbytes(elems); elems = getintegersize(binr); p = binr.readbytes(elems); elems = getintegersize(binr); q = binr.readbytes(elems); elems = getintegersize(binr); dp = binr.readbytes(elems); elems = getintegersize(binr); dq = binr.readbytes(elems); elems = getintegersize(binr); iq = binr.readbytes(elems); // ------- create rsacryptoserviceprovider instance and initialize with public key ----- cspparameters cspparameters = new cspparameters(); cspparameters.flags = cspproviderflags.usemachinekeystore; rsacryptoserviceprovider rsa = new rsacryptoserviceprovider(1024, cspparameters); rsaparameters rsaparams = new rsaparameters(); rsaparams.modulus = modulus; rsaparams.exponent = e; rsaparams.d = d; rsaparams.p = p; rsaparams.q = q; rsaparams.dp = dp; rsaparams.dq = dq; rsaparams.inverseq = iq; rsa.importparameters(rsaparams); return rsa; } catch (exception ex) { return null; } finally { binr.close(); } } private int getintegersize(binaryreader binr) { byte bt = 0; byte lowbyte = 0x00; byte highbyte = 0x00; int count = 0; bt = binr.readbyte(); if (bt != 0x02) //expect integer return 0; bt = binr.readbyte(); if (bt == 0x81) count = binr.readbyte(); // data size in next byte else if (bt == 0x82) { highbyte = binr.readbyte(); // data size in next 2 bytes lowbyte = binr.readbyte(); byte[] modint = { lowbyte, highbyte, 0x00, 0x00 }; count = bitconverter.toint32(modint, 0); } else { count = bt; // we already have the data size } while (binr.readbyte() == 0x00) { //remove high order zeros in data count -= 1; } binr.basestream.seek(-1, seekorigin.current); //last readbyte wasn't a removed zero, so back up a byte return count; } }}
?
php签名:
1)从包含公私钥的pfx证书中取得.key私钥:于c#的证书一致
2)公钥生成:
f:\openssl-0.9.8k_win32\bin>openssl pkcs12 -in f:\certs\zhuo.pfx -out f:\certs\zhuo.pem
?
3)签名及验签:
/*签名数据:data:utf-8编码的订单原文,privatekeyfile:私钥路径passphrase:私钥密码返回:base64转码的签名数据*/function sign($data, $privatekeyfile,$passphrase){ $signature = ''; $privatekey = openssl_pkey_get_private(file_get_contents($privatekeyfile), $passphrase); $res=openssl_get_privatekey($privatekey); openssl_sign($data, $signature, $res); openssl_free_key($res); return base64_encode($signature);}/*验证签名:data:原文signature:签名publickeypath:公钥路径返回:签名结果,true为验签成功,false为验签失败*/function verity($data, $signature, $publickeypath){ $pubkey = file_get_contents('d:/certs/test.pem'); $res = openssl_get_publickey($pubkey); $result = (bool)openssl_verify($data, base64_decode($signature), $res); openssl_free_key($res); return $result;}
?* php需要注意版本和一些包的导入,如果有报错再google了~~
?
?
?
?
?
?
该用户其它信息

VIP推荐

免费发布信息,免费发布B2B信息网站平台 - 三六零分类信息网 沪ICP备09012988号-2
企业名录 Product