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 后缀的密钥文件:
下面是加解密输出的结果: