• 中宣部防沉迷系统PHP版本(管局防沉迷验证-PHP-全版本-接口测试样例)


    现在对接游戏,无论是登录还是支付都是要去对接防沉迷实名认证接口,但前期的话你要登录网络游戏防沉迷实名认证系统进行接口测试,$appid ,$bizId,$key去接口测试页面找(正式上线在密钥管理)接下来跟大家说说调试步骤:

    第一步:配置白名单

     第二步:点击接口测试,配置好你要测试的IP白名单(api服务器IP),接下来操作那一列有一个【开始测试】按钮,点击获取测试码(最好一个个接口测试)。

    第三步: 添加测试代码(thinkphp框架,Wlc类请看文章最后)

    1、testcase01-实名认证接口(认证成功),testcase02-实名认证接口(认证中),testcase03-实名认证接口(认证失败)

    测试地址:https://wlc.nppa.gov.cn/test/authentication/check/测试码

    1. // 测试防成谜(接口测试)
    2. public function checkTest()
    3. {
    4. $appid = '';
    5. $bizId = ;
    6. $key = "";
    7. $wlc = new Wlc($appid, $key, $bizId);
    8. //认证成功
    9. $body = [
    10. "ai" => '1000023000000007',
    11. "name" => '某一七',
    12. "idNum" => '110000190101030010',
    13. ];
    14. $res = $wlc->setBody($body)->check();
    15. print_r($res);
    16. }

     说明:参数按照传就行说明文档,testcase03的参数随便改错一个即可

    2、testcase04-实名认证结果查询接口(认证成功),testcase05-实名认证结果查询接口(认证中),testcase06-实名认证结果查询接口(认证失败)

    测试地址:https://wlc.nppa.gov.cn/test/authentication/query/测试码?

    1. // 测试防成谜(接口测试)
    2. public function queryTest()
    3. {
    4. $appid = '';
    5. $bizId = ;
    6. $key = "";
    7. $wlc = new Wlc($appid, $key, $bizId);
    8. //认证成功
    9. $body = [
    10. "ai" => '300000000000000002',
    11. ];
    12. $res = $wlc->setParams($body)->query();
    13. print_r($res);
    14. }

    说明:参数按照传就行说明文档,testcase06的参数随便改错一个即可

    3、 testcase07-游戏用户行为数据上报接口(游客模式),testcase08-游戏用户行为数据上报接口(已认证)

    测试地址:https://wlc.nppa.gov.cn/test/collection/loginout/测试码

    游客模式:

    1. // 测试防成谜(接口测试)
    2. public function loginoutTest()
    3. {
    4. $appid = '';
    5. $bizId = ;
    6. $key = "";
    7. $wlc = new Wlc($appid, $key, $bizId);
    8. //认证成功 (游客模式)
    9. $body =[
    10. 'collections'=>[
    11. [
    12. 'no'=>1,
    13. 'si'=>'95edkzei5exh47pk0z2twm6zpielesrd',
    14. 'bt'=>0,
    15. 'ot'=>time(),
    16. 'ct'=>2,
    17. 'di'=>'ecvndx6r6xfwofmufs3lbimcr639r33t',
    18. ]
    19. ],
    20. ];
    21. $res = $wlc->setBody($body)->loginout();
    22. print_r($res);
    23. }

    已认证模式:

    1. // 测试防成谜(接口测试)
    2. public function loginoutTest()
    3. {
    4. $appid = '';
    5. $bizId = ;
    6. $key = "";
    7. $wlc = new Wlc($appid, $key, $bizId);
    8. //认证用户测试上报
    9. $presetlist = [
    10. ['pi'=>'1fffbjzos82bs9cnyj1dna7d6d29zg4esnh99u'],
    11. ['pi'=>'1fffbkmd9ebtwi7u7f4oswm9li6twjydqs7qjv'],
    12. ];
    13. $preset = $presetlist[mt_rand(0,count($presetlist)-1)];
    14. $pi = $preset['pi'];
    15. $body =[
    16. 'collections'=>[
    17. [
    18. 'no'=>1,
    19. 'si'=>'95edkzei5exh47pk0z2twm6zpielesrd',
    20. 'bt'=>0,
    21. 'ot'=>time(),
    22. 'ct'=>0,
    23. 'di'=>'ecvndx6r6xfwofmufs3lbimcr639r33t',
    24. 'pi'=>$pi
    25. ]
    26. ],
    27. ];
    28. $res = $wlc->setBody($body)->loginout();
    29. print_r($res);
    30. }
    第四步:调试系统返回错误码

    附录:  响应参数 

    字段                  类型       名称             字段说明 

    errcode               Int       状态码             状态码 

    errmsg                String    状态描述           状态描述 

    data                  Object    响应对象          响应结果 

    data.result           Object    响应结果对象      响应结果内容 

    data.result.status    Int       实名认证结果      认证结果 0:认证成功 1:认证中  2:认证失败 

    data.result.pi       String     用户唯一标识      已通过实名认证用户的唯一标识

        

    接口返回状态码

    状态码               状态描述           状态说明 

    0                     OK                请求成功

    1001                SYS ERROR           系统错误 

    1002      SYS REQ RESOURCE NOT EXIST    接口请求的资源不存在 

    1003        SYS REQ METHOD ERROR        接口请求方式错误 

    1004      SYS REQ HEADER MISS ERROR     接口请求核心参数缺失 

    1005      SYS REQ IP ERROR              接口请求IP地址非法 

    1006      SYS REQ BUSY ERROR            接口请求超出流量限制 

    1007      SYS REQ EXPIRE ERROR          接口请求过期 

    1008      SYS REQ PARTNER ERROR         接口请求方身份非法 

    1009      SYS REQ PARTNER AUTH DISABLE  接口请求方权限未启用 

    1010        SYS REQ AUTH ERROR          接口请求方无该接口权限 

    1011      SYS REQ PARTNER AUTH ERROR    接口请求方身份核验错误 

    1012      SYS REQ PARAM CHECK ERROR     接口请求报文核验失败

    实名认证业务异常

    2001      BUS AUTH IDNUM ILLEGAL        身份证号格式校验失败 

    2002      BUS AUTH RESOURCE LIMIT       实名认证条目已达上限 

    2003      BUS AUTH CODE NO AUTH RECODE  无该编码提交的实名认证记录 

    2004      BUS AUTH CODE ALREADY IN USE  编码已经被占用

    游戏用户行为数据上报业务异常 

    3001     BUS COLL PARTIAL ERROR         行为数据部分上报失败 

    3002     BUS COLL BEHAVIOR NULL ERROR   行为数据为空 

    3003     BUS COLL OVER LIMIT COUNT      行为数据超出条目数量限制 

    3004     BUS COLL NO INVALID            行为数据编码错误 

    3005     BUS COLL BEHAVIOR TIME ERROR   行为发生时间错误 

    3006     BUS COLL PLAYER MODE INVALID   用户类型无效 

    3007     BUS COLL BEHAVIOR MODE INVALID 行为类型无效 

    3008     BUS COLL PLAYERID MISS         缺失PI(用户唯一标识)值 

    3009     BUS COLL DEVICEID MISS         缺失DI(设备标识)值 3

    010      BUS COLL PLAYERID INVALID PI (用户唯一标识)值无效

    Wlc类:(里面的地址都是正式地址)

    1. namespace app\extend\wlc;
    2. use app\extend\wlc\AESGCM;
    3. class Wlc
    4. {
    5. public $app_id;
    6. public $secret_key;
    7. public $biz_id;
    8. public $headers;
    9. public $body;
    10. public $params = [];
    11. public function __construct($app_id, $secret_key, $biz_id)
    12. {
    13. $this->app_id = $app_id;
    14. $this->secret_key = $secret_key;
    15. $this->biz_id = $biz_id;
    16. $time = $this->mtime();
    17. $this->headers = [
    18. "appId" => $this->app_id,
    19. "bizId" => $this->biz_id,
    20. "timestamps" => "$time",
    21. ];
    22. return $this;
    23. }
    24. /**
    25. * 获取毫秒
    26. * @return float
    27. */
    28. protected function mtime()
    29. {
    30. list($msec, $sec) = explode(' ', microtime());
    31. $mtime = round(round($sec . substr($msec, 2, 3)));
    32. return $mtime;
    33. }
    34. /**
    35. * 加密请求体
    36. * @param $text
    37. * @return string
    38. */
    39. protected function encrypt($text)
    40. {
    41. $key = hex2bin($this->secret_key);
    42. $cipher = "aes-128-gcm";
    43. $iv = openssl_random_pseudo_bytes(openssl_cipher_iv_length($cipher));
    44. //php7.1以上可直接使用以下代码
    45. if (version_compare(PHP_VERSION, '7.1.0') >= 0) {
    46. $encrypt = openssl_encrypt($text, $cipher, $key, OPENSSL_RAW_DATA, $iv, $tag);
    47. return base64_encode($iv . $encrypt . $tag);
    48. }
    49. //php5.6-7.0使用以下代码
    50. list($encrypt, $tag) = AESGCM::encrypt($key, $iv, $text);
    51. $str = bin2hex($iv) . bin2hex($encrypt) . bin2hex($tag);
    52. return base64_encode(hex2bin($str));
    53. }
    54. /**
    55. * 签名
    56. * @param $body
    57. * @return string
    58. */
    59. protected function sign($body)
    60. {
    61. $data = array_merge($this->headers, $this->params);
    62. ksort($data);
    63. $sign_str = '';
    64. foreach ($data as $k => $v) {
    65. $sign_str .= "{$k}{$v}";
    66. }
    67. $sign_str = $this->secret_key . $sign_str . $body;
    68. $sign = hash("sha256", $sign_str);
    69. return $sign;
    70. }
    71. /**
    72. * 发送请求
    73. * @param $url
    74. * @param $method
    75. * @param $headers
    76. * @param $body
    77. * @return mixed
    78. */
    79. protected function request($url, $method, $headers, $body)
    80. {
    81. $ch = curl_init();
    82. curl_setopt($ch, CURLOPT_URL, $url);
    83. curl_setopt($ch, CURLOPT_CUSTOMREQUEST, strtoupper($method));
    84. curl_setopt($ch, CURLOPT_POSTFIELDS, $body);
    85. curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
    86. curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE);
    87. curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, FALSE);
    88. curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
    89. curl_setopt($ch, CURLOPT_HEADER, false);
    90. curl_setopt($ch, CURLOPT_TIMEOUT, 5);
    91. $response = curl_exec($ch);
    92. curl_close($ch);
    93. unset($ch);
    94. return json_decode($response, true);
    95. }
    96. /**
    97. * 设置url 请求参数
    98. * @param $params
    99. * @return $this
    100. */
    101. public function setParams($params)
    102. {
    103. $this->params = $params;
    104. return $this;
    105. }
    106. /**
    107. * 设置请求体
    108. * @param $body
    109. * @return $this
    110. */
    111. public function setBody($body)
    112. {
    113. $this->body = $body;
    114. return $this;
    115. }
    116. public function check()
    117. {
    118. $url = "https://api.wlc.nppa.gov.cn/idcard/authentication/check";
    119. //加密请求体
    120. $body = json_encode([
    121. "data" => $this->encrypt(json_encode($this->body, JSON_UNESCAPED_UNICODE)),
    122. ]);
    123. //签名
    124. $sign = $this->sign($body);
    125. $headers[] = "sign:$sign";
    126. $headers[] = "Content-Type:application/json; charset=utf-8";
    127. foreach ($this->headers as $k => $v) {
    128. $headers[] = "{$k}:{$v}";
    129. }
    130. return $this->request($url, "POST", $headers, $body);
    131. }
    132. public function query()
    133. {
    134. $url = "http://api2.wlc.nppa.gov.cn/idcard/authentication/query";
    135. //设置url参数
    136. $params = '';
    137. if (!empty($this->params)) {
    138. $params = http_build_query($this->params);
    139. $url .= "?$params";
    140. }
    141. $body = '';
    142. $sign = $this->sign($body);
    143. $headers[] = "sign:$sign";
    144. foreach ($this->headers as $k => $v) {
    145. $headers[] = "{$k}:{$v}";
    146. }
    147. return $this->request($url, "GET", $headers, $body);
    148. }
    149. public function loginout()
    150. {
    151. $url = "http://api2.wlc.nppa.gov.cn/behavior/collection/loginout";
    152. //加密请求体
    153. $body = json_encode([
    154. "data" => $this->encrypt(json_encode($this->body, JSON_UNESCAPED_UNICODE)),
    155. ]);
    156. //签名
    157. $sign = $this->sign($body);
    158. $headers[] = "sign:$sign";
    159. $headers[] = "Content-Type:application/json; charset=utf-8";
    160. foreach ($this->headers as $k => $v) {
    161. $headers[] = "{$k}:{$v}";
    162. }
    163. return $this->request($url, "POST", $headers, $body);
    164. }
    165. }
    AESGCM类:
    1. /*
    2. * https://github.com/Spomky-Labs/php-aes-gcm
    3. * 从以上gitub项目提取的单文件
    4. */
    5. namespace app\extend\wlc;
    6. class AESGCM
    7. {
    8. /**
    9. * @param string $K Key encryption key
    10. * @param string $IV Initialization vector
    11. * @param null|string $P Data to encrypt (null for authentication)
    12. * @param null|string $A Additional Authentication Data
    13. * @param int $tag_length Tag length
    14. *
    15. * @return array
    16. */
    17. public static function encrypt($K, $IV, $P = null, $A = null, $tag_length = 128)
    18. {
    19. $key_length = mb_strlen($K, '8bit') * 8;
    20. if (version_compare(PHP_VERSION, '7.1.0RC5') >= 0 && null !== $P) {
    21. return self::encryptWithPHP71($K, $key_length, $IV, $P, $A, $tag_length);
    22. } elseif (class_exists('\Crypto\Cipher')) {
    23. return self::encryptWithCryptoExtension($K, $key_length, $IV, $P, $A, $tag_length);
    24. }
    25. return self::encryptWithPHP($K, $key_length, $IV, $P, $A, $tag_length);
    26. }
    27. /**
    28. * This method will append the tag at the end of the ciphertext.
    29. *
    30. * @param string $K Key encryption key
    31. * @param string $IV Initialization vector
    32. * @param null|string $P Data to encrypt (null for authentication)
    33. * @param null|string $A Additional Authentication Data
    34. * @param int $tag_length Tag length
    35. *
    36. * @return string
    37. */
    38. public static function encryptAndAppendTag($K, $IV, $P = null, $A = null, $tag_length = 128)
    39. {
    40. return implode(self::encrypt($K, $IV, $P, $A, $tag_length));
    41. }
    42. /**
    43. * @param string $K Key encryption key
    44. * @param string $key_length Key length
    45. * @param string $IV Initialization vector
    46. * @param null|string $P Data to encrypt (null for authentication)
    47. * @param null|string $A Additional Authentication Data
    48. * @param int $tag_length Tag length
    49. *
    50. * @return array
    51. */
    52. private static function encryptWithPHP71($K, $key_length, $IV, $P = null, $A = null, $tag_length = 128)
    53. {
    54. $mode = 'aes-'.($key_length).'-gcm';
    55. $T = null;
    56. $C = openssl_encrypt($P, $mode, $K, OPENSSL_RAW_DATA, $IV, $T, $A, $tag_length / 8);
    57. return [$C, $T];
    58. }
    59. /**
    60. * @param string $K Key encryption key
    61. * @param string $key_length Key length
    62. * @param string $IV Initialization vector
    63. * @param null|string $P Data to encrypt (null for authentication)
    64. * @param null|string $A Additional Authentication Data
    65. * @param int $tag_length Tag length
    66. *
    67. * @return array
    68. */
    69. private static function encryptWithPHP($K, $key_length, $IV, $P = null, $A = null, $tag_length = 128)
    70. {
    71. list($J0, $v, $a_len_padding, $H) = self::common($K, $key_length, $IV, $A);
    72. $C = self::getGCTR($K, $key_length, self::getInc(32, $J0), $P);
    73. $u = self::calcVector($C);
    74. $c_len_padding = self::addPadding($C);
    75. $S = self::getHash($H, $A.str_pad('', $v / 8, "\0").$C.str_pad('', $u / 8, "\0").$a_len_padding.$c_len_padding);
    76. $T = self::getMSB($tag_length, self::getGCTR($K, $key_length, $J0, $S));
    77. return [$C, $T];
    78. }
    79. /**
    80. * @param string $K Key encryption key
    81. * @param string $key_length Key length
    82. * @param string $IV Initialization vector
    83. * @param null|string $P Data to encrypt (null for authentication)
    84. * @param null|string $A Additional Authentication Data
    85. * @param int $tag_length Tag length
    86. *
    87. * @return array
    88. */
    89. private static function encryptWithCryptoExtension($K, $key_length, $IV, $P = null, $A = null, $tag_length = 128)
    90. {
    91. $cipher = \Crypto\Cipher::aes(\Crypto\Cipher::MODE_GCM, $key_length);
    92. $cipher->setAAD($A);
    93. $cipher->setTagLength($tag_length / 8);
    94. $C = $cipher->encrypt($P, $K, $IV);
    95. $T = $cipher->getTag();
    96. return [$C, $T];
    97. }
    98. /**
    99. * @param string $K Key encryption key
    100. * @param string $IV Initialization vector
    101. * @param string|null $C Data to encrypt (null for authentication)
    102. * @param string|null $A Additional Authentication Data
    103. * @param string $T Tag
    104. *
    105. * @return string
    106. */
    107. public static function decrypt($K, $IV, $C, $A, $T)
    108. {
    109. $key_length = mb_strlen($K, '8bit') * 8;
    110. $tag_length = self::getLength($T);
    111. if (version_compare(PHP_VERSION, '7.1.0RC5') >= 0 && null !== $C) {
    112. return self::decryptWithPHP71($K, $key_length, $IV, $C, $A, $T);
    113. } elseif (class_exists('\Crypto\Cipher')) {
    114. return self::decryptWithCryptoExtension($K, $key_length, $IV, $C, $A, $T, $tag_length);
    115. }
    116. return self::decryptWithPHP($K, $key_length, $IV, $C, $A, $T, $tag_length);
    117. }
    118. /**
    119. * This method should be used if the tag is appended at the end of the ciphertext.
    120. * It is used by some AES GCM implementations such as the Java one.
    121. *
    122. * @param string $K Key encryption key
    123. * @param string $IV Initialization vector
    124. * @param string|null $Ciphertext Data to encrypt (null for authentication)
    125. * @param string|null $A Additional Authentication Data
    126. * @param int $tag_length Tag length
    127. *
    128. * @return string
    129. *
    130. * @see self::encryptAndAppendTag
    131. */
    132. public static function decryptWithAppendedTag($K, $IV, $Ciphertext = null, $A = null, $tag_length = 128)
    133. {
    134. $tag_length_in_bits = $tag_length / 8;
    135. $C = mb_substr($Ciphertext, 0, -$tag_length_in_bits, '8bit');
    136. $T = mb_substr($Ciphertext, -$tag_length_in_bits, null, '8bit');
    137. return self::decrypt($K, $IV, $C, $A, $T);
    138. }
    139. /**
    140. * @param string $K Key encryption key
    141. * @param string $key_length Key length
    142. * @param string $IV Initialization vector
    143. * @param string|null $C Data to encrypt (null for authentication)
    144. * @param string|null $A Additional Authentication Data
    145. * @param string $T Tag
    146. *
    147. * @return string
    148. */
    149. private static function decryptWithPHP71($K, $key_length, $IV, $C, $A, $T)
    150. {
    151. $mode = 'aes-'.($key_length).'-gcm';
    152. $P = openssl_decrypt(null === $C ? '' : $C, $mode, $K, OPENSSL_RAW_DATA, $IV, $T, null === $A ? '' : $A);
    153. return $P;
    154. }
    155. /**
    156. * @param string $K Key encryption key
    157. * @param string $key_length Key length
    158. * @param string $IV Initialization vector
    159. * @param string|null $C Data to encrypt (null for authentication)
    160. * @param string|null $A Additional Authentication Data
    161. * @param string $T Tag
    162. * @param int $tag_length Tag length
    163. *
    164. * @return string
    165. */
    166. private static function decryptWithPHP($K, $key_length, $IV, $C, $A, $T, $tag_length = 128)
    167. {
    168. list($J0, $v, $a_len_padding, $H) = self::common($K, $key_length, $IV, $A);
    169. $P = self::getGCTR($K, $key_length, self::getInc(32, $J0), $C);
    170. $u = self::calcVector($C);
    171. $c_len_padding = self::addPadding($C);
    172. $S = self::getHash($H, $A.str_pad('', $v / 8, "\0").$C.str_pad('', $u / 8, "\0").$a_len_padding.$c_len_padding);
    173. $T1 = self::getMSB($tag_length, self::getGCTR($K, $key_length, $J0, $S));
    174. return $P;
    175. }
    176. /**
    177. * @param string $K Key encryption key
    178. * @param string $key_length Key length
    179. * @param string $IV Initialization vector
    180. * @param string|null $C Data to encrypt (null for authentication)
    181. * @param string|null $A Additional Authentication Data
    182. * @param string $T Tag
    183. * @param int $tag_length Tag length
    184. *
    185. * @return string
    186. */
    187. private static function decryptWithCryptoExtension($K, $key_length, $IV, $C, $A, $T, $tag_length = 128)
    188. {
    189. $cipher = \Crypto\Cipher::aes(\Crypto\Cipher::MODE_GCM, $key_length);
    190. $cipher->setTag($T);
    191. $cipher->setAAD($A);
    192. $cipher->setTagLength($tag_length / 8);
    193. return $cipher->decrypt($C, $K, $IV);
    194. }
    195. /**
    196. * @param $K
    197. * @param $key_length
    198. * @param $IV
    199. * @param $A
    200. *
    201. * @return array
    202. */
    203. private static function common($K, $key_length, $IV, $A)
    204. {
    205. $H = openssl_encrypt(str_repeat("\0", 16), 'aes-'.($key_length).'-ecb', $K, OPENSSL_NO_PADDING | OPENSSL_RAW_DATA); //---
    206. $iv_len = self::getLength($IV);
    207. if (96 === $iv_len) {
    208. $J0 = $IV.pack('H*', '00000001');
    209. } else {
    210. $s = self::calcVector($IV);
    211. $packed_iv_len = pack('N', $iv_len);
    212. $iv_len_padding = str_pad($packed_iv_len, 8, "\0", STR_PAD_LEFT);
    213. $hash_X = $IV.str_pad('', ($s + 64) / 8, "\0").$iv_len_padding;
    214. $J0 = self::getHash($H, $hash_X);
    215. }
    216. $v = self::calcVector($A);
    217. $a_len_padding = self::addPadding($A);
    218. return [$J0, $v, $a_len_padding, $H];
    219. }
    220. /**
    221. * @param string $value
    222. *
    223. * @return int
    224. */
    225. private static function calcVector($value)
    226. {
    227. return (128 * ceil(self::getLength($value) / 128)) - self::getLength($value);
    228. }
    229. /**
    230. * @param string $value
    231. *
    232. * @return string
    233. */
    234. private static function addPadding($value)
    235. {
    236. return str_pad(pack('N', self::getLength($value)), 8, "\0", STR_PAD_LEFT);
    237. }
    238. /**
    239. * @param string $x
    240. *
    241. * @return int
    242. */
    243. private static function getLength($x)
    244. {
    245. return mb_strlen($x, '8bit') * 8;
    246. }
    247. /**
    248. * @param int $num_bits
    249. * @param int $x
    250. *
    251. * @return string
    252. */
    253. private static function getMSB($num_bits, $x)
    254. {
    255. $num_bytes = $num_bits / 8;
    256. return mb_substr($x, 0, $num_bytes, '8bit');
    257. }
    258. /**
    259. * @param int $num_bits
    260. * @param int $x
    261. *
    262. * @return string
    263. */
    264. private static function getLSB($num_bits, $x)
    265. {
    266. $num_bytes = ($num_bits / 8);
    267. return mb_substr($x, -$num_bytes, null, '8bit');
    268. }
    269. /**
    270. * @param int $s_bits
    271. * @param int $x
    272. *
    273. * @return string
    274. */
    275. private static function getInc($s_bits, $x)
    276. {
    277. $lsb = self::getLSB($s_bits, $x);
    278. $X = self::toUInt32Bits($lsb) + 1;
    279. $res = self::getMSB(self::getLength($x) - $s_bits, $x).pack('N', $X);
    280. return $res;
    281. }
    282. /**
    283. * @param string $bin
    284. *
    285. * @return mixed
    286. */
    287. private static function toUInt32Bits($bin)
    288. {
    289. list(, $h, $l) = unpack('n*', $bin);
    290. return $l + ($h * 0x010000);
    291. }
    292. /**
    293. * @param $X
    294. * @param $Y
    295. *
    296. * @return string
    297. */
    298. private static function getProduct($X, $Y)
    299. {
    300. $R = pack('H*', 'E1').str_pad('', 15, "\0");
    301. $Z = str_pad('', 16, "\0");
    302. $V = $Y;
    303. $parts = str_split($X, 4);
    304. $x = sprintf('%032b%032b%032b%032b', self::toUInt32Bits($parts[0]), self::toUInt32Bits($parts[1]), self::toUInt32Bits($parts[2]), self::toUInt32Bits($parts[3]));
    305. $lsb_mask = "\1";
    306. for ($i = 0; $i < 128; $i++) {
    307. if ($x[$i]) {
    308. $Z = self::getBitXor($Z, $V);
    309. }
    310. $lsb_8 = mb_substr($V, -1, null, '8bit');
    311. if (ord($lsb_8 & $lsb_mask)) {
    312. $V = self::getBitXor(self::shiftStringToRight($V), $R);
    313. } else {
    314. $V = self::shiftStringToRight($V);
    315. }
    316. }
    317. return $Z;
    318. }
    319. /**
    320. * @param string $input
    321. *
    322. * @return string
    323. */
    324. private static function shiftStringToRight($input)
    325. {
    326. $width = 4;
    327. $parts = array_map('self::toUInt32Bits', str_split($input, $width));
    328. $runs = count($parts);
    329. for ($i = $runs - 1; $i >= 0; $i--) {
    330. if ($i) {
    331. $lsb1 = $parts[$i - 1] & 0x00000001;
    332. if ($lsb1) {
    333. $parts[$i] = ($parts[$i] >> 1) | 0x80000000;
    334. $parts[$i] = pack('N', $parts[$i]);
    335. continue;
    336. }
    337. }
    338. $parts[$i] = ($parts[$i] >> 1) & 0x7FFFFFFF;
    339. $parts[$i] = pack('N', $parts[$i]);
    340. }
    341. $res = implode('', $parts);
    342. return $res;
    343. }
    344. /**
    345. * @param string $H
    346. * @param string $X
    347. *
    348. * @return mixed
    349. */
    350. private static function getHash($H, $X)
    351. {
    352. $Y = [];
    353. $Y[0] = str_pad('', 16, "\0");
    354. $num_blocks = (int) (mb_strlen($X, '8bit') / 16);
    355. for ($i = 1; $i <= $num_blocks; $i++) {
    356. $Y[$i] = self::getProduct(self::getBitXor($Y[$i - 1], mb_substr($X, ($i - 1) * 16, 16, '8bit')), $H);
    357. }
    358. return $Y[$num_blocks];
    359. }
    360. /**
    361. * @param string $K
    362. * @param int $key_length
    363. * @param string $ICB
    364. * @param string $X
    365. *
    366. * @return string
    367. */
    368. private static function getGCTR($K, $key_length, $ICB, $X)
    369. {
    370. if (empty($X)) {
    371. return '';
    372. }
    373. $n = (int) ceil(self::getLength($X) / 128);
    374. $CB = [];
    375. $Y = [];
    376. $CB[1] = $ICB;
    377. for ($i = 2; $i <= $n; $i++) {
    378. $CB[$i] = self::getInc(32, $CB[$i - 1]);
    379. }
    380. $mode = 'aes-'.($key_length).'-ecb';
    381. for ($i = 1; $i < $n; $i++) {
    382. $C = openssl_encrypt($CB[$i], $mode, $K, OPENSSL_NO_PADDING | OPENSSL_RAW_DATA);
    383. $Y[$i] = self::getBitXor(mb_substr($X, ($i - 1) * 16, 16, '8bit'), $C);
    384. }
    385. $Xn = mb_substr($X, ($n - 1) * 16, null, '8bit');
    386. $C = openssl_encrypt($CB[$n], $mode, $K, OPENSSL_NO_PADDING | OPENSSL_RAW_DATA);
    387. $Y[$n] = self::getBitXor($Xn, self::getMSB(self::getLength($Xn), $C));
    388. return implode('', $Y);
    389. }
    390. /**
    391. * @param string $o1
    392. * @param string $o2
    393. *
    394. * @return string
    395. */
    396. private static function getBitXor($o1, $o2)
    397. {
    398. $xorWidth = PHP_INT_SIZE;
    399. $o1 = str_split($o1, $xorWidth);
    400. $o2 = str_split($o2, $xorWidth);
    401. $res = '';
    402. $runs = count($o1);
    403. for ($i = 0; $i < $runs; $i++) {
    404. $res .= $o1[$i] ^ $o2[$i];
    405. }
    406. return $res;
    407. }
    408. }

    特别说明:如果你复制过去调试不行,请下载样例自己再去封装一下就行了

  • 相关阅读:
    pytorch数据增强
    curlpp(curl C++) http错误码和重定向后的url获取
    护网蓝队/红队面试题汇总
    携手走过四年,极智嘉(Geek+)赋能上海西门子开关智慧物流升级
    [问题]springboot启动时报Could not connect to SMTP host
    工程师新红利,我国预计到2025年培养20万名这类人才
    arm汇编求最大公约数
    2024年最新阿里云和腾讯云云服务器价格租用对比
    ③. GPT错误:python控制台运行pip list列出安装库,列出:pip install 库1 库2库3...,方便一次性安装错误
    Golang实现遍历切片时根据条件移除元素
  • 原文地址:https://blog.csdn.net/weixin_39801446/article/details/136629523