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
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
|
|
}
|