go和java,共通的AES加密实现

6 篇文章 2 订阅
该博客展示了如何在Go和Java之间实现AES加密的兼容性。通过使用相同的加密算法(AES/CBC/PKCS5Padding),并处理密钥长度以确保一致,实现了跨平台的加解密操作。示例代码包括了Java和Go的加密及解密方法,并给出了实际运行的示例输出。
摘要由CSDN通过智能技术生成
起因:因为工程需要,需要实现go和Java实现这AES加密共通

可以提供AES加密的密钥,是随机生成的字符串,所以在使用时,需要处理一下

java代码
import org.apache.commons.codec.digest.DigestUtils;

import java.net.URLEncoder;
import java.security.GeneralSecurityException;
import java.util.Arrays;
import java.util.Base64;
import javax.crypto.Cipher;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;


public class AesCode {


    public static byte[] encrypt(String key, byte[] origData) throws GeneralSecurityException {
        byte[] keyBytes = getKeyBytes(key);
        byte[] buf = new byte[16];
        System.arraycopy(keyBytes, 0, buf, 0, Math.max(keyBytes.length, buf.length));
        Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
        cipher.init(Cipher.ENCRYPT_MODE, new SecretKeySpec(buf, "AES"), new IvParameterSpec(keyBytes));
        return cipher.doFinal(origData);

    }

    public static byte[] decrypt(String key, byte[] crypted) throws GeneralSecurityException {
        byte[] keyBytes = getKeyBytes(key);
        byte[] buf = new byte[16];
        System.arraycopy(keyBytes, 0, buf, 0, Math.max(keyBytes.length, buf.length));
        Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
        cipher.init(Cipher.DECRYPT_MODE, new SecretKeySpec(buf, "AES"), new IvParameterSpec(keyBytes));
        return cipher.doFinal(crypted);
    }

    private static byte[] getKeyBytes(String key) {
        byte[] bytes = key.getBytes();
        return bytes.length == 16 ? bytes : Arrays.copyOf(bytes, 16);
    }

    public static String encrypt(String key, String val) {
        try {
            byte[] origData = val.getBytes();
            byte[] crafted = encrypt(key, origData);
            return Base64.getEncoder().encodeToString(crafted);
        }catch (Exception e){
            return "";
        }
    }

    public static String decrypt(String key, String val) throws GeneralSecurityException {
        byte[] crypted = Base64.getDecoder().decode(val);
        byte[] origData = decrypt(key, crypted);
        return new String(origData);
    }


    public static void main(String[] args) throws Exception {
        // 密钥
        String key = DigestUtils.md5Hex("cvrhsdftredhghgfjhgwsfresdsfhjk").substring(0, 16);
        // 明文
        String val = "hello,ase";

        String ret = encrypt(key, val);
        System.out.println(ret);
    }


}

输出:VYGThW0MXPf4v88IKP/o4g==

go的代码

import (
	"bytes"
	"crypto/aes"
	"crypto/cipher"
	"crypto/md5"
	"encoding/base64"
	"encoding/hex"
	"fmt"
)

func getKeyBytes(key string) []byte {
	keyBytes := []byte(key)
	switch l := len(keyBytes); {
	case l < 16:
		keyBytes = append(keyBytes, make([]byte, 16-l)...)
	case l > 16:
		keyBytes = keyBytes[:16]
	}
	return keyBytes
}

func encrypt(key string, origData []byte) ([]byte, error) {
	keyBytes := getKeyBytes(key)
	block, err := aes.NewCipher(keyBytes)
	if err != nil {
		return nil, err
	}
	blockSize := block.BlockSize()
	origData = PKCS5Padding(origData, blockSize)
	blockMode := cipher.NewCBCEncrypter(block, keyBytes[:blockSize])
	crypted := make([]byte, len(origData))
	blockMode.CryptBlocks(crypted, origData)
	return crypted, nil
}

func decrpt(key string, crypted []byte) ([]byte, error) {
	keyBytes := getKeyBytes(key)
	block, err := aes.NewCipher(keyBytes)
	if err != nil {
		return nil, err
	}
	blockSize := block.BlockSize()
	blockMode := cipher.NewCBCDecrypter(block, keyBytes[:blockSize])
	origData := make([]byte, len(crypted))
	blockMode.CryptBlocks(origData, crypted)
	origData = PKCS5UnPadding(origData)
	return origData, nil
}

func PKCS5Padding(ciphertext []byte, blockSize int) []byte {
	padding := blockSize - len(ciphertext)%blockSize
	padtext := bytes.Repeat([]byte{byte(padding)}, padding)
	return append(ciphertext, padtext...)
}

func PKCS5UnPadding(origData []byte) []byte {
	length := len(origData)
	unpadding := int(origData[length-1])
	return origData[:(length - unpadding)]
}

func Encrypt(key string, val string) (string, error) {
	origData := []byte(val)
	crypted, err := encrypt(key, origData)
	if err != nil {
		return "", err
	}
	return base64.URLEncoding.EncodeToString(crypted), nil
}

func Decrypt(key string, val []byte) (string, error) {
	origData, err := decrpt(key, val)
	if err != nil {
		return "", err
	}
	return string(origData), nil
}

func main() {
	m := md5.Sum([]byte("cvrhsdftredhghgfjhgwsfresdsfhjk"))
	key := hex.EncodeToString(m[:])[0:16]
	cal := "VYGThW0MXPf4v88IKP/o4g=="
	// url 解码
	//unescape, _ := url.QueryUnescape(cal)
	// base64 解码
	decodeString, _ := base64.StdEncoding.DecodeString(cal)

	// 揭秘
	decrypt, _ := Decrypt(key, decodeString)
	fmt.Println(decrypt)

}


输出:hello,ase

另外 还有对于输出的值,是否需要url编码

URLEncoder.encode(String, "UTF-8");

go的url编解码

url.QueryEscape()
url.QueryUnescape()

注意;如有侵权,请速联系

评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值