You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

105 lines
2.3 KiB
Go

// phone.go
package crypto
import (
"crypto/aes"
"crypto/cipher"
"encoding/base64"
"errors"
"strings"
)
var (
aesKey = []byte("FSMTjRoFVOzugwDJgxTPlVIEEqUYqyhJ")
// 使用固定的 IV
iv = []byte("0123456789abcdef")
)
type PhoneEncryptionService struct {
}
func NewPhoneEncryptionService() *PhoneEncryptionService {
return &PhoneEncryptionService{}
}
// Encrypt 使用 AES-CBC 加密手机号
func (s *PhoneEncryptionService) Encrypt(phone string) (string, error) {
if phone == "" {
return "", nil
}
// 创建 AES cipher
block, err := aes.NewCipher(aesKey)
if err != nil {
return "", err
}
// 创建 CBC 加密器
mode := cipher.NewCBCEncrypter(block, iv)
// 填充数据
plaintext := []byte(phone)
padding := aes.BlockSize - len(plaintext)%aes.BlockSize
padtext := make([]byte, len(plaintext)+padding)
copy(padtext, plaintext)
for i := len(plaintext); i < len(padtext); i++ {
padtext[i] = byte(padding)
}
// 加密
ciphertext := make([]byte, len(padtext))
mode.CryptBlocks(ciphertext, padtext)
// Base64编码
encoded := base64.StdEncoding.EncodeToString(ciphertext)
return encoded, nil
}
// Decrypt 解密手机号
func (s *PhoneEncryptionService) Decrypt(encryptedPhone string) (string, error) {
if encryptedPhone == "" {
return "", nil
}
// Base64解码
ciphertext, err := base64.StdEncoding.DecodeString(encryptedPhone)
if err != nil {
return "", err
}
// 创建 AES cipher
block, err := aes.NewCipher(aesKey)
if err != nil {
return "", err
}
// 创建 CBC 解密器
mode := cipher.NewCBCDecrypter(block, iv)
// 解密
plaintext := make([]byte, len(ciphertext))
mode.CryptBlocks(plaintext, ciphertext)
// 去除填充
padding := int(plaintext[len(plaintext)-1])
if padding > aes.BlockSize || padding == 0 {
return "", errors.New("无效的填充")
}
for i := len(plaintext) - padding; i < len(plaintext); i++ {
if int(plaintext[i]) != padding {
return "", errors.New("无效的填充")
}
}
return string(plaintext[:len(plaintext)-padding]), nil
}
func (s *PhoneEncryptionService) StringPhone(encryptedPhone string) (string, error) {
p, err := s.Decrypt(encryptedPhone)
if err != nil {
return "", err
}
a := strings.Join(strings.Split(p, "")[:3], "") + "****" + strings.Join(strings.Split(p, "")[7:], "")
return a, nil
}