• php base64_decode与java base64解密结果不匹配问题


    1.正常的字符串base64加密后,php和java都可以正常解析

    例如:

    原文:

    this is a test
    

    java代码:

    String test = "this is a test";
    System.out.println(new String(java.util.Base64.getEncoder().encode(test.getBytes())));
    System.out.println(org.apache.commons.codec.binary.Base64.encodeBase64String(test.getBytes()));
    

    java代码结果:

    dGhpcyBpcyBhIHRlc3Q=
    dGhpcyBpcyBhIHRlc3Q=
    

    php代码:

    <?php
            echo base64_encode('this is a test')."\n";
    ?>
    

    php代码结果:

    dGhpcyBpcyBhIHRlc3Q=
    

    解析过程就不再列举了,解析结果都是可以还原原字符串。

    2.特殊字符串(非base64加密的字符串结果)进行base64 decode解析结果不同

    场景:公司某个业务的手机号php系统加密算法传输(涉及到base64加密),对端java系统进行解密(涉及到base64解密)

    加密流程暂不列举,直接列举base64解密结果

    加密原文:

    MzMdWpavMBd+FBUoJWmdQeaqV5J1z57zXLKAn6NWtGhL1ygVtA
    

    php代码:

    <?php
            $string = base64_decode('MzMdWpavMBd+FBUoJWmdQeaqV5J1z57zXLKAn6NWtGhL1ygVtA');
            echo $string."\n";
            echo strlen($string)."\n";
    ?>
    

    php代码结果:

    33Z��0~(%i�A��W�uϞ�\����V�hK�(�
    37
    

    java代码:

    String test = "MzMdWpavMBd+FBUoJWmdQeaqV5J1z57zXLKAn6NWtGhL1ygVtA";
    String result1 = new String(java.util.Base64.getDecoder().decode(test.getBytes()));
    System.out.println(result1);
    System.out.println(result1.length());
    String result2 = new String(org.apache.commons.codec.binary.Base64.decodeBase64(test));
    System.out.println(result2);
    System.out.println(result2.length());
    

    java代码结果:

    33Z��0~(%i�A�W�uϞ�\����V�hK�(�
    35
    33Z��0~(%i�A�W�uϞ�\����V�hK�(�
    35
    

    很明显,php解密的结果文本和字符串长度都与java不同

    java解决问题:

    1.查看解密后字节长度

    java代码:

    String test = "MzMdWpavMBd+FBUoJWmdQeaqV5J1z57zXLKAn6NWtGhL1ygVtA";
    byte[] result1 = java.util.Base64.getDecoder().decode(test.getBytes());
    System.out.println(result1.length);
    byte[] result2 = org.apache.commons.codec.binary.Base64.decodeBase64(test);
    System.out.println(result2.length);
    

    java代码结果:

    37
    37
    

    结论:字节长度相符,所以最终得到的字符串,并不是通过new String()生成。

    2.查看php解密后ASCII码与java字节码的对比

    php代码:

    <?php
            $string = base64_decode('MzMdWpavMBd+FBUoJWmdQeaqV5J1z57zXLKAn6NWtGhL1ygVtA');
            for($i = 0; $i < strlen($string); $i++) {
                echo ord($string[$i])." ";
            }
    ?>
    

    php代码结果:

    51 51 29 90 150 175 48 23 126 20 21 40 37 105 157 65 230 170 87 146 117 207 158 243 92 178 128 159 163 86 180 104 75 215 40 21 180
    

    java代码:

    String test = "MzMdWpavMBd+FBUoJWmdQeaqV5J1z57zXLKAn6NWtGhL1ygVtA";
    byte[] result1 = java.util.Base64.getDecoder().decode(test.getBytes());
    for (int i = 0; i < result1.length; i++) {
        System.out.print(result1[i] + " ");
    }
    System.out.println();
    byte[] result2 = org.apache.commons.codec.binary.Base64.decodeBase64(test);
    for (int i = 0; i < result2.length; i++) {
        System.out.print(result2[i] + " ");
    }
    

    java代码结果:

    51 51 29 90 -106 -81 48 23 126 20 21 40 37 105 -99 65 -26 -86 87 -110 117 -49 -98 -13 92 -78 -128 -97 -93 86 -76 104 75 -41 40 21 -76
    51 51 29 90 -106 -81 48 23 126 20 21 40 37 105 -99 65 -26 -86 87 -110 117 -49 -98 -13 92 -78 -128 -97 -93 86 -76 104 75 -41 40 21 -76
    

    对比后发现:

    java的负数字节码与php的字节码结果相差256

    ok,修改java解密逻辑,新增256的计算

    java代码:

    String test = "MzMdWpavMBd+FBUoJWmdQeaqV5J1z57zXLKAn6NWtGhL1ygVtA";
    byte[] result1 = java.util.Base64.getDecoder().decode(test.getBytes());
    StringBuffer sb1 = new StringBuffer();
    for (int i = 0; i < result1.length; i++) {
        if (result1[i] > 0) {
            sb1.append((char) result1[i]);
        } else {
            sb1.append((char) (result1[i] + 256));
        }
    }
    System.out.println(sb1.toString());
    System.out.println(sb1.length());
    byte[] result2 = org.apache.commons.codec.binary.Base64.decodeBase64(test);
    StringBuffer sb2 = new StringBuffer();
    for (int i = 0; i < result2.length; i++) {
        if (result2[i] > 0) {
            sb2.append((char) result2[i]);
        } else {
            sb2.append((char) (result2[i] + 256));
        }
    }
    System.out.println(sb2.toString());
    System.out.println(sb2.length());
    
    String str3 = new String(result1, java.nio.charset.StandardCharsets.ISO_8859_1);
    System.out.println(str3);
    System.out.println(str3.length());
    

    java代码结果:

    33Z¯0~(%iAæªWuÏó\²£V´hK×(´
    37
    33Z¯0~(%iAæªWuÏó\²£V´hK×(´
    37
    33Z¯0~(%iAæªWuÏó\²£V´hK×(´
    37
    

    3.结论

    1.非base64加密的标准数据,通过base64解码,php和java结果字符串不同

    2.java获取base64解码的字节数组,长度与php解码长度一致,字节数字为正数,与php的ASCII码一致,负数的话,与php的ASCII码相差256;

    3.也可以通过ISO_8859_1编码,获取到长度一致的字符串,遍历字符串每个char的int值,也是与php的ASCII码相同

    4.不同的第三方jar解析base64,结果是一样的

    5.长度和ASCII码都与php相同时,得到的字符串与php也不相同,暂时不知道什么原因

  • 相关阅读:
    vue项目根据不同环境动态配置接口
    微信内置浏览器手机按返回键,给出提示,是否要退出
    Mac更新系统后提示xcrun error
    curl请求本地域名问题
    PHP把PNG图片转化为JPG时透明背景变黑色
    安卓微信浏览器中window.location.href失效的问题
    上拉加载触底事件最简单写法
    记一次virtualbox和夜神模拟器冲突的问题
    技术总结
    input type file onchange上传文件的过程中,同一个文件二次上传无效的问题。
  • 原文地址:https://www.cnblogs.com/forforever/p/15624480.html
Copyright © 2020-2023  润新知