2025.08.17

现在是8.17日周日晚上11:49分. 总结下这两天一直在搞的一个事情.

起因是客户那边要做密评改造. 涉及到身份认证, 数据保密性, 数据完整性, 操作不可否认性等改造.之前一直忙于其他琐事, 周四回深圳的高铁上才开始着手这件事情.

先看了下安全厂商的PPT, 讲的云里雾里;再看看群里的聊天记录, 大概明白了点; 最后看看接口文档, 算是明白到底要干啥了. 简单来说就三个东西: 一是和ukey交互,读取证书相关东西, 然后向服务器验证. 二是调用加密&解密接口对数据库中敏感数据进行加密和解密, 三是调用签名&验签接口对数据库中特定数据做摘要计算, 再把原文和摘要一起发给接口做验证. 听起来似乎挺简单.

然后就是第一个坑是要用国密算法SM3/SM4. PHP没有直接支持相关算法, 初步打算用openssl扩展来做. 查看了下服务器系统还是centos7的, PHP是7.4.3版本, 自带的openssl 版本不支持sm3/sm4算法. 只好自己升级下openssl版本, 重新编译PHP, 测试了下支持的算法.sm3/sm4可用了.

第二个坑是安全厂商只提供了JAVA的SDK, 我得自己用PHP封装一下. 好在提供了源码和测试代码.然后就是眼花缭乱的撸代码时间, 周五一天的时间总算是理解了整个过程. 难点有两个, 一是需要基于SM3的HMAC算法来签名, 二是参与签名的的参数都是怎么来的.

PHP自带的hash_hmac 貌似不支持SM3, 用hash_hmac_algos()查看了下, 确实不支持. 第一个想法是看看JAVA是怎么实现的, 撸了一个小时后我灵光一闪, 刚好试试Trae, 然后就让他帮忙把相关java类用PHP实现下. Trae整的像模像样的, 它先自己写一个类, 然后写测试代码, 测试过程有bug, 然后自己搁哪分析bug, 改bug, 继续测试,一直重复到能正常运行, 我有点被惊艳到了. 直接拿过来trae封装的PHP类测试了下, 发现输出和JAVA 不一致, 这就尴尬了, 我本身也没有研究过密码学啊, 自己去debug有点不现实.

然后github上找找其他人有没有实现过. 结果都是如何实现SM3摘要算法的. 没有和hmac结合的. 直到发现一个大佬. 大佬说:"hmac-sm3,这个算法与hmac-sha256在hmac的算法是一样的,只是hash的算法不一样,一个是sm3,一个sha256, 没有什么特殊的注意的地方", 然后还给出了具体实现. 原来如此简单! 抄过来, 测试, 和JAVA输出一致.

function myhash( $data,$digest_algo, $binary=false){
  // 这时可以是任何的hash算法,也包括了 sm3
    return openssl_digest($data, $digest_algo,$binary);
}

function hmac($key, $data, $algorithm = 'sm3')
{
    $blockSize = 64;

    if (strlen($key) > $blockSize) {
        die("please check key len");
    }

    $key = str_pad($key, $blockSize, chr(0x00));

    $innerPad = str_repeat(chr(0x36), $blockSize);
    $outerPad = str_repeat(chr(0x5C), $blockSize);

    $innerKey = $key ^ $innerPad;
    $inner = $innerKey . $data;
    $hash = myhash( $inner,$algorithm, true);

    $outerKey = $key ^ $outerPad;
    $outer = $outerKey . $hash;

    $hmac = myhash( $outer,$algorithm);

    return $hmac;
}

那么签名参数怎么来的呢, 继续撸JAVA代码. 一直到了周日上午, 感觉差不多了, 就把整个过程用PHP封装了下. 我还不想放到服务器上测试, 因为更新到服务器实在是太麻烦了. 于是想了一个偷懒的办法, 请求地址指向服务器前置机器, 前置机器proxy到内网应用服务器, 内网应用服务器再proxy到安全厂商服务器. 我就直接在本地调试. 然而认证一直失败.

这时候我有两个想法, 要么等周一问厂商具体的签名认证过程. 要么我自己跑一跑他们的java单元测试, 把参数直接打印出来. 此时已经是周日晚上了, 给娃洗漱哄睡然后自己爬起来调试, 好在之前装过eclipse, maven 也配置过, JAVA也略懂一点, 等打印出来他的参数我才发现原来是我缺少了一个换行符. OK, 改PHP, 测试, 通过. 感觉自己又长了点脑子了.

一块大石头落地, 困扰我一个周末的事情总算解决了. 剩下的就是按照文档封装几个接口的请求参数了, 周一再弄吧. 今天先记录下, 以备后查!

©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • IOS应用安全-加解密算法简述 导读客户端经常遇到需要对数据进行加密的情况,那应该如何加密,选用什么样的加密算法,...
    萝卜_7fad阅读 734评论 0 0
  • 一. 哈希算法 MD5和SHA都是用于创建唯一密钥以保护数据文件的哈希算法。从黑客的角度来看,SHA比MD5更复杂...
    Imkata阅读 286评论 0 0
  • 最近在做单片机中的国密算法测试, 基于国产单片机, 测非对称加密和对称加密 , 所以给自己一个记录哦 一般来说加密...
    whaosoft阅读 211评论 6 1
  • 概述 ​ 密码学是研究如何保护信息安全性的一门科学,涉及数学、物理、计算机、信息论、编码学、通讯技术等学科,已经在...
    卿酌南烛_b805阅读 1,762评论 0 0
  • 阿里云密钥管理服务KMS全解析,密钥管理服务KMS是阿里云针对云上数据加密需求设计的密码应用服务,为用户的应用提供...
    服务器比价阅读 120评论 0 0