@@ -0,0 +1,85 @@
|
||||
package auth
|
||||
|
||||
import (
|
||||
"crypto/aes"
|
||||
"encoding/base64"
|
||||
"errors"
|
||||
"fmt"
|
||||
)
|
||||
|
||||
func DecryptCredential(ciphertextBase64, key string) (string, error) {
|
||||
ciphertext, err := base64.StdEncoding.DecodeString(ciphertextBase64)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
if len(ciphertext) == 0 || len(ciphertext)%aes.BlockSize != 0 {
|
||||
return "", errors.New("invalid AES ciphertext length")
|
||||
}
|
||||
|
||||
block, err := aes.NewCipher(repeatKey(key, aes.BlockSize))
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
plain := make([]byte, len(ciphertext))
|
||||
for start := 0; start < len(ciphertext); start += aes.BlockSize {
|
||||
block.Decrypt(plain[start:start+aes.BlockSize], ciphertext[start:start+aes.BlockSize])
|
||||
}
|
||||
|
||||
plain, err = unpadPKCS7(plain, aes.BlockSize)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
return string(plain), nil
|
||||
}
|
||||
|
||||
func EncryptCredential(plaintext, key string) (string, error) {
|
||||
block, err := aes.NewCipher(repeatKey(key, aes.BlockSize))
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
plain := padPKCS7([]byte(plaintext), aes.BlockSize)
|
||||
out := make([]byte, len(plain))
|
||||
for start := 0; start < len(plain); start += aes.BlockSize {
|
||||
block.Encrypt(out[start:start+aes.BlockSize], plain[start:start+aes.BlockSize])
|
||||
}
|
||||
return base64.StdEncoding.EncodeToString(out), nil
|
||||
}
|
||||
|
||||
func repeatKey(key string, size int) []byte {
|
||||
src := []byte(key)
|
||||
out := make([]byte, size)
|
||||
if len(src) == 0 {
|
||||
return out
|
||||
}
|
||||
for i := range out {
|
||||
out[i] = src[i%len(src)]
|
||||
}
|
||||
return out
|
||||
}
|
||||
|
||||
func unpadPKCS7(in []byte, blockSize int) ([]byte, error) {
|
||||
if len(in) == 0 || len(in)%blockSize != 0 {
|
||||
return nil, errors.New("invalid padded data length")
|
||||
}
|
||||
pad := int(in[len(in)-1])
|
||||
if pad == 0 || pad > blockSize || pad > len(in) {
|
||||
return nil, fmt.Errorf("invalid padding size %d", pad)
|
||||
}
|
||||
for _, b := range in[len(in)-pad:] {
|
||||
if int(b) != pad {
|
||||
return nil, errors.New("invalid padding bytes")
|
||||
}
|
||||
}
|
||||
return in[:len(in)-pad], nil
|
||||
}
|
||||
|
||||
func padPKCS7(in []byte, blockSize int) []byte {
|
||||
pad := blockSize - len(in)%blockSize
|
||||
out := make([]byte, len(in)+pad)
|
||||
copy(out, in)
|
||||
for i := len(in); i < len(out); i++ {
|
||||
out[i] = byte(pad)
|
||||
}
|
||||
return out
|
||||
}
|
||||
Reference in New Issue
Block a user