美文网首页
php使用sm3加解密笔记!

php使用sm3加解密笔记!

作者: DragonersLi | 来源:发表于2021-09-16 18:33 被阅读0次

客户在平台申请产品后,跳转第三方填写信息。第三方审核通过后,返回给平台数据是用sm3加密的。无法关联到自己平台上的数据。所以根据申请时间把自己平台该产品申请数据字段加密去匹配。

用sm3加密自己平台该产品对应字段

        Db::name('records')
            ->where('product_id=632')
            ->field('id,name,mobile,idcard')
            ->chunk(1000,function($item) {
                foreach($item as $k=>$v){ 
                 Db::connect('mongo')->table('xyk')->insert([
                         'id'=>$v['id'],
                         'name'=>$v['name'],
                         'sm3_name'=>(new Sm3Service)->sign($v['name']),
                         'mobile'=>$v['mobile'],
                         'sm3_mobile'=>(new Sm3Service)->sign($v['mobile']),
                         'idcard'=>$v['IDcard'],
                         'sm3_idcard'=>(new Sm3Service)->sign($v['idcard'])
                         ]);
                }
            },'id');

根据第三方返回的sm3加密字段去匹配

$where[] =[
'sm3_name'=>"063bf224585385ce8886a7ba7703fc56703ca2907b9bba5dca143ef34a654705",
'sm3_idcard'=>"1aace674c1d51af434cd554b3162e002ddaace4c33b6066b8762c4e19540cceb",
'sm3_mobile'=>"5f517e5ed365008c898979d9052b220d519355f84f695c32204a8e843478c4e6"
];
        foreach($where as $k=>$v){
            $res = Db::connect('mongo')->table('records')->where($v)->find();
            if(!empty($res)){
               echo  $msg ="申请aid: {$res['aid']}  姓名name:{$res['name']}   手机号mobile:{$res['mobile']}  身份证idcard:{$res['idcard']}  sm3_name:{$res['sm3_name']}  sm3_mobile:{$res['sm3_mobile']}  sm3_idcard:{$res['sm3_idcard']}\n";

            }

        }

sm3加密封装类:

<?php

namespace app\common\service;

class Sm3Service
{
    private $IV      = '7380166f4914b2b9172442d7da8a0600a96f30bc163138aae38dee4db0fb0e4e';
    private $LEN     = 512;
    private $STR_LEN = 64;

    public function sign($str)
    {
        $l   = strlen($str) * 8;
        $k   = $this->getK($l);
        $bt  = $this->getB($k);
        $str = $str . $bt . pack('J', $l);

        $count = strlen($str);
        $l     = $count / $this->STR_LEN;
        $vr    = hex2bin($this->IV);
        for ($i = 0; $i < $l; $i++) {
            $vr = $this->cf($vr, substr($str, $i * $this->STR_LEN, $this->STR_LEN));
        }
        return bin2hex($vr);

    }

    private function getK($l)
    {
        $v = $l % $this->LEN;
        return $v + $this->STR_LEN < $this->LEN
            ? $this->LEN - $this->STR_LEN - $v - 1
            : ($this->LEN * 2) - $this->STR_LEN - $v - 1;
    }

    private function getB($k)
    {
        $arg = [128];
        $arg = array_merge($arg, array_fill(0, intval($k / 8), 0));
        return pack('C*', ...$arg);
    }

    public function signFile($file)
    {
        $l  = filesize($file) * 8;
        $k  = $this->getK($l);
        $bt = $this->getB($k) . pack('J', $l);

        $hd  = fopen($file, 'r');
        $vr  = hex2bin($this->IV);
        $str = fread($hd, $this->STR_LEN);
        if ($l > $this->LEN - $this->STR_LEN - 1) {
            do {
                $vr  = $this->cf($vr, $str);
                $str = fread($hd, $this->STR_LEN);
            } while (!feof($hd));
        }

        $str   = $str . $bt;
        $count = strlen($str) * 8;
        $l     = $count / $this->LEN;
        for ($i = 0; $i < $l; $i++) {
            $vr = $this->cf($vr, substr($str, $i * $this->STR_LEN, $this->STR_LEN));
        }
        return bin2hex($vr);
    }


    private function t($i)
    {
        return $i < 16 ? 0x79cc4519 : 0x7a879d8a;
    }

    private function cf($ai, $bi)
    {
        $wr = array_values(unpack('N*', $bi));
        for ($i = 16; $i < 68; $i++) {
            $wr[$i] = $this->p1($wr[$i - 16]
                    ^
                    $wr[$i - 9]
                    ^
                    $this->lm($wr[$i - 3], 15))
                ^
                $this->lm($wr[$i - 13], 7)
                ^
                $wr[$i - 6];
        }
        $wr1 = [];
        for ($i = 0; $i < 64; $i++) {
            $wr1[] = $wr[$i] ^ $wr[$i + 4];
        }

        list($a, $b, $c, $d, $e, $f, $g, $h) = array_values(unpack('N*', $ai));

        for ($i = 0; $i < 64; $i++) {
            $ss1 = $this->lm(
                ($this->lm($a, 12) + $e + $this->lm($this->t($i), $i % 32) & 0xffffffff),
                7);
            $ss2 = $ss1 ^ $this->lm($a, 12);
            $tt1 = ($this->ff($i, $a, $b, $c) + $d + $ss2 + $wr1[$i]) & 0xffffffff;
            $tt2 = ($this->gg($i, $e, $f, $g) + $h + $ss1 + $wr[$i]) & 0xffffffff;
            $d   = $c;
            $c   = $this->lm($b, 9);
            $b   = $a;
            $a   = $tt1;
            $h   = $g;
            $g   = $this->lm($f, 19);
            $f   = $e;
            $e   = $this->p0($tt2);
        }

        return pack('N*', $a, $b, $c, $d, $e, $f, $g, $h) ^ $ai;
    }


    private function ff($j, $x, $y, $z)
    {
        return $j < 16 ? $x ^ $y ^ $z : ($x & $y) | ($x & $z) | ($y & $z);
    }

    private function gg($j, $x, $y, $z)
    {
        return $j < 16 ? $x ^ $y ^ $z : ($x & $y) | (~$x & $z);
    }


    private function lm($a, $n)
    {
        return ($a >> (32 - $n) | (($a << $n) & 0xffffffff));
    }

    private function p0($x)
    {
        return $x ^ $this->lm($x, 9) ^ $this->lm($x, 17);
    }

    private function p1($x)
    {
        return $x ^ $this->lm($x, 15) ^ $this->lm($x, 23);
    }

}

相关文章

网友评论

      本文标题:php使用sm3加解密笔记!

      本文链接:https://www.haomeiwen.com/subject/yhizrxtx.html