65 Star 375 Fork 448

infraboard/go-course

加入 Gitee
与超过 1200万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
文件
克隆/下载
cbc.go 2.69 KB
一键复制 编辑 原始数据 按行查看 历史
Mr.Yu 提交于 2021-09-13 10:55 . 修复比较目录
/*CBC加密 按照golang标准库的例子代码
不过里面没有填充的部分,所以补上
*/
package cbc
import (
"bytes"
"crypto/aes"
"crypto/cipher"
"crypto/rand"
"crypto/sha1"
"errors"
"io"
)
func pkcs7Padding(ciphertext []byte, blockSize int) []byte {
padding := blockSize - len(ciphertext)%blockSize
padtext := bytes.Repeat([]byte{byte(padding)}, padding)
return append(ciphertext, padtext...)
}
func pkcs7UnPadding(origData []byte) []byte {
length := len(origData)
unpadding := int(origData[length-1])
return origData[:(length - unpadding)]
}
// aesCBCEncrypt aes加密,填充秘钥key的16位,24,32分别对应AES-128, AES-192, or AES-256.
func aesCBCEncrypt(rawData, key []byte) ([]byte, error) {
block, err := aes.NewCipher(key)
if err != nil {
return nil, err
}
//填充原文
blockSize := block.BlockSize()
rawData = pkcs7Padding(rawData, blockSize)
//初始向量IV必须是唯一,但不需要保密 []byte{}
cipherText := make([]byte, blockSize+len(rawData))
//block大小 16, 我们iv向量 也是16, 采用随机生成
iv := cipherText[:blockSize]
if _, err := io.ReadFull(rand.Reader, iv); err != nil {
return nil, err
}
//block大小和初始向量大小一定要一致
mode := cipher.NewCBCEncrypter(block, iv)
mode.CryptBlocks(cipherText[blockSize:], rawData)
return cipherText, nil
}
func aesCBCDecrypt(encryptData, key []byte) ([]byte, error) {
block, err := aes.NewCipher(key)
if err != nil {
return nil, err
}
blockSize := block.BlockSize()
if len(encryptData) < blockSize {
return nil, errors.New("ciphertext too short")
}
// 1. 读取iv
iv := encryptData[:blockSize]
// 2. 读取密文
encryptData = encryptData[blockSize:]
// CBC mode always works in whole blocks.
if len(encryptData)%blockSize != 0 {
return nil, errors.New("ciphertext is not a multiple of the block size")
}
mode := cipher.NewCBCDecrypter(block, iv)
plainText := encryptData[:]
// 之前加密 dst(encrypt) -- src(plainText)
// 解密 dst(plainText) -- src(entrypt)
// CryptBlocks can work in-place if the two arguments are the same.
mode.CryptBlocks(plainText, encryptData)
//解填充
unPaddingP := pkcs7UnPadding(plainText)
return unPaddingP, nil
}
// 采用hmac进行2次hash, 取32位
func sha1Hash2(key []byte) []byte {
h := sha1.New()
h.Write(key)
hashData := h.Sum(nil)
keyBuffer := bytes.NewBuffer(hashData)
h.Reset()
h.Write(hashData)
keyBuffer.Write(h.Sum(nil))
return keyBuffer.Bytes()[:32]
}
// Encrypt aes cbc加密
func Encrypt(data, key []byte) ([]byte, error) {
return aesCBCEncrypt(data, sha1Hash2(key))
}
// Decrypt aes cbc解密
func Decrypt(data, key []byte) ([]byte, error) {
return aesCBCDecrypt(data, sha1Hash2(key))
}
Loading...
马建仓 AI 助手
尝试更多
代码解读
代码找茬
代码优化
Go
1
https://gitee.com/infraboard/go-course.git
git@gitee.com:infraboard/go-course.git
infraboard
go-course
go-course
42078ba5e17c

搜索帮助

0d507c66 1850385 C8b1a773 1850385