发布时间:2024-11-21 22:12:00
非对称加密是一种非常重要且常用的密码学技术,它允许使用不同的密钥进行加密和解密。而数字签名则是非对称加密的一个重要应用,用于确认数据的完整性和身份认证。
非对称加密又被称为公私钥加密,它使用一对密钥:公钥和私钥。公钥可以公开,而私钥必须保密。使用公钥加密的数据只能使用相应的私钥进行解密,而使用私钥签名的数据只能使用相应的公钥进行验证。这样,非对称加密确保了数据的机密性和完整性。
数字签名用于验证数据的完整性和身份认证。发送者使用自己的私钥对数据进行签名,接收者使用发送者的公钥进行验签。如果验签成功,则说明数据没有被篡改,并且发送者的身份是可信的。
在golang中,我们可以使用crypto包来实现非对称加密与数字签名。首先,生成公私钥对:
```go package main import ( "crypto/rand" "crypto/rsa" "crypto/x509" "encoding/pem" "fmt" "os" ) func main() { privateKey, err := rsa.GenerateKey(rand.Reader, 2048) if err != nil { fmt.Println(err) os.Exit(1) } privateKeyFile, err := os.Create("private.pem") if err != nil { fmt.Println(err) os.Exit(1) } privateKeyPem := &pem.Block{ Type: "PRIVATE KEY", Bytes: x509.MarshalPKCS1PrivateKey(privateKey), } err = pem.Encode(privateKeyFile, privateKeyPem) if err != nil { fmt.Println(err) os.Exit(1) } privateKeyFile.Close() publicKey := privateKey.PublicKey publicKeyFile, err := os.Create("public.pem") if err != nil { fmt.Println(err) os.Exit(1) } publicKeyPem := &pem.Block{ Type: "PUBLIC KEY", Bytes: x509.MarshalPKCS1PublicKey(&publicKey), } err = pem.Encode(publicKeyFile, publicKeyPem) if err != nil { fmt.Println(err) os.Exit(1) } publicKeyFile.Close() } ``` 这段代码中,我们使用`rsa.GenerateKey`函数生成了一个2048位的RSA私钥,并导出了对应的公钥,分别保存在`private.pem`和`public.pem`文件中。 接下来,我们可以使用私钥进行签名,公钥进行验签: ```go package main import ( "crypto" "crypto/rand" "crypto/rsa" "crypto/sha256" "crypto/x509" "encoding/pem" "fmt" "io/ioutil" "os" ) func main() { data := []byte("hello world") privateKeyFile, err := os.Open("private.pem") if err != nil { fmt.Println(err) os.Exit(1) } privateKeyBytes, err := ioutil.ReadAll(privateKeyFile) if err != nil { fmt.Println(err) os.Exit(1) } block, _ := pem.Decode(privateKeyBytes) privateKey, err := x509.ParsePKCS1PrivateKey(block.Bytes) if err != nil { fmt.Println(err) os.Exit(1) } hash := sha256.Sum256(data) signature, err := rsa.SignPKCS1v15(rand.Reader, privateKey, crypto.SHA256, hash[:]) if err != nil { fmt.Println(err) os.Exit(1) } signatureFile, err := os.Create("signature.bin") if err != nil { fmt.Println(err) os.Exit(1) } defer signatureFile.Close() _, err = signatureFile.Write(signature) if err != nil { fmt.Println(err) os.Exit(1) } publicKeyFile, err := os.Open("public.pem") if err != nil { fmt.Println(err) os.Exit(1) } publicKeyBytes, err := ioutil.ReadAll(publicKeyFile) if err != nil { fmt.Println(err) os.Exit(1) } block, _ = pem.Decode(publicKeyBytes) publicKey, err := x509.ParsePKCS1PublicKey(block.Bytes) if err != nil { fmt.Println(err) os.Exit(1) } signatureFile.Seek(0, 0) signature, err = ioutil.ReadAll(signatureFile) if err != nil { fmt.Println(err) os.Exit(1) } err = rsa.VerifyPKCS1v15(publicKey, crypto.SHA256, hash[:], signature) if err != nil { fmt.Println("Verify failed:", err) } else { fmt.Println("Verify succeeded") } } ``` 这段代码中,我们首先读取了私钥和公钥文件,并对原始数据进行SHA256哈希计算。然后,使用私钥对哈希值进行签名,并将签名结果保存到`signature.bin`文件中。 接着,我们读取公钥和签名文件,并使用公钥进行验签。如果验签成功,则说明数据没有被篡改。本文介绍了golang中非对称加密数字签名的实现方法。使用非对称加密和数字签名可以保证数据的机密性、完整性和身份认证。在实际应用中,请注意安全性和密钥管理的问题,以防止私钥泄露或者被篡改。