IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> PHP知识库 -> php的openssl_encrypt改写成java版 -> 正文阅读

[PHP知识库]php的openssl_encrypt改写成java版

需求

我们之前的服务是php的,然后接下来的新功能打算用java开发,php的功能也打算后续迁移过来,然后数据库里的手机号是加密过的,所以java这边也需要按照相同的规则去加解密,下面就是过程

实现

php

先看下原来的php代码

    public static function encryptNew($plaintext)
    {
    //加密模式选择的AES-128-ECB,注意128表示密钥应该是16位的,16x8=128
        $cipher = 'AES-128-ECB';
        //此处是密钥
        $key = ENCRYPT_KEY;
        //此处进行AES-128-ECB加密
        $ciphertext_raw = openssl_encrypt($plaintext, $cipher, $key, OPENSSL_RAW_DATA);
        //得到AES-128-ECB的加密结果,继续进行sha256加密
        $hmac = hash_hmac('sha256', $ciphertext_raw, $key, true);
        //将两个加密串拼起来进行base64,得到最终结果
        $ciphertext = base64_encode($hmac . $ciphertext_raw);
        return $ciphertext;
    }

此处需要注意两点:

  1. AES-128-ECB的密钥是16位
  2. AES-128-ECB是不需要iv的

java

然后看一下对应的java代码,java用的是hutool包来做的加解密,pom引用如下:


        <dependency>
            <groupId>cn.hutool</groupId>
            <artifactId>hutool-all</artifactId>
            <version>5.7.22</version>
        </dependency>

接下来展示代码:

    /**
     * 加密啊
     * @param str 要加密的字符串
     * phpkey就是密钥=ENCRYPT_KEY的前16位
     * @return
     */
    public static String phpEcbEncryptHex(String str) {
        AES aes = new AES(Mode.ECB, Padding.PKCS5Padding, phpkey);
        byte[] encrypted = aes.encrypt(str);

        byte[] hash= new byte[0];
        try {
            hash = macSHA256(encrypted);
        } catch (NoSuchAlgorithmException e) {
            e.printStackTrace();
        } catch (InvalidKeyException e) {
            e.printStackTrace();
        }

        byte[] data3 = new byte[encrypted.length + hash.length];
        System.arraycopy(hash, 0, data3, 0, hash.length);
        System.arraycopy(encrypted, 0, data3, hash.length, encrypted.length);

        String base64Str3 = Base64.encode(data3);
        System.out.println("base 64 is "+base64Str3);
        return base64Str3;
    }
    /**
     * sha256加密
     * @param encrypted
     * @return mackey是加密的密钥=ENCRYPT_KEY
     * @throws NoSuchAlgorithmException
     * @throws InvalidKeyException
     */
    private static byte[] macSHA256(byte[] encrypted ) throws NoSuchAlgorithmException, InvalidKeyException {

        Mac sha256_HMAC = Mac.getInstance("HmacSHA256");

        SecretKeySpec secret_key = new SecretKeySpec(mackey, "HmacSHA256");

        sha256_HMAC.init(secret_key);

        //String hash = byteArrayToHexString(sha256_HMAC.doFinal(encrypted));// 重点
        byte[] hash = sha256_HMAC.doFinal(encrypted);// 重点
        System.out.println("hash is "+hash);

        return hash;
    }

遇到的问题

改写还是比较容易的,改完了之后跑了个测试发现,加密出来的结果不一样,这就搞笑了。
最终发现原因,php的使用的是32位长的密钥,但是PHP的openssl_encrypt方法,指定完method,也就是指定完加密模式之后,会直接使用对应长度的密钥,也就是就算提供的是32位的密钥,它只会使用前16位,仍然会进行AES-128-ECB加密。
而java这边,可以看到,只需要指定ECB模式,那么128还是256,是通过你使用的密钥长度来选择的,也就是说,当提供的密钥是32位时,就会进行256的加密。

  PHP知识库 最新文章
Laravel 下实现 Google 2fa 验证
UUCTF WP
DASCTF10月 web
XAMPP任意命令执行提升权限漏洞(CVE-2020-
[GYCTF2020]Easyphp
iwebsec靶场 代码执行关卡通关笔记
多个线程同步执行,多个线程依次执行,多个
php 没事记录下常用方法 (TP5.1)
php之jwt
2021-09-18
上一篇文章      下一篇文章      查看所有文章
加:2022-04-18 17:20:14  更:2022-04-18 17:20:59 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/23 7:32:41-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码