first commit
This commit is contained in:
120
pkg/aes/aes.go
Normal file
120
pkg/aes/aes.go
Normal file
@ -0,0 +1,120 @@
|
||||
package aes
|
||||
|
||||
import (
|
||||
cryptoAes "crypto/aes"
|
||||
"crypto/cipher"
|
||||
"encoding/base64"
|
||||
)
|
||||
|
||||
var _ Aes = (*aes)(nil)
|
||||
|
||||
type Aes interface {
|
||||
i()
|
||||
|
||||
EncryptCBC(encryptStr string, urlEncode bool) (string, error)
|
||||
DecryptCBC(decryptStr string, urlEncode bool) (string, error)
|
||||
|
||||
EncryptCFB(plain string, urlEncode bool) (string, error)
|
||||
DecryptCFB(encrypted string, urlEncode bool) (string, error)
|
||||
}
|
||||
|
||||
type aes struct {
|
||||
key string
|
||||
iv string
|
||||
}
|
||||
|
||||
func New(key, iv string) Aes {
|
||||
return &aes{
|
||||
key: key,
|
||||
iv: iv,
|
||||
}
|
||||
}
|
||||
|
||||
func (a *aes) i() {}
|
||||
|
||||
func (a *aes) EncryptCBC(encryptStr string, urlEncode bool) (string, error) {
|
||||
encoder := base64.StdEncoding
|
||||
if urlEncode {
|
||||
encoder = base64.URLEncoding
|
||||
}
|
||||
|
||||
encryptBytes := []byte(encryptStr)
|
||||
block, err := cryptoAes.NewCipher([]byte(a.key))
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
blockSize := block.BlockSize()
|
||||
encryptBytes = pkcsPadding(encryptBytes, blockSize)
|
||||
blockMode := cipher.NewCBCEncrypter(block, []byte(a.iv))
|
||||
encrypted := make([]byte, len(encryptBytes))
|
||||
blockMode.CryptBlocks(encrypted, encryptBytes)
|
||||
|
||||
return encoder.EncodeToString(encrypted), nil
|
||||
}
|
||||
|
||||
func (a *aes) DecryptCBC(decryptStr string, urlEncode bool) (string, error) {
|
||||
encoder := base64.StdEncoding
|
||||
if urlEncode {
|
||||
encoder = base64.URLEncoding
|
||||
}
|
||||
|
||||
decryptBytes, err := encoder.DecodeString(decryptStr)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
block, err := cryptoAes.NewCipher([]byte(a.key))
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
blockMode := cipher.NewCBCDecrypter(block, []byte(a.iv))
|
||||
decrypted := make([]byte, len(decryptBytes))
|
||||
blockMode.CryptBlocks(decrypted, decryptBytes)
|
||||
decrypted = pkcsUnPadding(decrypted)
|
||||
|
||||
return string(decrypted), nil
|
||||
}
|
||||
|
||||
func (a *aes) EncryptCFB(plain string, urlEncode bool) (string, error) {
|
||||
encoder := base64.StdEncoding
|
||||
if urlEncode {
|
||||
encoder = base64.URLEncoding
|
||||
}
|
||||
|
||||
block, err := cryptoAes.NewCipher([]byte(a.key))
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
encrypted := make([]byte, len(plain))
|
||||
stream := cipher.NewCFBEncrypter(block, []byte(a.iv))
|
||||
stream.XORKeyStream(encrypted, []byte(plain))
|
||||
|
||||
return encoder.EncodeToString(encrypted), nil
|
||||
|
||||
}
|
||||
|
||||
func (a *aes) DecryptCFB(encrypted string, urlEncode bool) (string, error) {
|
||||
encoder := base64.StdEncoding
|
||||
if urlEncode {
|
||||
encoder = base64.URLEncoding
|
||||
}
|
||||
|
||||
decryptBytes, err := encoder.DecodeString(encrypted)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
block, err := cryptoAes.NewCipher([]byte(a.key))
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
plain := make([]byte, len(decryptBytes))
|
||||
stream := cipher.NewCFBDecrypter(block, []byte(a.iv))
|
||||
stream.XORKeyStream(plain, decryptBytes)
|
||||
|
||||
return string(plain), nil
|
||||
}
|
25
pkg/aes/padding.go
Normal file
25
pkg/aes/padding.go
Normal file
@ -0,0 +1,25 @@
|
||||
package aes
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
)
|
||||
|
||||
/**
|
||||
* 填充有六种:NoPadding, PKCS#5, PKCS#7, ISO 10126, ANSI X9.23和ZerosPadding
|
||||
* 对于AES来说PKCS5Padding和PKCS7Padding是完全一样的,不同在于PKCS5限定了块大小为8bytes而PKCS7没有限定
|
||||
* 因此对于AES来说两者完全相同,但是对于Rijndael就不一样了
|
||||
* AES是Rijndael在块大小为8bytes时的特例,对于使用其他信息块大小的Rijndael算法只能使用PKCS7
|
||||
* 在AES加密当中严格来说是不能使用pkcs5的,因为AES的块大小是16bytes而pkcs5只能用于8bytes,通常我们在AES加密中所说的pkcs5指的就是pkcs7
|
||||
*/
|
||||
|
||||
func pkcsPadding(cipherText []byte, blockSize int) []byte {
|
||||
p := blockSize - len(cipherText)%blockSize
|
||||
padText := bytes.Repeat([]byte{byte(p)}, p)
|
||||
return append(cipherText, padText...)
|
||||
}
|
||||
|
||||
func pkcsUnPadding(decrypted []byte) []byte {
|
||||
length := len(decrypted)
|
||||
u := int(decrypted[length-1])
|
||||
return decrypted[:(length - u)]
|
||||
}
|
Reference in New Issue
Block a user