【代码】Go语言实现RSA加解密

前言

Go语言实现RSA加解密

生成密钥对

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
package main

import (
"crypto/rand"
"crypto/rsa"
"crypto/x509"
"encoding/base64"
"encoding/pem"
"fmt"
"os"
)

// GenerateRSAKeys 生成密钥对
// bits 指定生成密钥对位数
// generateFile 是否生成密钥文件
func GenerateRSAKeys(bits int, generateFile bool) (publicKeyBase64String string, privateKeyBase64String string) {

/* 生成私钥 */

// 生成私钥
privateKeyObject, _ := rsa.GenerateKey(rand.Reader, bits)
// 通过x509对私钥编码为字符数组
privateKeyByteArray := x509.MarshalPKCS1PrivateKey(privateKeyObject)
// 转换为Base64编码的字符串
privateKeyBase64String = base64.StdEncoding.EncodeToString(
pem.EncodeToMemory(&pem.Block{
Type: "PUBLIC KEY",
Bytes: privateKeyByteArray,
}),
)
// 创建文件存储私钥
if generateFile {
privateKeyFile, _ := os.Create("private.pem")
if err := pem.Encode(privateKeyFile, &pem.Block{
Type: "RSA Private Key",
Bytes: privateKeyByteArray,
}); err != nil {
fmt.Println(err.Error())
}
}

/* 生成公钥 */

// 生成公钥
publicKeyObject := &privateKeyObject.PublicKey
// 通过x509对公钥编码
publicKeyByteArray, _ := x509.MarshalPKIXPublicKey(publicKeyObject)
// 转换为Base64编码的字符串
publicKeyBase64String = base64.StdEncoding.EncodeToString(
pem.EncodeToMemory(&pem.Block{
Type: "PRIVATE KEY",
Bytes: publicKeyByteArray,
}),
)
// 创建文件存储公钥
if generateFile {
publicKeyFile, _ := os.Create("public.pem")
if err := pem.Encode(publicKeyFile, &pem.Block{
Type: "RSA Public Key",
Bytes: publicKeyByteArray,
}); err != nil {
fmt.Println(err.Error())
}
}

return privateKeyBase64String, publicKeyBase64String
}

RSA加密

  • 通过公钥进行RSA加密
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
package main

import (
"crypto/rand"
"crypto/rsa"
"crypto/x509"
"encoding/base64"
"encoding/pem"
"fmt"
"os"
)

// RSAEncrypt 通过RSA公钥加密字符串
// publicKeyFilePath 如果传递了公钥文件路径,就从公钥文件中获取私钥
// publicKeyBase64String 如果没有传递公钥文件路径,就从Base64字符串中获取公钥
func RSAEncrypt(plainText []byte, publicKeyFilePath string, publicKeyBase64String string) []byte {

// 公钥字符数组
var publicKeyByteArray []byte

if publicKeyFilePath != "" {
// 如果传递了文件路径,就从文件中获取公钥字符数组
publicKeyFileObject, _ := os.Open(publicKeyFilePath)
defer func(publicKeyFileObject *os.File) {
if err := publicKeyFileObject.Close(); err != nil {
fmt.Println(err.Error())
}
}(publicKeyFileObject)
publicKeyFile, _ := publicKeyFileObject.Stat()
publicKeyByteArray = make([]byte, publicKeyFile.Size())
if _, err := publicKeyFileObject.Read(publicKeyByteArray); err != nil {
fmt.Println(err.Error())
}
} else {
// 如果没有传递文件路径,就从Base64字符串中获取公钥字符数组
if res, err := base64.StdEncoding.DecodeString(publicKeyBase64String); err != nil {
fmt.Println(err.Error())
} else {
publicKeyByteArray = res
}
}

// pem解码
block, _ := pem.Decode(publicKeyByteArray)
// X509解码
publicKey, _ := x509.ParsePKIXPublicKey(block.Bytes)
// 对明文进行加密
cipherText, _ := rsa.EncryptPKCS1v15(
rand.Reader,
publicKey.(*rsa.PublicKey),
plainText,
)

//返回密文
return cipherText
}

RSA解密

  • 通过私钥进行RSA解密
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
package main

import (
"crypto/rand"
"crypto/rsa"
"crypto/x509"
"encoding/base64"
"encoding/pem"
"fmt"
"os"
)

// RSADecrypt 通过RSA私钥解密字符串
// privateKeyFilePath 如果传递了私钥文件路径,就从私钥文件中获取私钥
// privateKeyBase64String 如果没有传递私钥文件路径,就从Base64字符串中获取私钥
func RSADecrypt(cipherText []byte, privateKeyFilePath string, privateKeyBase64String string) []byte {

// 私钥字符数组
var privateKeyByteArray []byte

if privateKeyFilePath != "" {
// 如果传递了文件路径,就从文件中获取公钥字符数组
privateKeyFileObject, _ := os.Open(privateKeyFilePath)
defer func(privateKeyFileObject *os.File) {
if err := privateKeyFileObject.Close(); err != nil {
fmt.Println(err.Error())
}
}(privateKeyFileObject)
privateKeyFile, _ := privateKeyFileObject.Stat()
privateKeyByteArray = make([]byte, privateKeyFile.Size())
if _, err := privateKeyFileObject.Read(privateKeyByteArray); err != nil {
fmt.Println(err.Error())
}
} else {
// 如果没有传递文件路径,就从Base64字符串中获取公钥字符数组
if res, err := base64.StdEncoding.DecodeString(privateKeyBase64String); err != nil {
fmt.Println(err.Error())
} else {
privateKeyByteArray = res
}
}

// pem解码
block, _ := pem.Decode(privateKeyByteArray)
// X509解码
privateKey, _ := x509.ParsePKCS1PrivateKey(block.Bytes)
// 对密文进行解密
plainText, _ := rsa.DecryptPKCS1v15(
rand.Reader,
privateKey,
cipherText,
)

//返回明文
return plainText
}

完成

参考文献

CSDN——起个破名真费劲..
CSDN——Axing丶