需求


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


实现


php


先看下原来的php代码



此处需要注意两点:


  1. AES-128-ECB的密钥是16位


  1. 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, Python和Java的区别
PHP, Python和Java是广泛使用的编程语言。每种编程语言都有其独特的优点和缺点。在本文中,我们将对这些编程语言进行分析,并探讨它们在不同应用场景中的最佳用途。
学习了php之后再来看php怎样学java
我用了一天时间学会了php,真的。我现在已经可以流畅的用thinkphp框架开发php了。学习过程是这样的:我接了个php的项目,包括两个部分:老系统添加功能和优化,再新做一个系统。已经答应给人家做了,所以“嘣”一声,我就会了。逼上梁山,没有做不了的事。我接到活儿,白天一整天没能把环境跑通,但是我边想边联系了好几个做php的兄弟。当我自己可以将问题问题定位了,也晚上了,估计大家也都有空了。我开始有针对性的问他们问题。最后一个问题是关于nginx配置的,问了好多php大牛的兄弟都说我配置的没有问题,不知道为啥会那样。当问题没有道理
php加密函数与解密函数
Php常用的加密函数有MD5加密(不可逆)、Crypt加密(不可逆)、Sha1加密(不可逆)、Urlencode加密(可逆) base64编码加密(可逆)。
PHP 源码探秘 - 因为 Java 和 Php 在获取客户端 cookie 方式不同引发的 bug
PHP 源码探秘 - 因为 Java 和 Php 在获取客户端 cookie 方式不同引发的 bug