Java和go加密,解密,Base64失败

16 篇文章 0 订阅
10 篇文章 0 订阅

在客户端和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);
    }

}
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值