| 12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485 |
- <?php
- namespace common\components;
- use Yii;
- /**
- * 飞鹅云打印回调验签(SHA256WithRSA)
- * 文档:http://help.feieyun.com/#/home/doc/zh;nav=1-8
- */
- class feieyunCallbackUtil
- {
- /**
- * 飞鹅公钥文件路径
- */
- public static function getPublicKeyPath()
- {
- return Yii::getAlias('@app/web/feieyun/public.key');
- }
- /**
- * 组装待验签字符串:剔除 sign 与空值,按参数名 ASCII 升序拼接
- */
- public static function buildSignContent(array $params)
- {
- unset($params['sign']);
- $filtered = [];
- foreach ($params as $key => $value) {
- if ($value === null || $value === '') {
- continue;
- }
- $filtered[(string)$key] = (string)$value;
- }
- ksort($filtered, SORT_STRING);
- $parts = [];
- foreach ($filtered as $key => $value) {
- $parts[] = $key . '=' . $value;
- }
- return implode('&', $parts);
- }
- /**
- * 校验飞鹅回调签名
- */
- public static function verify(array $params)
- {
- $sign = trim((string)($params['sign'] ?? ''));
- if ($sign === '') {
- return false;
- }
- $publicKeyPath = self::getPublicKeyPath();
- if (!is_file($publicKeyPath)) {
- Yii::error('飞鹅公钥文件不存在: ' . $publicKeyPath, __METHOD__);
- return false;
- }
- $publicKey = file_get_contents($publicKeyPath);
- if ($publicKey === false || trim($publicKey) === '') {
- Yii::error('飞鹅公钥文件读取失败: ' . $publicKeyPath, __METHOD__);
- return false;
- }
- $signContent = self::buildSignContent($params);
- $signature = base64_decode($sign, true);
- if ($signature === false) {
- Yii::warning('飞鹅回调 sign Base64 解码失败', __METHOD__);
- return false;
- }
- $key = openssl_pkey_get_public($publicKey);
- if ($key === false) {
- Yii::error('飞鹅公钥解析失败: ' . openssl_error_string(), __METHOD__);
- return false;
- }
- $result = openssl_verify($signContent, $signature, $key, OPENSSL_ALGO_SHA256);
- if (PHP_VERSION_ID < 80000) {
- openssl_free_key($key);
- }
- return $result === 1;
- }
- }
|