在Go语言中实现RSA加解密、签名验证算法,通常使用crypto/rsa
和crypto/rand
等标准库包。由于RSA通常不用于直接加密大量数据(因为性能原因和可能的数据大小限制),它更常用于加密密钥或用于数字签名。
![图片[1]_在Go语言中实现RSA签名验证与加解密算法的详细指南_知途无界](https://zhituwujie.com/wp-content/uploads/2024/05/d2b5ca33bd20240529123315.png)
以下是RSA加密(实际上是签名,因为RSA加密通常指的是使用私钥签名)、解密(实际上是验证签名,使用公钥验证签名)、签名和验证签名的示例代码:
1. 生成RSA密钥对
package mainimport ("crypto/rand""crypto/rsa""crypto/x509""encoding/pem""fmt""os")func generateKeyPair(bits int) (*rsa.PrivateKey, error) {return rsa.GenerateKey(rand.Reader, bits)}func savePrivateKey(privateKey *rsa.PrivateKey, filename string) error {outFile, err := os.Create(filename)if err != nil {return err}defer outFile.Close()privateKeyPEM := &pem.Block{Type: "RSA PRIVATE KEY",Bytes: x509.MarshalPKCS1PrivateKey(privateKey),}err = pem.Encode(outFile, privateKeyPEM)if err != nil {return err}return nil}func main() {bits := 2048 // 通常使用2048位或更大的密钥privateKey, err := generateKeyPair(bits)if err != nil {fmt.Println(err)return}err = savePrivateKey(privateKey, "private_key.pem")if err != nil {fmt.Println(err)return}publicKey := &privateKey.PublicKey// ... 可以保存公钥,但在此示例中我们仅使用它}package main import ( "crypto/rand" "crypto/rsa" "crypto/x509" "encoding/pem" "fmt" "os" ) func generateKeyPair(bits int) (*rsa.PrivateKey, error) { return rsa.GenerateKey(rand.Reader, bits) } func savePrivateKey(privateKey *rsa.PrivateKey, filename string) error { outFile, err := os.Create(filename) if err != nil { return err } defer outFile.Close() privateKeyPEM := &pem.Block{ Type: "RSA PRIVATE KEY", Bytes: x509.MarshalPKCS1PrivateKey(privateKey), } err = pem.Encode(outFile, privateKeyPEM) if err != nil { return err } return nil } func main() { bits := 2048 // 通常使用2048位或更大的密钥 privateKey, err := generateKeyPair(bits) if err != nil { fmt.Println(err) return } err = savePrivateKey(privateKey, "private_key.pem") if err != nil { fmt.Println(err) return } publicKey := &privateKey.PublicKey // ... 可以保存公钥,但在此示例中我们仅使用它 }package main import ( "crypto/rand" "crypto/rsa" "crypto/x509" "encoding/pem" "fmt" "os" ) func generateKeyPair(bits int) (*rsa.PrivateKey, error) { return rsa.GenerateKey(rand.Reader, bits) } func savePrivateKey(privateKey *rsa.PrivateKey, filename string) error { outFile, err := os.Create(filename) if err != nil { return err } defer outFile.Close() privateKeyPEM := &pem.Block{ Type: "RSA PRIVATE KEY", Bytes: x509.MarshalPKCS1PrivateKey(privateKey), } err = pem.Encode(outFile, privateKeyPEM) if err != nil { return err } return nil } func main() { bits := 2048 // 通常使用2048位或更大的密钥 privateKey, err := generateKeyPair(bits) if err != nil { fmt.Println(err) return } err = savePrivateKey(privateKey, "private_key.pem") if err != nil { fmt.Println(err) return } publicKey := &privateKey.PublicKey // ... 可以保存公钥,但在此示例中我们仅使用它 }
2. 签名和验证签名
package mainimport ("crypto/rand""crypto/rsa""crypto/sha256""fmt""io/ioutil""os")func signData(message []byte, privateKey *rsa.PrivateKey) ([]byte, error) {h := sha256.New()h.Write(message)hashed := h.Sum(nil)return rsa.SignPKCS1v15(rand.Reader, privateKey, crypto.SHA256, hashed)}func verifySignature(message, signature []byte, publicKey *rsa.PublicKey) error {h := sha256.New()h.Write(message)hashed := h.Sum(nil)return rsa.VerifyPKCS1v15(publicKey, crypto.SHA256, hashed, signature)}func main() {// 假设你已经有了私钥和公钥,或者从文件中加载了它们// 在这里我们只是简单地模拟它们// ... 加载私钥和公钥的代码 ...message := []byte("Hello, RSA!")fmt.Printf("Original message: %s\n", message)// 签名消息signature, err := signData(message, privateKey)if err != nil {fmt.Println(err)return}fmt.Printf("Signature: %x\n", signature)// 验证签名err = verifySignature(message, signature, publicKey)if err != nil {fmt.Println("Signature verification failed:", err)} else {fmt.Println("Signature verification succeeded!")}}package main import ( "crypto/rand" "crypto/rsa" "crypto/sha256" "fmt" "io/ioutil" "os" ) func signData(message []byte, privateKey *rsa.PrivateKey) ([]byte, error) { h := sha256.New() h.Write(message) hashed := h.Sum(nil) return rsa.SignPKCS1v15(rand.Reader, privateKey, crypto.SHA256, hashed) } func verifySignature(message, signature []byte, publicKey *rsa.PublicKey) error { h := sha256.New() h.Write(message) hashed := h.Sum(nil) return rsa.VerifyPKCS1v15(publicKey, crypto.SHA256, hashed, signature) } func main() { // 假设你已经有了私钥和公钥,或者从文件中加载了它们 // 在这里我们只是简单地模拟它们 // ... 加载私钥和公钥的代码 ... message := []byte("Hello, RSA!") fmt.Printf("Original message: %s\n", message) // 签名消息 signature, err := signData(message, privateKey) if err != nil { fmt.Println(err) return } fmt.Printf("Signature: %x\n", signature) // 验证签名 err = verifySignature(message, signature, publicKey) if err != nil { fmt.Println("Signature verification failed:", err) } else { fmt.Println("Signature verification succeeded!") } }package main import ( "crypto/rand" "crypto/rsa" "crypto/sha256" "fmt" "io/ioutil" "os" ) func signData(message []byte, privateKey *rsa.PrivateKey) ([]byte, error) { h := sha256.New() h.Write(message) hashed := h.Sum(nil) return rsa.SignPKCS1v15(rand.Reader, privateKey, crypto.SHA256, hashed) } func verifySignature(message, signature []byte, publicKey *rsa.PublicKey) error { h := sha256.New() h.Write(message) hashed := h.Sum(nil) return rsa.VerifyPKCS1v15(publicKey, crypto.SHA256, hashed, signature) } func main() { // 假设你已经有了私钥和公钥,或者从文件中加载了它们 // 在这里我们只是简单地模拟它们 // ... 加载私钥和公钥的代码 ... message := []byte("Hello, RSA!") fmt.Printf("Original message: %s\n", message) // 签名消息 signature, err := signData(message, privateKey) if err != nil { fmt.Println(err) return } fmt.Printf("Signature: %x\n", signature) // 验证签名 err = verifySignature(message, signature, publicKey) if err != nil { fmt.Println("Signature verification failed:", err) } else { fmt.Println("Signature verification succeeded!") } }
注意:
- 在上述
signData
和verifySignature
函数中,我使用了crypto/sha256
进行哈希计算,但我没有在函数签名中显式导入它。在实际代码中,你需要导入它。 - 你需要处理私钥和公钥的加载和存储。在上述示例中,我展示了如何生成和保存私钥,但没有展示如何从文件中加载公钥。
- RSA签名通常使用PKCS#1 v1.5填充或PSS(概率签名方案),但在上述示例中,为了简单起见,我使用了PKCS#1 v1.5。
- 对于加密和解密大量数据,你应该使用混合加密系统(如RSA-AES),其中RSA用于安全地交换AES密钥
© 版权声明
文中内容均来源于公开资料,受限于信息的时效性和复杂性,可能存在误差或遗漏。我们已尽力确保内容的准确性,但对于因信息变更或错误导致的任何后果,本站不承担任何责任。如需引用本文内容,请注明出处并尊重原作者的版权。
THE END
暂无评论内容