package myCrypto import ( "bytes" "crypto/aes" "crypto/cipher" "crypto/rand" "crypto/rsa" "crypto/x509" "encoding/base64" "encoding/pem" "fmt" "os" "sync" ) var ( instance *CryptoService once sync.Once ) func CryptoServiceInstance() *CryptoService { once.Do(func() { instance = &CryptoService{} }) return instance } type CryptoService struct { rsaPriKey *rsa.PrivateKey rsaPubKey *rsa.PublicKey aesPriKey []byte } func (cryptoService *CryptoService) Init() { cryptoService.readAESPriKey() } func (cryptoService *CryptoService) EncryptByRSA(msg []byte) (encryptedBytes []byte, err error) { //公钥加密 encryptedBytes, err = rsa.EncryptPKCS1v15(rand.Reader, cryptoService.rsaPubKey, msg) if err != nil { fmt.Printf("EncryptByRSA failed!, err: %v", err) return } return } func (cryptoService *CryptoService) DecryptByRSA(encryptedBytes []byte) (decryptedBytes []byte, err error) { //私钥解密 decryptedBytes, err = rsa.DecryptPKCS1v15(rand.Reader, cryptoService.rsaPriKey, encryptedBytes) if err != nil { fmt.Printf("DecryptByRSA failed!, err: %v", err) return } return } func (cryptoService *CryptoService) EncryptByAES(msg []byte) (encryptedBytes []byte, err error) { //CBC加密 block, err := aes.NewCipher(cryptoService.aesPriKey) //block if err != nil { fmt.Printf("AES NewCipher failed!, err: %v", err) return nil, err } blockSize := block.BlockSize() //密钥块长度 paddedData := cryptoService.pkcs5Padding(msg, blockSize) //填充 blockMode := cipher.NewCBCEncrypter(block, cryptoService.aesPriKey[:blockSize]) //加密模式 encryptedBytes = make([]byte, len(paddedData)) //创建数组 blockMode.CryptBlocks(encryptedBytes, paddedData) //加密 return } func (cryptoService *CryptoService) DecryptByAES(encryptedBytes []byte) (decryptedBytes []byte, err error) { //CBC解密 block, err := aes.NewCipher(cryptoService.aesPriKey) // 分组秘钥 if err != nil { return } blockSize := block.BlockSize() // 获取秘钥块的长度 blockMode := cipher.NewCBCDecrypter(block, cryptoService.aesPriKey[:blockSize]) // 加密模式 decryptedBytes = make([]byte, len(encryptedBytes)) // 创建数组 blockMode.CryptBlocks(decryptedBytes, encryptedBytes) // 解密 decryptedBytes = pkcs5UnPadding(decryptedBytes) // 去除补全码 return } func (cryptoService *CryptoService) readRSAPubKey() (err error) { //读取公钥 file, err := os.Open("public.pem") if err != nil { fmt.Printf("Decoding rsa public key failed, check your config, please!, err: %v", err) return } fileInfo, err := file.Stat() if err != nil { fmt.Printf("Decoding rsa public key failed, check your config, please!, err: %v", err) return } rsaPubKeyBytes := make([]byte, fileInfo.Size()) file.Read(rsaPubKeyBytes) // 读取公钥文件内容 file.Close() // 2 pem解码 block, _ := pem.Decode(rsaPubKeyBytes) // 解码 // 3 x509解析得到公钥 pubInterface, err := x509.ParsePKIXPublicKey(block.Bytes) if err != nil { fmt.Printf("Decoding rsa public key failed, check your config, please!, err: %v", err) return } // 断言类型转换 cryptoService.rsaPubKey = pubInterface.(*rsa.PublicKey) return } func (cryptoService *CryptoService) readRSAPriKey() (err error) { //读取私钥 file, err := os.Open("private.pem") if err != nil { fmt.Printf("Decoding rsa public key failed, check your config, please!, err: %v", err) return } fileInfo, err := file.Stat() if err != nil { fmt.Printf("Decoding rsa public key failed, check your config, please!, err: %v", err) return } rsaPriKeyBytes := make([]byte, fileInfo.Size()) file.Read(rsaPriKeyBytes) file.Close() block, _ := pem.Decode(rsaPriKeyBytes) fmt.Printf("私钥:\n") fmt.Printf("%v", base64.StdEncoding.EncodeToString(block.Bytes)) rsaPriKey, err := x509.ParsePKCS1PrivateKey(block.Bytes) if err != nil { fmt.Printf("Decoding rsa primary key failed, check your config, please!, err: %v", err) return } cryptoService.rsaPriKey = rsaPriKey return } func (cryptoService *CryptoService) readAESPriKey() (aesPriKey []byte) { //读取私钥 aesPriKey = []byte("Xbz1145141919810") return } func (cryptoService *CryptoService) pkcs5Padding(ciphertext []byte, blockSize int) []byte { padding := blockSize - len(ciphertext)%blockSize //判断缺少几位长度。最少1,最多 blockSize padtext := bytes.Repeat([]byte{byte(padding)}, padding) //补足位数。把切片[]byte{byte(padding)}复制padding个 return append(ciphertext, padtext...) } func pkcs5UnPadding(origData []byte) []byte { length := len(origData) unpadding := int(origData[length-1]) return origData[:(length - unpadding)] }