dtp/crypto/cryptoService.go

166 lines
4.8 KiB
Go
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

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