YopSignUtils.php 5.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213
  1. <?php
  2. namespace app\common\modules\yop\sdk\Util;
  3. use app\common\modules\yop\sdk\Util\Base64Url;
  4. use app\common\modules\yop\sdk\Util\AESEncrypter;
  5. /**
  6. * Created by PhpStorm.
  7. * User: wilson
  8. * Date: 16/7/7
  9. * Time: 17:33
  10. */
  11. abstract class YopSignUtils{
  12. /**
  13. * 签名生成算法
  14. * @param array $params API调用的请求参数集合的关联数组,不包含sign参数
  15. * @param array $ignoreParamNames 忽略的参数数组
  16. * @param String $secret 密钥
  17. * @param String $algName 加密算法
  18. *
  19. md2
  20. md4
  21. md5
  22. sha1
  23. sha256
  24. sha384
  25. sha512
  26. ripemd128
  27. ripemd160
  28. ripemd256
  29. ripemd320
  30. whirlpool
  31. *
  32. * @return string 返回参数签名值
  33. */
  34. static function sign($params, $ignoreParamNames='', $secret, $algName='sha1'){
  35. $str = ''; //待签名字符串
  36. //先将参数以其参数名的字典序升序进行排序
  37. $requestparams = $params;
  38. ksort($requestparams);
  39. //遍历排序后的参数数组中的每一个key/value对
  40. foreach ($requestparams as $k => $v) {
  41. //查看Key 是否为忽略参数
  42. if(!in_array($k,$ignoreParamNames)){
  43. //为key/value对生成一个keyvalue格式的字符串,并拼接到待签名字符串后面
  44. //value不为空,则进行加密
  45. if(!empty($v)){
  46. $str .= "$k$v";
  47. }
  48. }
  49. }
  50. //将签名密钥拼接到签名字符串两头
  51. $str = $secret.$str.$secret;
  52. //通过指定算法生成sing
  53. return hash($algName,$str);
  54. }
  55. /**
  56. * 签名验证算法
  57. * @param array $result API调用的请求参数集合的关联数组,不包含sign参数
  58. * @param String $secret 密钥
  59. * @param String $algName 加密算法
  60. * @param String $sign 签名值
  61. * @return string 返回签名是否正确 0 - 如果两个字符串相等
  62. */
  63. static function isValidResult($result, $secret, $algName,$sign){
  64. $newString = $secret.$result.$secret;
  65. if(strcasecmp($sign,hash($algName,$newString))==0){
  66. return true;
  67. }else{
  68. return false;
  69. }
  70. }
  71. static function verifySign($source,$sign, $public_Key)
  72. {
  73. $content=strstr($source, '&sign', TRUE);
  74. $public_key = "-----BEGIN PUBLIC KEY-----\n" .
  75. wordwrap($public_Key, 64, "\n", true) .
  76. "\n-----END PUBLIC KEY-----";
  77. $publicKey = openssl_pkey_get_public($public_key);
  78. $res = openssl_verify($content,Base64Url::decode($sign), $public_key,'SHA256'); //验证
  79. openssl_free_key($publicKey);
  80. //输出验证结果,1:验证成功,0:验证失败
  81. if ($res == 1) {
  82. return true;
  83. } else {
  84. Die("verifySign fail!");
  85. }
  86. }
  87. static function decrypt($source,$private_Key, $public_Key)
  88. {
  89. $private_key = "-----BEGIN RSA PRIVATE KEY-----\n" .
  90. wordwrap($private_Key, 64, "\n", true) .
  91. "\n-----END RSA PRIVATE KEY-----";
  92. extension_loaded('openssl') or die('php需要openssl扩展支持');
  93. /* 提取私钥 */
  94. $privateKey = openssl_get_privatekey($private_key);
  95. ($privateKey) or die('密钥不可用');
  96. //分解参数
  97. $args = explode('$', $source);
  98. if (count($args) != 4) {
  99. die('source invalid : ');
  100. }
  101. $encryptedRandomKeyToBase64 = $args[0];
  102. $encryptedDataToBase64 = $args[1];
  103. $symmetricEncryptAlg = $args[2];
  104. $digestAlg = $args[3];
  105. //用私钥对随机密钥进行解密
  106. openssl_private_decrypt(Base64Url::decode($encryptedRandomKeyToBase64), $randomKey, $privateKey);
  107. openssl_free_key($privateKey);
  108. $encryptedData = openssl_decrypt(Base64Url::decode($encryptedDataToBase64), "AES-128-ECB", $randomKey, OPENSSL_RAW_DATA);
  109. //分解参数
  110. $signToBase64=substr(strrchr($encryptedData,'$'),1);
  111. $sourceData = substr($encryptedData,0,strlen($encryptedData)-strlen($signToBase64)-1);
  112. $public_key = "-----BEGIN PUBLIC KEY-----\n" .
  113. wordwrap($public_Key, 64, "\n", true) .
  114. "\n-----END PUBLIC KEY-----";
  115. $publicKey = openssl_pkey_get_public($public_key);
  116. $res = openssl_verify($sourceData,Base64Url::decode($signToBase64), $publicKey,$digestAlg); //验证
  117. openssl_free_key($publicKey);
  118. //输出验证结果,1:验证成功,0:验证失败
  119. if ($res == 1) {
  120. return $sourceData;
  121. } else {
  122. Die("verifySign fail!");
  123. }
  124. }
  125. static function signRsa($source,$private_Key)
  126. {
  127. $private_key = "-----BEGIN RSA PRIVATE KEY-----\n" .
  128. wordwrap($private_Key, 64, "\n", true) .
  129. "\n-----END RSA PRIVATE KEY-----";
  130. extension_loaded('openssl') or die('php需要openssl扩展支持');
  131. /* 提取私钥 */
  132. $privateKey = openssl_get_privatekey($private_key);
  133. ($privateKey) or die('密钥不可用');
  134. openssl_sign($source, $encode_data, $privateKey, "SHA256");
  135. openssl_free_key($privateKey);
  136. $signToBase64 = Base64Url::encode($encode_data);
  137. $signToBase64 .= '$SHA256';
  138. return $signToBase64;
  139. }
  140. /* static function getPrivateKey($filepath,$password)
  141. {
  142. $pkcs12 = file_get_contents($filepath);
  143. openssl_pkcs12_read($pkcs12, $certs, $password);
  144. $prikeyid = $certs['pkey']; //私钥
  145. $prikeyid = str_replace('-----BEGIN RSA PRIVATE KEY-----','',$prikeyid);
  146. $prikeyid = str_replace('-----END RSA PRIVATE KEY-----','',$prikeyid);
  147. $prikeyid = preg_replace("/(\r\n|\n|\r|\t)/i", '', $prikeyid);
  148. return $prikeyid;
  149. }*/
  150. }