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

简介: 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也不相同,暂时不知道什么原因


相关文章
|
6天前
|
存储 Java
java用base64编码案例
Java Base64编码示例:导入`java.util.Base64`,设置字符串`originalString`,使用`Base64.getEncoder().encodeToString()`编码并存储到`encodedString`,打印编码后字符串。解码用`Base64.getDecoder().decode()`。
12 0
|
7月前
|
存储 编解码 Cloud Native
基于Java的Base64编解码优化探讨
基于Java的Base64编解码优化探讨
101 0
|
7月前
|
存储 Java
使用Java进行Base64编码的示例
使用Java进行Base64编码的示例
70 1
|
24天前
|
Java 数据安全/隐私保护
java base64 加密 解密
java base64 加密 解密
|
2月前
|
Java
java base64转doc文件
以下是使用Java进行Base64转换的例子: 1. 使用Java Base64工具类进行转换 ```java // 导入相关包 import java.util.Base64; import java.io.FileOutputStream; import java.io.IOException; // 将Base64字符串转换为字节数组 byte[] decodedBytes = Base64.getDecoder().decode(base64String); // 将字节数组写入到文件中 try (FileOutputStream fos = new FileOutputStrea
|
2月前
|
Java API PHP
多多关键字API php java Python
多多关键字API接口广泛应用于商家进行市场分析、竞品分析、关键词优化等场景。商家可以通过分析关键词数据,了解用户需求,制定针对性的营销策略,提高产品的曝光率和转化率。
php案例:判断这个文件是什么编程语言代码的文件(判断java或者php)
php案例:判断这个文件是什么编程语言代码的文件(判断java或者php)
php案例:判断这个文件是什么编程语言代码的文件(判断java或者php)
|
5月前
|
存储 Java PHP
Java、PHP、C语言经典项目源码合集推荐(一)
Java、PHP、C语言经典项目源码合集推荐(一)
79 0
|
6月前
|
开发框架 JavaScript Java
推荐一个日历转换开源工具库,支持C#、Java、PHP等主流的语言
推荐一个日历转换开源工具库,支持C#、Java、PHP等主流的语言
47 0
|
7月前
|
消息中间件 Java 物联网
[笔记]阿里云物联网之业务服务端(java、php)接入阿里云平台(二)
[笔记]阿里云物联网之业务服务端(java、php)接入阿里云平台(二)
329 0