• Go语言中实现的RSA加解密功能代码
  • 发布于 2个月前
  • 201 热度
    0 评论
RSA 是一种非对称加密算法,它的名字是由它的三位开发者,即 Ron.Rivest、Adi.Shamir 和 Leonard.Adleman 的姓氏的首字母组成的(Rivest-Shamir-Adleman),可用于数据加密和数字签名。用于数据加密时,消息发送方利用对方的公钥进行加密,消息接受方收到密文时使用自己的私钥进行解密。

 如下代码,包含了生成密钥和加解密:(其中包含了 byte 类型和 base64 类型互相转换的操作)
package main
import (
    "crypto/rand"
    "crypto/rsa"
    "crypto/x509"
    "encoding/base64"
    "encoding/pem"
    "fmt"
    "os"
)

func main() {
    // 堆代码 duidaima.com
    // 生成密钥对,保存到文件
    GenerateRSAKey(2048)
    message: = [] byte("rsa 加密解密测试!")
        // 加密
    cipherText: = RSA_Encrypt(message, "public.pem")
    cipherText_base64: = base64.StdEncoding.EncodeToString(cipherText) // 将 []byte 类型的密文转换为 base64 字符串
    fmt.Println("加密后为(base64):", cipherText_base64)
    fmt.Println("加密后为([]byte):", cipherText)
        // 解密
    cipherText, _ = base64.StdEncoding.DecodeString(cipherText_base64) // 若转换为输入为 base64 字符串,则需先解码为 []byte
    plainText: = RSA_Decrypt(cipherText, "private.pem")
    fmt.Println("解密后为([]byte):", plainText)
    fmt.Println("解密后为(string):", string(plainText))
}

// 生成 RSA 私钥和公钥,保存到文件中
func GenerateRSAKey(bits int) {
    // GenerateKey 函数使用随机数据生成器 random 生成一对具有指定字位数的 RSA 密钥
    // Reader 是一个全局、共享的密码用强随机数生成器
    privateKey, err: = rsa.GenerateKey(rand.Reader, bits)
    if err != nil {
            panic(err)
        }
        // 保存私钥
        // 通过 x509 标准将得到的 ras 私钥序列化为 ASN.1 的 DER 编码字符串
    X509PrivateKey: = x509.MarshalPKCS1PrivateKey(privateKey)
        // 使用 pem 格式对 x509 输出的内容进行编码
        // 创建文件保存私钥
    privateFile, err: = os.Create("private.pem")
    if err != nil {
        panic(err)
    }
    defer privateFile.Close()
        // 构建一个 pem.Block 结构体对象
    privateBlock: = pem.Block {
            Type: "RSA Private Key",
            Bytes: X509PrivateKey
        }
        // 将数据保存到文件
    pem.Encode(privateFile, & privateBlock)
        // 保存公钥
        // 获取公钥的数据
    publicKey: = privateKey.PublicKey
        // X509 对公钥编码
    X509PublicKey, err: = x509.MarshalPKIXPublicKey( & publicKey)
    if err != nil {
            panic(err)
        }
        // pem 格式编码
        // 创建用于保存公钥的文件
    publicFile, err: = os.Create("public.pem")
    if err != nil {
        panic(err)
    }
    defer publicFile.Close()
        // 创建一个 pem.Block 结构体对象
    publicBlock: = pem.Block {
            Type: "RSA Public Key",
            Bytes: X509PublicKey
        }
        // 保存到文件
    pem.Encode(publicFile, & publicBlock)
}

// RSA 加密
func RSA_Encrypt(plainText[] byte, path string)[] byte {
    // 打开文件
    file, err: = os.Open(path)
    if err != nil {
        panic(err)
    }
    defer file.Close()
        // 读取文件的内容
    info, _: = file.Stat()
    buf: = make([] byte, info.Size())
    file.Read(buf)
        // pem 解码
    block, _: = pem.Decode(buf)
        // x509 解码
    publicKeyInterface, err: = x509.ParsePKIXPublicKey(block.Bytes)
    if err != nil {
            panic(err)
        }
        // 类型断言
    publicKey: = publicKeyInterface.( * rsa.PublicKey)
        // 对明文进行加密
    cipherText, err: = rsa.EncryptPKCS1v15(rand.Reader, publicKey, plainText)
    if err != nil {
            panic(err)
        }
        // 返回 []byte 密文
    return cipherText
}

// RSA 解密
func RSA_Decrypt(cipherText[] byte, path string)[] byte {
    // 打开文件
    file, err: = os.Open(path)
    if err != nil {
        panic(err)
    }
    defer file.Close()
        // 获取文件内容
    info, _: = file.Stat()
    buf: = make([] byte, info.Size())
    file.Read(buf)
        // pem 解码
    block, _: = pem.Decode(buf)
        // X509 解码
    privateKey, err: = x509.ParsePKCS1PrivateKey(block.Bytes)
    if err != nil {
            panic(err)
        }
        // 对密文进行解密
    plainText, _: = rsa.DecryptPKCS1v15(rand.Reader, privateKey, cipherText)
        // 返回明文
    return plainText
}
运行生成密钥方法后,main.go 的同级目录下,回自动生成两个 .pem 后缀的密钥文件:

下面是加解密输出的结果:

用户评论