Golang 实现 RSA 签名与验证:密钥生成及应用详解

文章目录

在这篇文章中,我们将深入探讨 RSA 算法及其在 Go 语言中的实现方法,帮助你理解如何安全地加密和签名数据。

什么是 RSA 加密?

RSA(Rivest–Shamir–Adleman)是一种广泛使用的非对称加密算法。它通过生成一对密钥(公钥和私钥)来实现数据加密与解密。公钥可以公开,而私钥则需妥善保管。

RSA 加密工作原理

公钥用于加密数据,而私钥用于解密。以下是基本的流程:

  1. 加密过程:使用公钥加密数据。
    data -----------|
                    |
                    -----RSA 加密-----加密数据
                    |
    public key -----|
    
  2. 解密过程:使用私钥解密数据。
    加密数据 -------|
                    |
                    -----RSA 解密-----data
                    |
    private key ----|
    

这意味着任何人都可以使用你的公钥加密信息,而只有拥有私钥的人可以解密。

如何生成 RSA 密钥

首先,我们需要生成一对 RSA 公钥和私钥。可以使用 Go 的 crypto/rsacrypto/rand 库来完成这一操作。

// GenerateKey 方法接受随机读取器和位数
privateKey, err := rsa.GenerateKey(rand.Reader, 2048)
if err != nil {
    panic(err)
}

// 获取公钥
publicKey := privateKey.PublicKey

privateKeypublicKey 将在后续的加密、解密和签名中使用。

RSA 加密数据

我们使用 EncryptOAEP 方法对消息进行加密。需要提供以下输入:

  1. 哈希函数(例如 SHA256)。
  2. 随机读取器。
  3. 生成的公钥。
  4. 要加密的消息。
encryptedBytes, err := rsa.EncryptOAEP(
    sha256.New(),
    rand.Reader,
    &publicKey,
    []byte("超级机密信息"),
    nil)
if err != nil {
    panic(err)
}

fmt.Println("加密字节:", encryptedBytes)

RSA 解密数据

要解密数据,我们使用与加密时相对应的私钥。

decryptedBytes, err := privateKey.Decrypt(nil, encryptedBytes, &rsa.OAEPOptions{Hash: crypto.SHA256})
if err != nil {
    panic(err)
}

fmt.Println("解密消息:", string(decryptedBytes))

RSA 签名与验证

RSA 还可以用于数据签名,确保消息的真实性。签名过程如下:

  1. 使用私钥对消息进行签名。
  2. 任何人可以使用公钥验证签名。
msg := []byte("可验证的消息")
msgHash := sha256.New()
_, err = msgHash.Write(msg)
if err != nil {
    panic(err)
}
msgHashSum := msgHash.Sum(nil)

signature, err := rsa.SignPSS(rand.Reader, privateKey, crypto.SHA256, msgHashSum, nil)
if err != nil {
    panic(err)
}

err = rsa.VerifyPSS(&publicKey, crypto.SHA256, msgHashSum, signature, nil)
if err != nil {
    fmt.Println("无法验证签名:", err)
    return
}
fmt.Println("签名验证成功")

常见问题解答(FAQ)

1. 如何在 Golang 中生成公钥和私钥?

使用 rsa.GenerateKey 方法可以生成公钥和私钥。

2. RSA 算法仍然被使用吗?

是的,RSA 算法广泛应用于数据加密和数字签名。

3. 什么是 RSA 公钥?

公钥是用于加密数据的密钥,任何人都可以获取,而私钥则是解密该数据的密钥,必须保密。

总结

在本文中,我们探讨了 RSA 加密、解密、签名和验证的完整流程。需要注意的是,RSA 加密的输入数据长度应小于密钥的位数。


也可以看看