关于RSA原理
RSA加密是一种非对称加密。可以在不直接传递密钥的情况下,完成解密。这能够确保信息的安全性,避免了直接传递密钥所造成的被破解的风险。是由一对密钥来进行加解密的过程,分别称为公钥和私钥。两者之间有数学相关,该加密算法的原理就是对一极大整数做因数分解的困难性来保证安全性。通常个人保存私钥,公钥是公开的(可能同时多人持有)。
RSA可以用于加密解密和签名验证。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 |
using Org.BouncyCastle.Crypto; using Org.BouncyCastle.Crypto.Parameters; using Org.BouncyCastle.OpenSsl; using Org.BouncyCastle.Security; using System; using System.IO; using System.Security.Cryptography; using System.Security.Cryptography.X509Certificates; namespace CommonUtils { public static class RsaUtil { #region 加载私钥 /// <summary> /// 转换私钥字符串为RSACryptoServiceProvider /// </summary> /// <param name="privateKeyStr">私钥字符串</param> /// <param name="keyFormat">PKCS8,PKCS1</param> /// <param name="signType">RSA 私钥长度1024 ,RSA2 私钥长度2048</param> /// <returns></returns> public static RSACryptoServiceProvider LoadPrivateKey(string privateKeyStr, string keyFormat) { string signType = "RSA"; if (privateKeyStr.Length > 1024) { signType = "RSA2"; } //PKCS8,PKCS1 if (keyFormat == "PKCS1") { return LoadPrivateKeyPKCS1(privateKeyStr, signType); } else { return LoadPrivateKeyPKCS8(privateKeyStr); } } /// <summary> /// PKCS1 格式私钥转 RSACryptoServiceProvider 对象 /// </summary> /// <param name="strKey">pcsk1 私钥的文本内容</param> /// <param name="signType">RSA 私钥长度1024 ,RSA2 私钥长度2048 </param> /// <returns></returns> public static RSACryptoServiceProvider LoadPrivateKeyPKCS1(string privateKeyPemPkcs1, string signType) { try { privateKeyPemPkcs1 = privateKeyPemPkcs1.Replace("-----BEGIN RSA PRIVATE KEY-----", "").Replace("-----END RSA PRIVATE KEY-----", "").Replace("\r", "").Replace("\n", "").Trim(); privateKeyPemPkcs1 = privateKeyPemPkcs1.Replace("-----BEGIN PRIVATE KEY-----", "").Replace("-----END PRIVATE KEY-----", "").Replace("\r", "").Replace("\n", "").Trim(); byte[] data = null; //读取带 data = Convert.FromBase64String(privateKeyPemPkcs1); RSACryptoServiceProvider rsa = DecodeRSAPrivateKey(data, signType); return rsa; } catch (Exception ex) { throw ex; } return null; } private static RSACryptoServiceProvider DecodeRSAPrivateKey(byte[] privkey, string signType) { 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; int bitLen = 1024; if ("RSA2".Equals(signType)) { bitLen = 2048; } RSACryptoServiceProvider RSA = new RSACryptoServiceProvider(bitLen, CspParameters); //RSACryptoServiceProvider RSA = new RSACryptoServiceProvider(); 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) { throw ex; // return null; } finally { binr.Close(); } } private static 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; } /// <summary> /// PKCS8 文本转RSACryptoServiceProvider 对象 /// </summary> /// <param name="privateKeyPemPkcs8"></param> /// <returns></returns> public static RSACryptoServiceProvider LoadPrivateKeyPKCS8(string privateKeyPemPkcs8) { try { //PKCS8是“BEGIN PRIVATE KEY” privateKeyPemPkcs8 = privateKeyPemPkcs8.Replace("-----BEGIN RSA PRIVATE KEY-----", "").Replace("-----END RSA PRIVATE KEY-----", "").Replace("\r", "").Replace("\n", "").Trim(); privateKeyPemPkcs8 = privateKeyPemPkcs8.Replace("-----BEGIN PRIVATE KEY-----", "").Replace("-----END PRIVATE KEY-----", "").Replace("\r", "").Replace("\n", "").Trim(); //pkcs8 文本先转为 .NET XML 私钥字符串 string privateKeyXml = RSAPrivateKeyJava2DotNet(privateKeyPemPkcs8); RSACryptoServiceProvider publicRsa = new RSACryptoServiceProvider(); publicRsa.FromXmlString(privateKeyXml); return publicRsa; } catch (Exception ex) { throw ex; } } /// <summary> /// PKCS8 私钥文本 转 .NET XML 私钥文本 /// </summary> /// <param name="privateKeyPemPkcs8"></param> /// <returns></returns> public static string RSAPrivateKeyJava2DotNet(string privateKeyPemPkcs8) { RsaPrivateCrtKeyParameters privateKeyParam = (RsaPrivateCrtKeyParameters)PrivateKeyFactory.CreateKey(Convert.FromBase64String(privateKeyPemPkcs8)); return string.Format("<RSAKeyValue><Modulus>{0}</Modulus><Exponent>{1}</Exponent><P>{2}</P><Q>{3}</Q><DP>{4}</DP><DQ>{5}</DQ><InverseQ>{6}</InverseQ><D>{7}</D></RSAKeyValue>", Convert.ToBase64String(privateKeyParam.Modulus.ToByteArrayUnsigned()), Convert.ToBase64String(privateKeyParam.PublicExponent.ToByteArrayUnsigned()), Convert.ToBase64String(privateKeyParam.P.ToByteArrayUnsigned()), Convert.ToBase64String(privateKeyParam.Q.ToByteArrayUnsigned()), Convert.ToBase64String(privateKeyParam.DP.ToByteArrayUnsigned()), Convert.ToBase64String(privateKeyParam.DQ.ToByteArrayUnsigned()), Convert.ToBase64String(privateKeyParam.QInv.ToByteArrayUnsigned()), Convert.ToBase64String(privateKeyParam.Exponent.ToByteArrayUnsigned())); } #endregion /// <summary> /// 加载公钥证书 /// </summary> /// <param name="publicKeyCert">公钥证书文本内容</param> /// <returns></returns> public static RSACryptoServiceProvider LoadPublicCert(string publicKeyCert) { publicKeyCert = publicKeyCert.Replace("-----BEGIN CERTIFICATE-----", "").Replace("-----END CERTIFICATE-----", "").Replace("\r", "").Replace("\n", "").Trim(); byte[] bytesCerContent = Convert.FromBase64String(publicKeyCert); X509Certificate2 x509 = new X509Certificate2(bytesCerContent); RSACryptoServiceProvider rsaPub = (RSACryptoServiceProvider)x509.PublicKey.Key; return rsaPub; } /// <summary> /// pem 公钥文本 转 .NET RSACryptoServiceProvider。 /// </summary> /// <param name="publicKeyPem"></param> /// <returns></returns> public static RSACryptoServiceProvider LoadPublicKey(string publicKeyPem) { publicKeyPem = publicKeyPem.Replace("-----BEGIN PUBLIC KEY-----", "").Replace("-----END PUBLIC KEY-----", "").Replace("\r", "").Replace("\n", "").Trim(); //pem 公钥文本 转 .NET XML 公钥文本。 string publicKeyXml = RSAPublicKeyJava2DotNet(publicKeyPem); RSACryptoServiceProvider publicRsa = new RSACryptoServiceProvider(); publicRsa.FromXmlString(publicKeyXml); return publicRsa; } /// <summary> /// pem 公钥文本 转 .NET XML 公钥文本。 /// </summary> /// <param name="publicKey"></param> /// <returns></returns> private static string RSAPublicKeyJava2DotNet(string publicKey) { RsaKeyParameters publicKeyParam = (RsaKeyParameters)PublicKeyFactory.CreateKey(Convert.FromBase64String(publicKey)); return string.Format("<RSAKeyValue><Modulus>{0}</Modulus><Exponent>{1}</Exponent></RSAKeyValue>", Convert.ToBase64String(publicKeyParam.Modulus.ToByteArrayUnsigned()), Convert.ToBase64String(publicKeyParam.Exponent.ToByteArrayUnsigned())); } } } |
另一个文件
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 |
using Org.BouncyCastle.Crypto; using Org.BouncyCastle.Crypto.Parameters; using Org.BouncyCastle.Security; using System; using System.Security.Cryptography; using System.Text; namespace CommonUtils { public static class RsaEncryptUtil { /// <summary> /// 私钥加密 .Net平台默认是使用公钥进行加密,私钥进行解密。私钥加密需要自己实现或者使用第三方dll /// </summary> /// <param name="data"></param> /// <param name="key">私钥,格式:PKCS8</param> /// <returns></returns> public static byte[] encryptByPrivateKey(String data, String key) { String priKey = key.Trim(); String xmlPrivateKey = RSAPrivateKeyJava2DotNet(priKey); //加载私钥 RSACryptoServiceProvider privateRsa = new RSACryptoServiceProvider(); privateRsa.FromXmlString(xmlPrivateKey); //转换密钥 AsymmetricCipherKeyPair keyPair = DotNetUtilities.GetKeyPair(privateRsa); IBufferedCipher c = CipherUtilities.GetCipher("RSA/ECB/PKCS1Padding");// 参数与Java中加密解密的参数一致 c.Init(true, keyPair.Private); //第一个参数为true表示加密,为false表示解密;第二个参数表示密钥 byte[] DataToEncrypt = Encoding.UTF8.GetBytes(data); byte[] outBytes = c.DoFinal(DataToEncrypt);//加密 return outBytes; } /// <summary> /// 私钥加密 /// </summary> /// <param name="data">明文</param> /// <param name="key">私钥</param> /// <param name="keyFormat">私钥格式:PKCS1,PKCS8</param> /// <returns></returns> public static byte[] encryptByPrivateKey(String data, String key, string keyFormat) { String priKey = key.Trim(); //加载私钥 RSACryptoServiceProvider privateRsa = RsaUtil.LoadPrivateKey(key, keyFormat); //转换密钥 AsymmetricCipherKeyPair keyPair = DotNetUtilities.GetKeyPair(privateRsa); IBufferedCipher c = CipherUtilities.GetCipher("RSA/ECB/PKCS1Padding");// 参数与Java中加密解密的参数一致 c.Init(true, keyPair.Private); //第一个参数为true表示加密,为false表示解密;第二个参数表示密钥 byte[] DataToEncrypt = Encoding.UTF8.GetBytes(data); byte[] outBytes = c.DoFinal(DataToEncrypt);//加密 return outBytes; } /// <summary> /// 用私钥加密数据,并返回base64字符串 /// </summary> /// <param name="data"></param> /// <param name="privateKey"></param> /// <param name="publicKey"></param> /// <returns></returns> public static string encryptByPrivateKeyBase64(String data, String privateKey, string publicKey) { var byteArry = encryptByPrivateKey(data, privateKey, publicKey); return Convert.ToBase64String(byteArry); } /// <summary> /// RSA私钥格式转换,java->.net /// </summary> /// <param name="privateKey"></param> /// <returns></returns> private static string RSAPrivateKeyJava2DotNet(string privateKey) { RsaPrivateCrtKeyParameters privateKeyParam = (RsaPrivateCrtKeyParameters)PrivateKeyFactory.CreateKey(Convert.FromBase64String(privateKey)); return string.Format("<RSAKeyValue><Modulus>{0}</Modulus><Exponent>{1}</Exponent><P>{2}</P><Q>{3}</Q><DP>{4}</DP><DQ>{5}</DQ><InverseQ>{6}</InverseQ><D>{7}</D></RSAKeyValue>", Convert.ToBase64String(privateKeyParam.Modulus.ToByteArrayUnsigned()), Convert.ToBase64String(privateKeyParam.PublicExponent.ToByteArrayUnsigned()), Convert.ToBase64String(privateKeyParam.P.ToByteArrayUnsigned()), Convert.ToBase64String(privateKeyParam.Q.ToByteArrayUnsigned()), Convert.ToBase64String(privateKeyParam.DP.ToByteArrayUnsigned()), Convert.ToBase64String(privateKeyParam.DQ.ToByteArrayUnsigned()), Convert.ToBase64String(privateKeyParam.QInv.ToByteArrayUnsigned()), Convert.ToBase64String(privateKeyParam.Exponent.ToByteArrayUnsigned())); } /// <summary> /// 用公钥解密 /// </summary> /// <param name="data"></param> /// <param name="key"></param> /// <returns></returns> public static byte[] decryptByPublicKey(String data, String key) { String pubKey = key.Trim(); String xmlPublicKey = RSAPublicKeyJava2DotNet(pubKey); RSACryptoServiceProvider publicRsa = new RSACryptoServiceProvider(); publicRsa.FromXmlString(xmlPublicKey); AsymmetricKeyParameter keyPair = DotNetUtilities.GetRsaPublicKey(publicRsa); //转换密钥 // AsymmetricCipherKeyPair keyPair = DotNetUtilities.GetRsaKeyPair(publicRsa); IBufferedCipher c = CipherUtilities.GetCipher("RSA/ECB/PKCS1Padding");// 参数与Java中加密解密的参数一致 c.Init(false, keyPair); //第一个参数为true表示加密,为false表示解密;第二个参数表示密钥 byte[] DataToEncrypt = Convert.FromBase64String(data); byte[] outBytes = c.DoFinal(DataToEncrypt);//解密 return outBytes; } /// <summary> /// RSA公钥格式转换,java->.net /// </summary> /// <param name="publicKey"></param> /// <returns></returns> private static string RSAPublicKeyJava2DotNet(string publicKey) { RsaKeyParameters publicKeyParam = (RsaKeyParameters)PublicKeyFactory.CreateKey(Convert.FromBase64String(publicKey)); return string.Format("<RSAKeyValue><Modulus>{0}</Modulus><Exponent>{1}</Exponent></RSAKeyValue>", Convert.ToBase64String(publicKeyParam.Modulus.ToByteArrayUnsigned()), Convert.ToBase64String(publicKeyParam.Exponent.ToByteArrayUnsigned())); } /// <summary> /// 用私钥签名数据 /// </summary> /// <param name="data">数据</param> /// <param name="privateKey">私钥</param> /// <param name="publicKey">公钥</param> /// <returns></returns> public static string SignData(string data,string privateKey,string publicKey) { RSACryptoServiceProvider privateRsa = RsaUtil.LoadPrivateKey(privateKey, publicKey); string Result = Convert.ToBase64String(privateRsa.SignData(UTF8Encoding.UTF8.GetBytes(data), HashAlgorithmName.SHA256, RSASignaturePadding.Pkcs1)); return Result; } } } |
使用实例:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
//前端传送过来的参数,json数据 string data = "{\"user_no\":\"1333333\",\"mobile\":\"12300006633\",\"number\":\"2\"}"; //客户私钥 string privateKey = "HWUoXK6.../JOZRRtMTUFQ==";//为了安全这里省略了实际密钥 //客户公钥 string publicKey = "MIIBIjANBg.....XxBFWwIDAQAB";//为了安全这里省略了实际密钥 //以下两个参数data和sign值用于调用API接口 // //json数据进行私钥加密,此数据为API接口中data参数值 var encryptData = RsaEncryptUtil.encryptByPrivateKeyBase64(data, privateKey, publicKey); ViewBag.Data = encryptData; //拼接客户key和data加密数据,然后进行签名,生成sign参数值 string signStr = "key=test&data=" + encryptData; //签名结果字符串 var sign = RsaEncryptUtil.SignData(signStr, privateKey, publicKey); ViewBag.Sign = sign; |
php私钥加密公钥解密工具类参考代码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 |
<?php /** * RSA签名类 */ class Rsa { public $publicKey = ''; public $privateKey = ''; /** * private key */ private $_privKey; /** * public key */ private $_pubKey; /** * the construtor,the param $path is the keys saving path * @param string $publicKey 公钥 * @param string $privateKey 私钥 */ public function __construct($publicKey = null, $privateKey = null) { $this->setKey($publicKey, $privateKey); } /** * 设置公钥和私钥 * @param string $publicKey 公钥 * @param string $privateKey 私钥 */ public function setKey($publicKey = null, $privateKey = null) { if (!is_null($publicKey)) { $this->publicKey = $publicKey; } if (!is_null($privateKey)) { $this->privateKey = $privateKey; } } /** * setup the private key */ private function setupPrivKey() { if (is_resource($this->_privKey)) { return true; } $pem = chunk_split($this->privateKey, 64, "\n"); $pem = "-----BEGIN PRIVATE KEY-----\n" . $pem . "-----END PRIVATE KEY-----\n"; $this->_privKey = openssl_pkey_get_private($pem); return true; } /** * setup the public key */ private function setupPubKey() { if (is_resource($this->_pubKey)) { return true; } $pem = chunk_split($this->publicKey, 64, "\n"); $pem = "-----BEGIN PUBLIC KEY-----\n" . $pem . "-----END PUBLIC KEY-----\n"; $this->_pubKey = openssl_pkey_get_public($pem); return true; } /** * encrypt with the private key */ public function privEncrypt($data, $json = false) { if ($json) { $data = json_encode($data); } if (!is_string($data)) { return null; } $this->setupPrivKey(); $encrypted = ''; $r = true; foreach (str_split($data, 245) as $chunk) { $r = $r && openssl_private_encrypt($chunk, $tmp, $this->_privKey); $encrypted .= $tmp; } /* echo "ok:<br>"; echo $encrypted; echo "<br>"; */ if ($r) { return base64_encode($encrypted); } return null; } /** * decrypt with the private key */ public function privDecrypt($encrypted, $json = false) { if (!is_string($encrypted)) { return null; } $this->setupPrivKey(); $encrypted = base64_decode($encrypted); $decrypted = ''; $r = true; foreach (str_split($encrypted, 256) as $chunk) { $r = $r && openssl_private_decrypt($chunk, $tmp, $this->_privKey); $decrypted .= $tmp; } if ($r) { if ($json) { $decrypted = json_decode($decrypted, true); } return $decrypted; } return null; } /** * encrypt with public key */ public function pubEncrypt($data, $json = false) { if ($json) { $data = json_encode($data); } if (!is_string($data)) { return null; } $this->setupPubKey(); $encrypted = ''; $r = true; foreach (str_split($data, 245) as $chunk) { $r = $r && openssl_public_encrypt($chunk, $tmp, $this->_pubKey); $encrypted .= $tmp; } if ($r) { return base64_encode($encrypted); } return null; } /** * decrypt with the public key */ public function pubDecrypt($crypted, $json = false) { if (!is_string($crypted)) { return null; } $this->setupPubKey(); $crypted = base64_decode($crypted); $decrypted = ''; $r = true; foreach (str_split($crypted, 256) as $chunk) { $r = $r && openssl_public_decrypt($chunk, $tmp, $this->_pubKey); $decrypted .= $tmp; } if ($r) { if ($json) { $decrypted = json_decode($decrypted, true); } return $decrypted; } return null; } public function getSignContent($params) { ksort($params); unset($params['sign']); $stringToBeSigned = ""; $i = 0; foreach ($params as $k => $v) { if ("@" != substr($v, 0, 1)) { if ($i == 0) { $stringToBeSigned .= "$k" . "=" . "$v"; } else { $stringToBeSigned .= "&" . "$k" . "=" . "$v"; } $i++; } } unset ($k, $v); return $stringToBeSigned; } /** * 构造签名 * @param array $params 被签名数据 * @return string */ public function sign($params) { $this->setupPrivKey(); $signature = false; $dataString = $this->getSignContent($params); openssl_sign($dataString, $signature, $this->_privKey, OPENSSL_ALGO_SHA256); return base64_encode($signature); } /** * 验证签名 * @param array $params 被签名数据 * @param string $signString 已经签名的字符串 * @return number 1签名正确 0签名错误 */ public function verify($params, $signString) { $this->setupPubKey(); $dataString = $this->getSignContent($params); $signature = base64_decode($signString); $flg = openssl_verify($dataString, $signature, $this->_pubKey, OPENSSL_ALGO_SHA256); return $flg; } public function __destruct() { is_resource($this->_privKey) && @openssl_free_key($this->_privKey); is_resource($this->_pubKey) && @openssl_free_key($this->_pubKey); } } |
发表评论