Java和go加密,解密,Base64失败
Posted 陳英傑
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Java和go加密,解密,Base64失败相关的知识,希望对你有一定的参考价值。
在客户端和go后台对接口的时候,加解密出现了问题记录。
问题主要出现在base64上,刚开始android使用
import android.util.Base64;
public class AesUtil
public static String encryptEcb(String content, String key)
if (TextUtils.isEmpty(content) || TextUtils.isEmpty(key)) return "";
try
byte[] raw = key.getBytes("UTF-8");
SecretKeySpec skeySpec = new SecretKeySpec(raw, "AES");
Cipher cipher = Cipher.getInstance(format);
// IvParameterSpec iv = new IvParameterSpec(getIv(key));// go后台没有使用向量
cipher.init(Cipher.ENCRYPT_MODE, skeySpec);
byte[] encrypted = cipher.doFinal(content.getBytes("UTF-8"));
return Base64.encodeToString(encrypted, Base64.URL_SAFE);
catch (Exception e)
e.printStackTrace();
return "";
go的解密如下:
这里的URLEncoding对应Java的Base64.URL_SAFE,我们知道加密结果中含有3种特殊URL字符/,+,=(只有使用Base64.NO_PADDING模式加密的才没有=),所以这里使用URL_SAFE模式做替换,它是用-替换+,_替换/,=省略,替换好还原,但是=号不只一个找回就比较难了,上面第二张图就是go用来找回我们舍弃掉的=;其中的来龙去脉介绍完了,出问题的地方是Java的Base64.encodeToString出来的结果,go拿到之后decode失败,重点来了,为什么呢?
原因:Java的Base64的结果有一个特殊操作其他语言没有,下面这是Java的Base64结果
ZSDSpCpVGsZf6OAMDaIsyC1Ni2yOnYN1GT9MBTowuGcrYnrL0378CiJWR08lCSvSjnVqF_Bdg7xm
ZHsP1QGRBKZUBoJJmepryh3jjNhlX9dLRweWIDqjvgZizmucw7NS3MvznJnaAdUkbB8rOcJWB3db
NWqCTkYQB1AzUyzYky4oJYUJEtBx-RUhXCfYiMqGJ6_V53Xlbky8onJIkHgzmVopa7luko9ihLJY
LPnOL65SrotvSAHHi_yRIjj2TprZtLH3X_mPjS9GLDoX6dAR-4vfuMwdeSCSpwKP8sq2XxOXXKVb
r6xmIeVNY-miqBFEDSktj15KxnKADTWQDLJm6NW7tiwq6d0UkLIl0c9u7ViIxBbF3jCfWFulsCG5
7kvyaE1jDHUjN-R7U0idW5WYLlyBPUvAoQnoXYZZPK2a9jgVoGB-OJpF99_HLbFPoJjN5nJMvPNq
KCPXiqpkEgF1objdjJjq0JZNw5LhuxZoDPUrmhMlFYrhueyrIjh4rugDlnqp2uZig-ksQocKCQjg
pGOZ6B_lWHWE5U_FZrhFLYE5hjBNcBiYn1qHV64Z2zkjKm6s5V7wBTXVZQKX6ahvzS4wJzzoarNF
aStoxG4KM7q1Luv2tQU5ZjYvxYnE3ijJQqOl2UiYd2pv9fPF0eJche0R77tyViVBGrp7Fj79RBrP
eTsZVnEQ14JojLSTHMiGkk88s8CiP1Mr0kKr6rtnXZsKgXc-8DlafrKfpU2aw1WfjlSFOrMkqF9V
vs1Y5I3kuIzFBlyXf-9Akku4bNS1raVboYl3W8AefPcW3IF8QlZ904NCGwOwtNfIty0W0vKm
它里面包含换行符,这个就是go使用decode失败的原因,所以我们在和这些语言调试加解密之类的时候可以给换行符去掉,测试发现trim()
不可以,使用replace("\\n", "")
可以,这里自己写了一个Base64的工具类实现此功能:
import android.text.TextUtils;
import android.util.Base64;
public class Base64UrlSafe
private static char[] base64EncodeChars = new char[]'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L',
'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', 'a', 'b', 'c', 'd', 'e', 'f', 'g',
'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', '0', '1',
'2', '3', '4', '5', '6', '7', '8', '9', '-', '_';
private LzBase64()
public static String base64Encode(String data)
if (TextUtils.isEmpty(data))
return "";
byte[] dataBytes = data.getBytes();
return encode(dataBytes);
public static String base64Decode(String data)
if (TextUtils.isEmpty(data))
return "";
return new String(decode(data));
public static String encode(byte[] data)
StringBuffer sb = new StringBuffer();
int len = data.length;
int i = 0;
int b1, b2, b3;
while (i < len)
b1 = data[i++] & 0xff;
if (i == len)
sb.append(base64EncodeChars[b1 >>> 2]);
sb.append(base64EncodeChars[(b1 & 0x3) << 4]);
sb.append(""); // "=="
break;
b2 = data[i++] & 0xff;
if (i == len)
sb.append(base64EncodeChars[b1 >>> 2]);
sb.append(base64EncodeChars[((b1 & 0x03) << 4) | ((b2 & 0xf0) >>> 4)]);
sb.append(base64EncodeChars[(b2 & 0x0f) << 2]);
sb.append(""); // "="
break;
b3 = data[i++] & 0xff;
sb.append(base64EncodeChars[b1 >>> 2]);
sb.append(base64EncodeChars[((b1 & 0x03) << 4) | ((b2 & 0xf0) >>> 4)]);
sb.append(base64EncodeChars[((b2 & 0x0f) << 2) | ((b3 & 0xc0) >>> 6)]);
sb.append(base64EncodeChars[b3 & 0x3f]);
return sb.toString();
private static byte[] decode(String str)
return Base64.decode(str, Base64.URL_SAFE);
以上是关于Java和go加密,解密,Base64失败的主要内容,如果未能解决你的问题,请参考以下文章