Golang实现java的AES加解密 SHA1PRNG处理

实测好用!

package sha1

import (
	"bytes"
	"crypto/aes"
	"crypto/sha1"
	"encoding/hex"
	"errors"
	"strings"
)

// 解密【模拟了Java SHA1PRNG处理】
func AesDecrypt(data, outEncryptKey string) string {
	dataByte := Hex2bin(data)
	key, err := AesSha1prng([]byte(outEncryptKey), 128)
	if err != nil {
		return ""
	}

	block, err := aes.NewCipher(generateKey(key))
	if err != nil {
		return ""
	}

	decrypted := make([]byte, len(dataByte))
	size := block.BlockSize()
	for bs, be := 0, size; bs < len(dataByte); bs, be = bs+size, be+size {
		block.Decrypt(decrypted[bs:be], dataByte[bs:be])
	}

	decrypted = PKCS5UnPadding(decrypted)
	return string(decrypted)
}

// 加密【模拟了Java SHA1PRNG处理】
func AesEncrypt(data []byte, outEncryptKey string) string {
	key, err := AesSha1prng([]byte(outEncryptKey), 128)
	if err != nil {
		return ""
	}

	block, err := aes.NewCipher(generateKey(key))
	if err != nil {
		return ""
	}

	data = PKCS5Padding(data, block.BlockSize())
	decrypted := make([]byte, len(data))
	size := block.BlockSize()
	for bs, be := 0, size; bs < len(data); bs, be = bs+size, be+size {
		block.Encrypt(decrypted[bs:be], data[bs:be])
	}

	return Bin2hex(decrypted)
}

// 模拟java SHA1PRNG 处理
func AesSha1prng(keyBytes []byte, encryptLength int) ([]byte, error) {
	hashs := Sha1(Sha1(keyBytes))
	maxLen := len(hashs)
	realLen := encryptLength / 8
	if realLen > maxLen {
		return nil, errors.New("invalid length")
	}

	return hashs[0:realLen], nil
}

func Sha1(data []byte) []byte {
	h := sha1.New()
	h.Write(data)
	bs := h.Sum(nil)
	h.Reset()

	return bs
}

func generateKey(key []byte) (genKey []byte) {
	genKey = make([]byte, 16)
	copy(genKey, key)
	for i := 16; i < len(key); {
		for j := 0; j < 16 && i < len(key); j, i = j+1, i+1 {
			genKey[j] ^= key[i]
		}
	}

	return genKey
}

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)]
}

// Bin2hex 二进制转十六进制
func Bin2hex(b []byte) string {
	// 将 byte 装换为 16进制的字符串
	hexStringData := strings.ToUpper(hex.EncodeToString(b))
	return hexStringData
}

// Hex2bin 十六进制转二进制
func Hex2bin(x string) []byte {
	// 将 16进制的字符串 转换 byte
	hexData, _ := hex.DecodeString(x)
	return hexData
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值