114 lines
		
	
	
		
			2.7 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
		
		
			
		
	
	
			114 lines
		
	
	
		
			2.7 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
|  | package crypto | |||
|  | 
 | |||
|  | import ( | |||
|  | 	"bytes" | |||
|  | 	"crypto/aes" | |||
|  | 	"crypto/cipher" | |||
|  | 	"crypto/md5" | |||
|  | 	"crypto/rand" | |||
|  | 	"encoding/base64" | |||
|  | 	"encoding/hex" | |||
|  | 	"errors" | |||
|  | 	"io" | |||
|  | ) | |||
|  | 
 | |||
|  | // PKCS7填充 | |||
|  | func PKCS7Padding(ciphertext []byte, blockSize int) []byte { | |||
|  | 	padding := blockSize - len(ciphertext)%blockSize | |||
|  | 	padtext := bytes.Repeat([]byte{byte(padding)}, padding) | |||
|  | 	return append(ciphertext, padtext...) | |||
|  | } | |||
|  | 
 | |||
|  | // 去除PKCS7填充 | |||
|  | func PKCS7UnPadding(origData []byte) ([]byte, error) { | |||
|  | 	length := len(origData) | |||
|  | 	if length == 0 { | |||
|  | 		return nil, errors.New("input data error") | |||
|  | 	} | |||
|  | 	unpadding := int(origData[length-1]) | |||
|  | 	if unpadding > length { | |||
|  | 		return nil, errors.New("unpadding size is invalid") | |||
|  | 	} | |||
|  | 
 | |||
|  | 	// 检查填充字节是否一致 | |||
|  | 	for i := 0; i < unpadding; i++ { | |||
|  | 		if origData[length-1-i] != byte(unpadding) { | |||
|  | 			return nil, errors.New("invalid padding") | |||
|  | 		} | |||
|  | 	} | |||
|  | 
 | |||
|  | 	return origData[:(length - unpadding)], nil | |||
|  | } | |||
|  | 
 | |||
|  | // AES CBC模式加密,Base64传入传出 | |||
|  | func AesEncrypt(plainText []byte, key string) (string, error) { | |||
|  | 	keyBytes, err := hex.DecodeString(key) | |||
|  | 	if err != nil { | |||
|  | 		return "", err | |||
|  | 	} | |||
|  | 	block, err := aes.NewCipher(keyBytes) | |||
|  | 	if err != nil { | |||
|  | 		return "", err | |||
|  | 	} | |||
|  | 	blockSize := block.BlockSize() | |||
|  | 	plainText = PKCS7Padding(plainText, blockSize) | |||
|  | 
 | |||
|  | 	cipherText := make([]byte, blockSize+len(plainText)) | |||
|  | 	iv := cipherText[:blockSize] // 使用前blockSize字节作为IV | |||
|  | 	_, err = io.ReadFull(rand.Reader, iv) | |||
|  | 	if err != nil { | |||
|  | 		return "", err | |||
|  | 	} | |||
|  | 
 | |||
|  | 	mode := cipher.NewCBCEncrypter(block, iv) | |||
|  | 	mode.CryptBlocks(cipherText[blockSize:], plainText) | |||
|  | 
 | |||
|  | 	return base64.StdEncoding.EncodeToString(cipherText), nil | |||
|  | } | |||
|  | 
 | |||
|  | // AES CBC模式解密,Base64传入传出 | |||
|  | func AesDecrypt(cipherTextBase64 string, key string) ([]byte, error) { | |||
|  | 	keyBytes, err := hex.DecodeString(key) | |||
|  | 	if err != nil { | |||
|  | 		return nil, err | |||
|  | 	} | |||
|  | 	cipherText, err := base64.StdEncoding.DecodeString(cipherTextBase64) | |||
|  | 	if err != nil { | |||
|  | 		return nil, err | |||
|  | 	} | |||
|  | 
 | |||
|  | 	block, err := aes.NewCipher(keyBytes) | |||
|  | 	if err != nil { | |||
|  | 		return nil, err | |||
|  | 	} | |||
|  | 
 | |||
|  | 	blockSize := block.BlockSize() | |||
|  | 	if len(cipherText) < blockSize { | |||
|  | 		return nil, errors.New("ciphertext too short") | |||
|  | 	} | |||
|  | 
 | |||
|  | 	iv := cipherText[:blockSize] | |||
|  | 	cipherText = cipherText[blockSize:] | |||
|  | 
 | |||
|  | 	if len(cipherText)%blockSize != 0 { | |||
|  | 		return nil, errors.New("ciphertext is not a multiple of the block size") | |||
|  | 	} | |||
|  | 
 | |||
|  | 	mode := cipher.NewCBCDecrypter(block, iv) | |||
|  | 	mode.CryptBlocks(cipherText, cipherText) | |||
|  | 
 | |||
|  | 	plainText, err := PKCS7UnPadding(cipherText) | |||
|  | 	if err != nil { | |||
|  | 		return nil, err | |||
|  | 	} | |||
|  | 
 | |||
|  | 	return plainText, nil | |||
|  | } | |||
|  | 
 | |||
|  | // Md5Encrypt 用于对传入的message进行MD5加密 | |||
|  | func Md5Encrypt(message string) string { | |||
|  | 	hash := md5.New() | |||
|  | 	hash.Write([]byte(message))              // 将字符串转换为字节切片并写入 | |||
|  | 	return hex.EncodeToString(hash.Sum(nil)) // 将哈希值转换为16进制字符串并返回 | |||
|  | } |