首页 > 编程语言 >记录一下 php解密java的问题

记录一下 php解密java的问题

时间:2023-01-09 17:25:54浏览次数:81  
标签:java substr 解密 c3 cipher 64 encryptData c2 php

使用大佬的:https://github.com/lpilp/phpsm2sm3sm4
php版本国密

意见问题:在判断椭圆点的时候x,y报错。

发现java部分的问题在于
/***分解加密字串
* (C1 = C1标志位2位 + C1实体部分128位 = 130)
* (C3 = C3实体部分64位 = 64)
* (C2 = encryptedData.length * 2 - C1长度 - C2长度)
*/

 if (data == null || data.length == 0)
        {
            return null;
        }
         
        byte[] source = new byte[data.length];
        System.arraycopy(data, 0, source, 0, data.length);
         
        Cipher cipher = new Cipher();
        SM2 sm2 = SM2.Instance();
        ECPoint userKey = sm2.ecc_curve.decodePoint(Util.hexToByte(pubk));
         
        ECPoint c1 = cipher.Init_enc(sm2, userKey);
        cipher.Encrypt(source);
        byte[] c3 = new byte[32];
        cipher.Dofinal(c3);
         
        //C1 C2 C3拼装成加密字串
      //使用BC库/也有可能是Hutool工具库进行sm2加密后的密文,前两位也是04标志位,而其进行解密的时候也必须有该标志位。
        return Util.byteToHex(c1.getEncoded()) + Util.byteToHex(source) + Util.byteToHex(c3);

java解密重要代码

 byte[] c1Bytes = Util.hexToByte(data.substring(0,130));
        int c2Len = encryptedData.length - 97;
        byte[] c2 = Util.hexToByte(data.substring(130,130 + 2 * c2Len));
        byte[] c3 = Util.hexToByte(data.substring(130 + 2 * c2Len,194 + 2 * c2Len));
         
        SM2 sm2 = SM2.Instance();
        BigInteger userD = new BigInteger(1, privateKey);
         
        //通过C1实体字节来生成ECPoint
        ECPoint c1 = sm2.ecc_curve.decodePoint(c1Bytes);
        Cipher cipher = new Cipher();
        cipher.Init_dec(userD, c1);
        cipher.Decrypt(c2);
        cipher.Dofinal(c3);

因为bc库自带的标志位,经过发现咋计算检查椭圆点的时候,位数对不上了,找不到,就报错了,截取掉04(解密里面根据trim来控制,默认就好)


 public function doDecrypt($encryptData, $privateKey, $trim = true, $model = C1C3C2)
    {

        // $encryptData = $c1.$c3.$c2
        if (substr($encryptData, 0, 2) == '04' && $trim) {
            $encryptData = substr($encryptData, 2);
        }


        if (strlen($privateKey) == 66 && substr($privateKey, 0, 2) == '00') {
            $privateKey = substr($privateKey, 2); // 个别的key 前面带着00
        }

        $c1 = substr($encryptData, 0, 128); 
        $c3 = substr($encryptData, -64);
        $c2 = substr($encryptData, 128, strlen($encryptData) - 128 - 64);

        $encryptData = $c1 . $c3 . $c2;




        $adapter = $this->adapter;
        $generator = $this->generator;
        $this->cipher = new \Rtgm\smecc\SM2\Cipher();
        $c1X = substr($encryptData, 0, 64);

        $c1Y = substr($encryptData, strlen($c1X), 64);

        $c1Length = strlen($c1X) + strlen($c1Y);

        if ($model == C1C3C2) {
            $c3 = substr($encryptData, $c1Length, 64);

            $c2 = substr($encryptData, $c1Length + strlen($c3));
        } else {
            $c3 = substr($encryptData, -64);
            $c2 = substr($encryptData, $c1Length, strlen($encryptData) - $c1Length - 64);
        }

        $p1 = new Point($adapter, $generator->getCurve(), gmp_init($c1X, 16), gmp_init($c1Y, 16));


        $this->cipher->initDecipher($p1, $privateKey);

        $arrMsg = Hex2ByteBuf::HexStringToByteArray2($c2);
        $arrMsg = $this->cipher->decryptBlock($arrMsg);
        $document = hex2bin(Hex2ByteBuf::ByteArrayToHexString($arrMsg));


        $c3_ = strtolower(Hex2ByteBuf::ByteArrayToHexString($this->cipher->Dofinal()));
        $c3 = strtolower($c3);
        if ($c3 == $c3_) { //hash签名相同,
            return $document;
        } else {
            return '';
        }
    }

标签:java,substr,解密,c3,cipher,64,encryptData,c2,php
From: https://www.cnblogs.com/mengluo/p/17037616.html

相关文章

  • JavaScript项目榜单
    JavaScript项目榜单参考资料2022年最受欢迎的JavaScript项目榜单出炉BestofJS正式公布2022年JavaScript明星项目榜单该榜单提供了过去12个月JavaScript生态......
  • Docker构建镜像时,报错:manifest for java:8-jdk-alpine not found: manifest unknown
     今天在用Docker构建镜像时,突然提示构建失败,错误信息如下:错误:manifestforjava:8notfound:manifestunknown:manifestunknown 经查原来是Docker官网弃用了Java......
  • Java中this和super
    Java中this和super的用法总结thisthis是自身的一个对象,代表对象本身,可以理解为:指向对象本身的一个指针。this的用法在Java中大体可以分为3种:1.普通的直接引用......
  • Java中的instanceof关键字
    instanceof是Java的一个二元操作符,和==,>,<是同一类东东。由于它是由字母组成的,所以也是Java的保留关键字。它的作用是测试它左边的对象是否是它右边的类的实例,返回boolean类......
  • Java注解
    @Override-检查该方法是否是重写方法。如果发现其父类,或者是引用的接口中并没有该方法时,会报编译错误。@Deprecated-标记过时方法。如果使用该方法,会报编译警告。@S......
  • Java面向对象
    面向过程&面向对象一、什么是面向对象二、类与对象的关系三、创建与初始化对象NEW关键字的作用:1.实例化初始对象2.内存开辟一个空间3.把等号右边开好的......
  • Java基础学习05
    通过一道简单的算法题找路问题总结一下一些小结论。问题:在迷宫中找到一条通路并计算长度(2023-01-09)解法:首先利用二维数组创建迷宫,创建一个类,调用类中的方法实现问题解决,方......
  • VsCode里面运行mvn命令显示The JAVA_HOME environment variable is not defined corre
    问题描述关于这个问题,就是环境配置出了问题!!!问题解决在settings.json里面,配置的环境的路径不能出错,我就是在配置的时候,名为Environments的文件夹写成Environment了,才......
  • java SSL加密传输
    网络传输是存在风险的,因此对服服务端和客户端进行安全校验和传输信息的加密就显得非常的重要。上面一句有点拗口,简单解释如下文: 当客户使用SSL向站点服务器发送请求时......
  • Java工作流详解(附6大工作流框架对比)​
    ​目录​1.什么是工作流​2.工作流应用场景​3.工作流实现方式​4.有哪些工作流框架?​5.1.Activiti6.2.Flowable7.3.Camunda8.4.jBPM9.5.osworkflow,6.jflow.​10.工作流......