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 回复

stackoverflow.com

如何用公钥验证签名?

标签: digital-signature, public-key-encryption, private-key, public-key

更多关于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拥有私钥,因此只有她能生成有效的签名。

回到顶部