• PHP DES解密 对应Java SHA1PRNG方式加密


    • 背景及问题

      背景:在和外部系统通过HTTP方式跳转时, 为保障传输参数安全性, 采用AES 加密参数. 关于对称加密中 AES, DES, CBC, ECB, PKCS5Padding 概念可参考https://blog.csdn.net/qq_35698774/article/details/78964249 

      问题:  我方技术java, 对方使用PHP.  使用同样加密算法DES, 加密模式ECB, 填充方式PKCS5Padding, 编码处理BASE64, 解密仍失败. 最终发现原因: JAVA 端加密时使用了SHA1PRNG, 通过google最终解决 , 拿来分享.

    加密代码中黄色部分是解决linux下随机生成key添加的. 正是这个代码 ,导致php解密异常.

     1 private static SecretKeySpec getSecretKey(final String key) {
     2         //返回生成指定算法密钥生成器的 KeyGenerator 对象
     3         KeyGenerator kg = null;
     4 
     5         try {
     6             kg = KeyGenerator.getInstance(KEY_ALGORITHM);
     7             //防止linux下 随机生成key
     8             SecureRandom secureRandom = SecureRandom.getInstance("SHA1PRNG");
     9             secureRandom.setSeed(key.getBytes());
    10             //DES 要求密钥长度为 56
    11             kg.init(56, secureRandom);
    12 
    13             //生成一个密钥
    14             SecretKey secretKey = kg.generateKey();
    15 
    16             return new SecretKeySpec(secretKey.getEncoded(), KEY_ALGORITHM);// 转换为DES专用密钥
    17         } catch (NoSuchAlgorithmException ex) {
    18             Logger.getLogger(DESUtils.class.getName()).log(Level.SEVERE, null, ex);
    19         }
    20 
    21         return null;
    22     }
    • 解决方法

      php 代码:

      

        /**
         * 解密
         *
         * @param $encrypted
         * @return string
         */
        public function decrypt($encrypted)
        {
            if ($this->output == self::OUTPUT_BASE64) {
                $encrypted = base64_decode($encrypted);
            } else if ($this->output == self::OUTPUT_HEX) {
                $encrypted = hex2bin($encrypted);
            }
            $key2 = substr(openssl_digest(openssl_digest($this->key, 'sha1', true), 'sha1', true), 0, 16);
            
            $sign = @openssl_decrypt($encrypted, $this->method, $key2, $this->options, $this->iv);
            $sign = $this->unPkcsPadding($sign);
            $sign = rtrim($sign);
            return $sign;
        }

        代码中,  绿色部分是解决此问题关键.

      $key2 = substr(openssl_digest(openssl_digest($this->key, 'sha1', true), 'sha1', true), 0, 16);

    • 新技能
    1. 在线PHP运行环境

        由于之前未接触php, 本地搭建php环境代价较多, 直接找在线的php环境 , 如https://www.dooccn.com/php/, 可直接运行, 并有错误调试信息, 非常方便.

    •   总结

      技术问题google 真的是靠谱,  找准搜索关键词至关重要.

    参考:

    JAVA安全与加密 https://www.jianshu.com/p/1ea4c7cb83f3

    https://www.jianshu.com/p/9591a3f59b19

    https://www.cnblogs.com/dragon16/p/7238858.html

  • 相关阅读:
    Dom-Align
    antd Dialog 学习笔记
    setState 同步 与异步
    移动端使用iframe碰到的那些坑
    谈页面上下滑动时,页面顶部导航等部分元素的定位方式发生改变
    一款table结合分页的插件
    监听页面滚动时间时所碰到的一些坑
    值得收藏的前端大牛博客
    后端时间转js时间,主要用于取倒计时
    论jquery与vuejs结合时的部分问题
  • 原文地址:https://www.cnblogs.com/qdpurple/p/10270593.html
Copyright © 2020-2023  润新知