Golang中非对称加密与验证机制的理解与实践
Golang中非对称加密与验证机制的理解与实践 我想理解RSA或椭圆曲线验证。我的最终目标是编写一个简单的玩具程序,让Alice可以输入“Alice”作为字符串标识符,并生成一个字符串/字节切片,Bob可以用它来验证消息来自Alice而不是Charley。我以前在我的个人工具中使用过Bcrypt来保护密码(需要澄清的是,我还没有制作出需要安全性的东西,并且我写的代码得到了他人的信任),并且能够很好地理解它,但不知为何,我在这个问题上遇到了思维障碍。我阅读了关于RSA和椭圆曲线的Go文档,但不知为何,我就是不理解。
func main() {
fmt.Println("hello world")
}
更多关于Golang中非对称加密与验证机制的理解与实践的实战教程也可以访问 https://www.itying.com/category-94-b0.html
2 回复
更多关于Golang中非对称加密与验证机制的理解与实践的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html
在Go中实现非对称加密的验证机制,通常使用RSA或ECDSA签名方案。以下是完整的示例代码,展示Alice如何生成密钥对并签名消息,Bob如何验证签名:
package main
import (
"crypto"
"crypto/rand"
"crypto/rsa"
"crypto/sha256"
"crypto/x509"
"encoding/base64"
"encoding/pem"
"fmt"
"log"
)
// Alice生成RSA密钥对
func generateKeyPair() (*rsa.PrivateKey, error) {
privateKey, err := rsa.GenerateKey(rand.Reader, 2048)
if err != nil {
return nil, err
}
return privateKey, nil
}
// Alice使用私钥对消息签名
func signMessage(privateKey *rsa.PrivateKey, message string) (string, error) {
hashed := sha256.Sum256([]byte(message))
signature, err := rsa.SignPKCS1v15(rand.Reader, privateKey, crypto.SHA256, hashed[:])
if err != nil {
return "", err
}
return base64.StdEncoding.EncodeToString(signature), nil
}
// Bob使用公钥验证签名
func verifySignature(publicKey *rsa.PublicKey, message, signature string) (bool, error) {
sigBytes, err := base64.StdEncoding.DecodeString(signature)
if err != nil {
return false, err
}
hashed := sha256.Sum256([]byte(message))
err = rsa.VerifyPKCS1v15(publicKey, crypto.SHA256, hashed[:], sigBytes)
return err == nil, nil
}
// 将私钥转换为PEM格式字符串
func privateKeyToPEM(privateKey *rsa.PrivateKey) string {
privBytes := x509.MarshalPKCS1PrivateKey(privateKey)
privPem := pem.EncodeToMemory(&pem.Block{
Type: "RSA PRIVATE KEY",
Bytes: privBytes,
})
return string(privPem)
}
// 将公钥转换为PEM格式字符串
func publicKeyToPEM(publicKey *rsa.PublicKey) (string, error) {
pubBytes, err := x509.MarshalPKIXPublicKey(publicKey)
if err != nil {
return "", err
}
pubPem := pem.EncodeToMemory(&pem.Block{
Type: "PUBLIC KEY",
Bytes: pubBytes,
})
return string(pubPem), nil
}
func main() {
// Alice生成密钥对
alicePrivateKey, err := generateKeyPair()
if err != nil {
log.Fatal(err)
}
alicePublicKey := &alicePrivateKey.PublicKey
// Alice签名消息
message := "Hello Bob, this is Alice"
signature, err := signMessage(alicePrivateKey, message)
if err != nil {
log.Fatal(err)
}
fmt.Printf("Alice的消息: %s\n", message)
fmt.Printf("Alice的签名: %s\n", signature)
fmt.Printf("Alice的公钥(PEM):\n%s\n", publicKeyToPEM(alicePublicKey))
// Bob验证签名
valid, err := verifySignature(alicePublicKey, message, signature)
if err != nil {
log.Fatal(err)
}
if valid {
fmt.Println("✓ Bob验证成功:消息确实来自Alice")
} else {
fmt.Println("✗ Bob验证失败:消息可能被篡改或来自Charley")
}
// 尝试用错误的消息验证
wrongMessage := "Hello Bob, this is Charley"
valid, _ = verifySignature(alicePublicKey, wrongMessage, signature)
if !valid {
fmt.Println("✓ Bob检测到Charley的伪造消息")
}
}
如果需要椭圆曲线(ECDSA)版本,以下是实现示例:
package main
import (
"crypto/ecdsa"
"crypto/elliptic"
"crypto/rand"
"crypto/sha256"
"crypto/x509"
"encoding/base64"
"encoding/pem"
"fmt"
"log"
"math/big"
)
// Alice生成ECDSA密钥对
func generateECDSAKeyPair() (*ecdsa.PrivateKey, error) {
return ecdsa.GenerateKey(elliptic.P256(), rand.Reader)
}
// Alice使用私钥对消息签名
func signMessageECDSA(privateKey *ecdsa.PrivateKey, message string) (string, error) {
hashed := sha256.Sum256([]byte(message))
r, s, err := ecdsa.Sign(rand.Reader, privateKey, hashed[:])
if err != nil {
return "", err
}
// 将r和s组合为签名
signature := append(r.Bytes(), s.Bytes()...)
return base64.StdEncoding.EncodeToString(signature), nil
}
// Bob使用公钥验证签名
func verifySignatureECDSA(publicKey *ecdsa.PublicKey, message, signature string) (bool, error) {
sigBytes, err := base64.StdEncoding.DecodeString(signature)
if err != nil {
return false, err
}
// 分割r和s
keySize := publicKey.Curve.Params().BitSize / 8
if len(sigBytes) != 2*keySize {
return false, fmt.Errorf("invalid signature length")
}
r := new(big.Int).SetBytes(sigBytes[:keySize])
s := new(big.Int).SetBytes(sigBytes[keySize:])
hashed := sha256.Sum256([]byte(message))
return ecdsa.Verify(publicKey, hashed[:], r, s), nil
}
func main() {
// Alice生成ECDSA密钥对
alicePrivateKey, err := generateECDSAKeyPair()
if err != nil {
log.Fatal(err)
}
alicePublicKey := &alicePrivateKey.PublicKey
// Alice签名消息
message := "Hello Bob, this is Alice"
signature, err := signMessageECDSA(alicePrivateKey, message)
if err != nil {
log.Fatal(err)
}
fmt.Printf("Alice的消息: %s\n", message)
fmt.Printf("Alice的ECDSA签名: %s\n", signature)
// Bob验证签名
valid, err := verifySignatureECDSA(alicePublicKey, message, signature)
if err != nil {
log.Fatal(err)
}
if valid {
fmt.Println("✓ Bob验证成功:ECDSA签名有效")
} else {
fmt.Println("✗ Bob验证失败:ECDSA签名无效")
}
}
这两个示例展示了非对称加密验证的核心机制:Alice使用私钥生成签名,Bob使用公钥验证签名。任何人都可以获得Alice的公钥,但只有Alice拥有私钥,因此只有她能生成有效的签名。

