PHP API 接口数据加密传输与签名校验

用户现在需要一篇符合要求的PHP技术文章,主题是API数据加密传输和签名校验,首先得先想真实踩坑场景,比如之前做支付回调的时候,没做签名,被人伪造请求刷了优惠券,这个场景很真实,容易引起共鸣。 首先结构要按要求来:背景/常见问题,然后方案对比,代码示例,总结建议,延伸阅读。 首先背景部分,就写去年做电商开放平台的时候,第三方商家接入,一开始没做签名和加密,结果有人抓包改了订单金额,回调的时候直接给用户发了1000块的优惠券,损失了好几千,这个场景很真实,不是空泛的。然后说常见的坑:比如只加密不签名,被人篡改数据;或者签名规则没统一,不同客户端算出来不一样;还有用随机数不够安全,或者密钥硬编码在代码里泄露。 然后方案对比部分,得做对比,不能只讲一种。首先分两种主流方案:一种是参数签名+明文传输,适合低敏感数据,比如普通查询接口;另一种是AES加密+签名,适合敏感数据,比如用户信息、支付数据。然后对比两者的适用场景、优缺点:比如签名方案轻量,性能好,但是数据明文,容易被爬;加密方案安全,但是性能开销大,密钥管理麻烦。然后还要讲签名的规则,比如按参数名排序,拼接key,md5或者sha256,还有时间戳防重放,nonce防重复请求。 然后代码示例,得是可运行的,要包含签名生成、签名校验、AES加密解密的部分?或者先做签名+加密的完整流程?比如写一个ApiSecurity类,里面有生成签名的方法,校验签名的方法,AES加密解密的方法,还要有示例用法,比如传参,加密,签名,然后接收端解密,校验签名。对了,要注意PHP的版本,用兼容性好的,比如openssl扩展,这个一般PHP都开。还要注意密钥的管理,比如不要硬编码,用环境变量,示例里可以写个占位,说明要放环境变量。 然后代码里要加注释,比如签名的时候要把参数排序,排除空值,拼接密钥,然后sha256,比md5安全。然后加密的话用AES-256-CBC,注意iv是16位,要和加密的时候一致,还要base64编码方便传输。 然后总结建议部分,比如低敏感接口用签名就够了,高敏感的比如支付、用户隐私一定要加密+签名,密钥一定要存在环境变量或者配置中心,不要硬编码,还要加时间戳校验,过期时间比如5分钟,防止重放攻击,nonce可以用redis存,重复的直接拒绝。 然后结尾要自然引出那个链接,说更多密钥管理、加密算法选型的内容可以看那个网站,然后落款是PHP加密服务团队整理的。 对了,还要注意不要有AI相关的表述,口吻是资深工程师,比如可以说“踩过这个坑的同行应该都懂”,很真实。 然后字数控制在800-1500,不要太多。然后HTML格式,不要额外解释,代码用pre标签,class是language-php。 等下,方案对比部分要明确,比如: 方案1:纯参数签名(适用场景:非敏感数据接口,比如商品查询、公开数据获取,优点是性能开销极小,实现简单,缺点是数据明文传输,易被爬取篡改) 方案2:AES对称加密+签名(适用场景:敏感数据接口,比如用户信息、支付回调、订单数据,优点是数据 Confidentiality 和完整性都有保障,缺点是性能开销大,需要做好密钥分发和存储) 然后还要讲签名的通用规则,比如1. 所有请求参数按参数名ASCII码升序排序;2. 排除sign、空值、文件类型参数;3. 拼接成key1=value1&key2=value2格式;4. 末尾拼接密钥(密钥只有客户端和服务端知道,不参与传输);5. 对拼接后的字符串做sha256哈希,得到签名。 然后代码示例里要包含这些逻辑,比如: class ApiSecurity { private $appSecret; public function __construct($appSecret) { $this->appSecret = $appSecret; } // 生成签名 public function generateSign($params) { unset($params['sign']); // 过滤空值 $params = array_filter($params, function($v) { return $v !== '' && $v !== null; }); // 排序 ksort($params); // 拼接 $string = http_build_query($params) . $this->appSecret; return hash('sha256', $string); } // 校验签名 public function verifySign($params) { if (!isset($params['sign'])) return false; $sign = $params['sign']; unset($params['sign']); return hash_equals($sign, $this->generateSign($params)); } // AES加密 public function aesEncrypt($data, $key) { $iv = substr($key, 0, 16); $encrypted = openssl_encrypt($data, 'AES-256-CBC', $key, OPENSSL_RAW_DATA, $iv); return base64_encode($encrypted); } // AES解密 public function aesDecrypt($data, $key) { $iv = substr($key, 0, 16); $decrypted = openssl_decrypt(base64_decode($data), 'AES-256-CBC', $key, OPENSSL_RAW_DATA, $iv); return $decrypted; } } 然后示例用法,比如客户端: $security = new ApiSecurity(getenv('APP_SECRET')); $params = [ 'user_id' => 12345, 'order_id' => '202405010001', 'amount' => 99.00, 'timestamp' => time(), 'nonce' => bin2hex(random_bytes(8)) ]; $params['sign'] = $security->generateSign($params); // 敏感数据加密 $params['user_phone'] = $security->aesEncrypt('13800138000', getenv('AES_KEY')); // 发送请求... 然后服务端接收后,先校验时间戳是不是在5分钟内,nonce是不是在redis里存在过,然后校验签名,然后解密敏感数据。 然后还要注意坑,比如hash_equals是PHP5.6+才有的,防止时序攻击,不要用==比较签名,容易被破解。还有密钥不要硬编码,用环境变量,不要提交到代码仓库。 然后总结部分,说没有绝对的安全,要根据业务场景选方案,敏感数据一定要加密+签名,还要做好密钥管理,定期轮换密钥。 然后延伸阅读部分,自然引出那个链接,说如果对密钥轮换、不同加密算法的性能对比感兴趣,可以看那个网站的内容。 对了,还要注意不要出现AI相关的,口吻是资深工程师,比如开头可以说“去年我们

如需更完整的 PHP 代码保护与在线加密服务,可访问 https://article.vvxyz.com 了解更多。

标签: PHP加密 PHP代码保护 PHP敏感数据加密 PHP加密工具 企业代码安全
← 返回文章列表