package wafsec import ( "bytes" "crypto" "crypto/rand" "crypto/rsa" "crypto/sha256" "crypto/x509" "encoding/pem" "errors" "fmt" "os" ) type CryptoUtil struct { } // 生成密钥对 func (r *CryptoUtil) CreateKeys(bits int) (prvkey, pubkey []byte) { // 生成私钥文件 privateKey, err := rsa.GenerateKey(rand.Reader, bits) if err != nil { panic(err) } derStream := x509.MarshalPKCS1PrivateKey(privateKey) block := &pem.Block{ Type: "RSA PRIVATE KEY", Bytes: derStream, } prvkey = pem.EncodeToMemory(block) publicKey := &privateKey.PublicKey derPkix, err := x509.MarshalPKIXPublicKey(publicKey) if err != nil { panic(err) } block = &pem.Block{ Type: "PUBLIC KEY", Bytes: derPkix, } pubkey = pem.EncodeToMemory(block) return } // 公钥加密 func (r *CryptoUtil) RsaEncrypt(data, keyBytes []byte) ([]byte, error) { //解密pem格式的公钥 block, _ := pem.Decode(keyBytes) if block == nil { panic(errors.New("public key error")) } // 解析公钥 pubInterface, err := x509.ParsePKIXPublicKey(block.Bytes) if err != nil { panic(err) } // 类型断言 pub := pubInterface.(*rsa.PublicKey) partLen := pub.N.BitLen()/8 - 11 chunks := split([]byte(data), partLen) buffer := bytes.NewBufferString("") //加密 for _, chunk := range chunks { bytes, err := rsa.EncryptPKCS1v15(rand.Reader, pub, chunk) if err != nil { return nil, err } buffer.Write(bytes) } //加密 ciphertext := buffer.Bytes() return ciphertext, nil } // 私钥解密 func (r *CryptoUtil) RsaDecrypt(ciphertext, keyBytes []byte) ([]byte, error) { //获取私钥 block, _ := pem.Decode(keyBytes) if block == nil { panic(errors.New("private key error!")) } //解析PKCS1格式的私钥 priv, err := x509.ParsePKCS1PrivateKey(block.Bytes) if err != nil { panic(err) } partLen := priv.N.BitLen() / 8 chunks := split([]byte(ciphertext), partLen) // 解密 buffer := bytes.NewBufferString("") for _, chunk := range chunks { decrypted, err := rsa.DecryptPKCS1v15(rand.Reader, priv, chunk) if err != nil { return nil, err } buffer.Write(decrypted) } return buffer.Bytes(), nil } // 签名 func (r *CryptoUtil) RsaSignWithSha256(data []byte, keyBytes []byte) ([]byte, error) { h := sha256.New() h.Write(data) hashed := h.Sum(nil) block, _ := pem.Decode(keyBytes) if block == nil { return nil, errors.New(fmt.Sprintf("private key error: ")) } privateKey, err := x509.ParsePKCS1PrivateKey(block.Bytes) if err != nil { return nil, errors.New(fmt.Sprintf("ParsePKCS8PrivateKey: %s\n", err)) } signature, err := rsa.SignPKCS1v15(rand.Reader, privateKey, crypto.SHA256, hashed) if err != nil { return nil, errors.New(fmt.Sprintf("Error from signing: %s\n", err)) } return signature, nil } // 验证 func (r *CryptoUtil) RsaVerySignWithSha256(data, signData, keyBytes []byte) bool { block, _ := pem.Decode(keyBytes) if block == nil { panic(errors.New("public key error")) } pubKey, err := x509.ParsePKIXPublicKey(block.Bytes) if err != nil { panic(err) } hashed := sha256.Sum256(data) err = rsa.VerifyPKCS1v15(pubKey.(*rsa.PublicKey), crypto.SHA256, hashed[:], signData) if err != nil { panic(err) } return true } 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 } func (r *CryptoUtil) File2Bytes(filename string) ([]byte, error) { // File file, err := os.Open(filename) if err != nil { return nil, err } defer file.Close() // FileInfo: stats, err := file.Stat() if err != nil { return nil, err } // []byte data := make([]byte, stats.Size()) count, err := file.Read(data) if err != nil { return nil, err } fmt.Printf("read file %s len: %d \n", filename, count) return data, nil }