package main import ( "bytes" "crypto" "crypto/rand" "crypto/rsa" "crypto/sha512" "crypto/x509" "encoding/base64" "encoding/pem" "fmt" "os" ) // getPublicKey 获取公钥 func getPublicKey() any { // 构造公钥文件硬盘路径 rootPath, _ := os.Getwd() publicKeyFile := rootPath + "/conf/rsa/rsa_public_key.pem" // 打开公钥文件 file, err := os.Open(publicKeyFile) if err != nil { panic("打开公钥文件失败,原因:" + err.Error()) } // 关闭公钥文件 defer func(file *os.File) { err := file.Close() if err != nil { panic("关闭公钥文件失败,原因:" + err.Error()) } }(file) // 读取公钥文件 contents, _ := file.Stat() buffers := make([]byte, contents.Size()) _, err = file.Read(buffers) if err != nil { panic("读取公钥文件失败,原因:" + err.Error()) } pemDecode, _ := pem.Decode(buffers) // pem解码 publicKeyInterface, err := x509.ParsePKIXPublicKey(pemDecode.Bytes) // x509解码 if err != nil { panic("解析公钥文件失败,原因:" + err.Error()) } return publicKeyInterface } // getPrivateKey 获取私钥 func getPrivateKey() *rsa.PrivateKey { // 构造私钥文件硬盘路径 rootPath, _ := os.Getwd() privateKeyFile := rootPath + "/conf/rsa/rsa_private_key.pem" // 打开私钥文件 file, err := os.Open(privateKeyFile) if err != nil { panic("打开私钥文件失败,原因:" + err.Error()) } // 关闭私钥文件 defer func(file *os.File) { err := file.Close() if err != nil { panic("关闭私钥文件失败,原因:" + err.Error()) } }(file) // 读取私钥文件 contents, _ := file.Stat() buffers := make([]byte, contents.Size()) _, err = file.Read(buffers) if err != nil { panic("读取私钥文件失败,原因:" + err.Error()) } pemDecode, _ := pem.Decode(buffers) // pem解码 privateKey, err := x509.ParsePKCS1PrivateKey(pemDecode.Bytes) // x509解码 if err != nil { panic("解析私钥文件失败,原因:" + err.Error()) } return privateKey } // RSADecrypt 私钥解密 func RSADecrypt(ciphertext string) string { privateKey := getPrivateKey() ciphertextByte, _ := base64.StdEncoding.DecodeString(ciphertext) privateKeySize := privateKey.Size() // 私钥文件长度 ciphertextSize := len(ciphertextByte) // 消息密文长度 var offset = 0 var buffer = bytes.Buffer{} for offset < ciphertextSize { endIndex := offset + privateKeySize if endIndex > ciphertextSize { endIndex = ciphertextSize } decrypt, err := rsa.DecryptPKCS1v15(rand.Reader, privateKey, ciphertextByte[offset:endIndex]) if err != nil { panic("解密失败,原因:" + err.Error()) } buffer.Write(decrypt) offset = endIndex } return string(buffer.Bytes()) } // RSAEncrypt 公钥加密(相同的消息每次加密产生的密文都不同) func RSAEncrypt(plaintext string) string { publicKey := getPublicKey().(*rsa.PublicKey) // 类型断言 plaintextByte := []byte(plaintext) publicKeySize := publicKey.Size() // 公钥文件长度 plaintextSize := len(plaintextByte) // 消息明文长度 offset := 0 buffer := bytes.Buffer{} // 开始加密操作(分段加密) for offset < plaintextSize { endIndex := offset + publicKeySize - 11 if endIndex > plaintextSize { endIndex = plaintextSize } encrypt, err := rsa.EncryptPKCS1v15(rand.Reader, publicKey, plaintextByte[offset:endIndex]) if err != nil { panic("加密失败,原因:" + err.Error()) } buffer.Write(encrypt) offset = endIndex } return base64.StdEncoding.EncodeToString(buffer.Bytes()) } // RSASign 私钥签名(相同的消息每次生成的签名都相同) func RSASign(plaintext string) string { privateKey := getPrivateKey() hash := sha512.New() hash.Write([]byte(plaintext)) hashed := hash.Sum(nil) sign, err := rsa.SignPKCS1v15(rand.Reader, privateKey, crypto.SHA512, hashed) if err != nil { panic("生成签名失败,原因:" + err.Error()) } return base64.StdEncoding.EncodeToString(sign) } // RSAVerify 公钥验签 func RSAVerify(data string, sign string) bool { publicKey := getPublicKey().(*rsa.PublicKey) // 类型断言 sum512 := sha512.Sum512([]byte(data)) signByte, _ := base64.StdEncoding.DecodeString(sign) err := rsa.VerifyPKCS1v15(publicKey, crypto.SHA512, sum512[:], signByte) if err == nil { return true } return false } func main() { // 消息明文 message := "孩儿立志出乡关,学不成名誓不还。埋骨何须桑梓地,人生无处不青山。" //========== 加密 ==========// ciphertext := RSAEncrypt(message) fmt.Println("加密后的密文 ===> " + ciphertext) // 加密后的密文 ===> UwoKQ1aWvG+grf/NTrUlXcYxD2EniBMBtf2O++ymmzzQpm3GRHYcCS6S1sT... //========== 解密 ==========// plaintext := RSADecrypt(ciphertext) fmt.Println("解密后的明文 ===> " + plaintext) // 解密后的明文 ===> 孩儿立志出乡关,学不成名誓不还。埋骨何须桑梓地,人生无处不青山。 //========== 签名 ==========// sign := RSASign(message) fmt.Println("生成签名 ===> " + sign) // 生成签名 ===> cntcA15sxnLTzZ6prvioC1A+dRxfcHT94O6KiS0RYay5j+Sk7Ciz27ux8C6UcYS/To1dFXjza... //========== 验签 ==========// verify := RSAVerify(message, sign) fmt.Printf("验证签名 ===> %+v \r\n", verify) // 验证签名 ===> true }
Copyright © 2024 码农人生. All Rights Reserved