123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423 |
- package tool
- import (
- "bytes"
- "crypto/cipher"
- "crypto/des"
- "crypto/md5"
- "crypto/rand"
- "crypto/rsa"
- "crypto/x509"
- "encoding/base64"
- "encoding/hex"
- "encoding/pem"
- "errors"
- "fmt"
- "github.com/smartwalle/crypto4go"
- "log"
- "os"
- "strings"
- )
- var SysConfigDir = ""
- const (
- MD5_SALT = "keiven"
- )
- var (
- publicKey []byte
- privateKey []byte
- )
- // InitEncrypt
- // @Description: 初始化秘钥
- func InitEncrypt(pubKey, priKey string) {
- publicKey = []byte(pubKey)
- privateKey = []byte(priKey)
- //GenerateRSAKey(1024 * 4)
- }
- // 生成RSA私钥和公钥,保存到文件中
- func GenerateRSAKey(bits int) {
- //GenerateKey函数使用随机数据生成器random生成一对具有指定字位数的RSA密钥
- //Reader是一个全局、共享的密码用强随机数生成器
- privateKey, err := rsa.GenerateKey(rand.Reader, bits)
- if err != nil {
- panic(err)
- }
- //保存私钥
- //通过x509标准将得到的ras私钥序列化为ASN.1 的 DER编码字符串
- X509PrivateKey := x509.MarshalPKCS1PrivateKey(privateKey)
- //使用pem格式对x509输出的内容进行编码
- //创建文件保存私钥
- privateFile, err := os.Create(SysConfigDir + "private.pem")
- if err != nil {
- panic(err)
- }
- defer privateFile.Close()
- //构建一个pem.Block结构体对象
- privateBlock := pem.Block{Type: "RSA Private Key", Bytes: X509PrivateKey}
- //将数据保存到文件
- pem.Encode(privateFile, &privateBlock)
- //保存公钥
- //获取公钥的数据
- publicKey := privateKey.PublicKey
- //X509对公钥编码
- X509PublicKey, err := x509.MarshalPKIXPublicKey(&publicKey)
- if err != nil {
- panic(err)
- }
- //pem格式编码
- //创建用于保存公钥的文件
- publicFile, err := os.Create(SysConfigDir + "public.pem")
- if err != nil {
- panic(err)
- }
- defer publicFile.Close()
- //创建一个pem.Block结构体对象
- publicBlock := pem.Block{Type: "RSA Public Key", Bytes: X509PublicKey}
- //保存到文件
- pem.Encode(publicFile, &publicBlock)
- }
- func RSA_DecryptLong(cipherText []byte, paths ...string) ([]byte, error) {
- path := SysConfigDir + "private.pem"
- if len(paths) > 0 {
- path = paths[0]
- }
- //打开文件
- file, err := os.Open(path)
- if err != nil {
- return nil, err
- }
- defer file.Close()
- //获取文件内容
- info, err := file.Stat()
- if err != nil {
- return nil, err
- }
- buf := make([]byte, info.Size())
- file.Read(buf)
- //pem解码
- block, _ := pem.Decode(buf)
- //X509解码
- priKey, err := x509.ParsePKCS1PrivateKey(block.Bytes)
- if err != nil {
- return nil, err
- }
- path2 := SysConfigDir + "public.pem"
- if len(paths) > 0 {
- path2 = paths[0]
- }
- //打开文件
- file2, err := os.Open(path2)
- if err != nil {
- panic(err)
- }
- defer file2.Close()
- //读取文件的内容
- info2, _ := file2.Stat()
- buf2 := make([]byte, info2.Size())
- file2.Read(buf2)
- //pem解码
- block2, _ := pem.Decode(buf2)
- //x509解码
- publicKeyInterface, err := x509.ParsePKIXPublicKey(block2.Bytes)
- if err != nil {
- panic(err)
- }
- //类型断言
- pubKey := publicKeyInterface.(*rsa.PublicKey)
- partLen := pubKey.N.BitLen() / 8
- chunks := split(cipherText, partLen)
- buffer := bytes.NewBufferString("")
- for _, chunk := range chunks {
- //对密文进行解密
- plainText, err := rsa.DecryptPKCS1v15(rand.Reader, priKey, chunk)
- if err != nil {
- return nil, err
- }
- buffer.Write(plainText)
- }
- //返回明文
- return []byte(buffer.String()), nil
- }
- func split(buf []byte, lim int) [][]byte {
- var chunk []byte
- chunks := make([][]byte, 0, len(buf)/lim+1)
- for len(buf) >= lim {
- chunk, buf = buf[:lim], buf[lim:]
- chunks = append(chunks, chunk)
- }
- if len(buf) > 0 {
- chunks = append(chunks, buf[:len(buf)])
- }
- return chunks
- }
- // RSA_Encrypt
- // @Description: RSA加密,当前端传过来时需要使用
- // @param plainText
- // @param path
- // @return []byte
- func RSA_Encrypt(plainText []byte, paths ...string) []byte {
- path := SysConfigDir + "public.pem"
- if len(paths) > 0 {
- path = paths[0]
- }
- //打开文件
- file, err := os.Open(path)
- if err != nil {
- panic(err)
- }
- defer file.Close()
- //读取文件的内容
- info, _ := file.Stat()
- buf := make([]byte, info.Size())
- file.Read(buf)
- log.Println(string(buf))
- //pem解码
- block, _ := pem.Decode(buf)
- //x509解码
- publicKeyInterface, err := x509.ParsePKIXPublicKey(block.Bytes)
- if err != nil {
- panic(err)
- }
- //类型断言
- pubKey := publicKeyInterface.(*rsa.PublicKey)
- //对明文进行加密
- cipherText, err := rsa.EncryptPKCS1v15(rand.Reader, pubKey, plainText)
- if err != nil {
- panic(err)
- }
- //返回密文
- return cipherText
- }
- // RSA_Decrypt
- // @Description: RSA解密
- // @param cipherText
- // @param paths
- // @return []byte
- // @return error
- func RSA_Decrypt(cipherText []byte, paths ...string) ([]byte, error) {
- path := SysConfigDir + "private.pem"
- if len(paths) > 0 {
- path = paths[0]
- }
- //打开文件
- file, err := os.Open(path)
- if err != nil {
- return nil, err
- }
- defer file.Close()
- //获取文件内容
- info, err := file.Stat()
- if err != nil {
- return nil, err
- }
- buf := make([]byte, info.Size())
- file.Read(buf)
- //pem解码
- block, _ := pem.Decode(buf)
- //X509解码
- priKey, err := x509.ParsePKCS1PrivateKey(block.Bytes)
- if err != nil {
- return nil, err
- }
- //对密文进行解密
- plainText, err := rsa.DecryptPKCS1v15(rand.Reader, priKey, cipherText)
- if err != nil {
- return nil, err
- }
- //返回明文
- return plainText, nil
- }
- // Md5Crypt 加盐MD5加密
- // @params str 需要加密的字符串
- // @params salt interface{} 加密的盐
- // @return str 返回md5码
- func Md5Crypt(str string, salt ...interface{}) (CryptStr string) {
- if l := len(salt); l > 0 {
- slice := make([]string, l+1)
- str = fmt.Sprintf(str+strings.Join(slice, "%v"), salt...)
- }
- return fmt.Sprintf("%x", md5.Sum([]byte(str)))
- }
- // MD5Bytes 数据块MD5计算函数
- func MD5Bytes(s []byte) string {
- ret := md5.Sum(s)
- return fmt.Sprintf("%x", ret)
- }
- // MD5 计算字符串MD5值
- func MD5(s string) string {
- return MD5Bytes([]byte(s))
- }
- // EncryptDES_CBC CBC加密
- func EncryptDES_CBC(src, key string) string {
- data := []byte(src)
- keyByte := []byte(key)
- block, err := des.NewCipher(keyByte)
- if err != nil {
- panic(err)
- }
- data = PKCS5Padding(data, block.BlockSize())
- //获取CBC加密模式
- iv := keyByte //用密钥作为向量(不建议这样使用)
- mode := cipher.NewCBCEncrypter(block, iv)
- out := make([]byte, len(data))
- mode.CryptBlocks(out, data)
- return fmt.Sprintf("%X", out)
- }
- // CBC解密
- func DecryptDES_CBC(src, key string) string {
- keyByte := []byte(key)
- data, err := hex.DecodeString(src)
- if err != nil {
- panic(err)
- }
- block, err := des.NewCipher(keyByte)
- if err != nil {
- panic(err)
- }
- iv := keyByte //用密钥作为向量(不建议这样使用)
- mode := cipher.NewCBCDecrypter(block, iv)
- plaintext := make([]byte, len(data))
- mode.CryptBlocks(plaintext, data)
- plaintext = PKCS5UnPadding(plaintext)
- return string(plaintext)
- }
- // ECB加密
- func EncryptDES_ECB(src, key string) string {
- data := []byte(src)
- keyByte := []byte(key)
- block, err := des.NewCipher(keyByte)
- if err != nil {
- panic(err)
- }
- bs := block.BlockSize()
- //对明文数据进行补码
- data = PKCS5Padding(data, bs)
- if len(data)%bs != 0 {
- panic("Need a multiple of the blocksize")
- }
- out := make([]byte, len(data))
- dst := out
- for len(data) > 0 {
- //对明文按照blocksize进行分块加密
- //必要时可以使用go关键字进行并行加密
- block.Encrypt(dst, data[:bs])
- data = data[bs:]
- dst = dst[bs:]
- }
- return fmt.Sprintf("%X", out)
- }
- // ECB解密
- func DecryptDES_ECB(src, key string) string {
- data, err := hex.DecodeString(src)
- if err != nil {
- panic(err)
- }
- keyByte := []byte(key)
- block, err := des.NewCipher(keyByte)
- if err != nil {
- panic(err)
- }
- bs := block.BlockSize()
- if len(data)%bs != 0 {
- panic("crypto/cipher: input not full blocks")
- }
- out := make([]byte, len(data))
- dst := out
- for len(data) > 0 {
- block.Decrypt(dst, data[:bs])
- data = data[bs:]
- dst = dst[bs:]
- }
- out = PKCS5UnPadding(out)
- return string(out)
- }
- // 明文补码算法
- func PKCS5Padding(ciphertext []byte, blockSize int) []byte {
- padding := blockSize - len(ciphertext)%blockSize
- padtext := bytes.Repeat([]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)]
- }
- // RsaEncrypt Rsa加密
- func RsaEncrypt(origData []byte) ([]byte, error) {
- block, _ := pem.Decode(publicKey)
- publicKeyInterface, err := x509.ParsePKIXPublicKey(block.Bytes)
- if err != nil {
- panic(err)
- }
- //类型断言
- pubKey := publicKeyInterface.(*rsa.PublicKey)
- encryptedBytes, err := rsa.EncryptPKCS1v15(rand.Reader, pubKey, origData)
- return encryptedBytes, err
- }
- // RsaDecrypt Rsa解密
- func RsaDecrypt(cipherText []byte) ([]byte, error) {
- //解密
- block, _ := pem.Decode(privateKey)
- if block == nil {
- return nil, errors.New("private key error!")
- }
- //解析PKCS1格式的私钥
- priv, err := x509.ParsePKCS1PrivateKey(block.Bytes)
- if err != nil {
- return nil, err
- }
- //解密密文
- return rsa.DecryptPKCS1v15(rand.Reader, priv, cipherText)
- }
- func RSADecryptByPrivateKey(data string, privateKey string) (string, error) {
- priKey, err := crypto4go.ParsePKCS1PrivateKey(crypto4go.FormatPKCS1PrivateKey(string(privateKey)))
- if err != nil {
- priKey, err = crypto4go.ParsePKCS8PrivateKey(crypto4go.FormatPKCS8PrivateKey(string(privateKey)))
- if err != nil {
- fmt.Println("ParsePKCS8PrivateKey : ", err.Error())
- return "", err
- }
- }
- // 转成base64
- key, err := base64.StdEncoding.DecodeString(data)
- if err != nil {
- fmt.Println("base64.RawURLEncoding.DecodeString : ", err.Error())
- return "", err
- }
- partLen := priKey.N.BitLen() / 8
- chunks := split([]byte(key), partLen)
- buffer := bytes.NewBufferString("")
- for _, chunk := range chunks {
- decrypted, err := rsa.DecryptPKCS1v15(rand.Reader, priKey, chunk)
- if err != nil {
- return "", err
- }
- buffer.Write(decrypted)
- }
- return buffer.String(), err
- }
|