-
Notifications
You must be signed in to change notification settings - Fork 0
/
rsautil.go
144 lines (130 loc) · 3.44 KB
/
rsautil.go
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
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
package rsautil
import (
"crypto/rand"
"crypto/rsa"
"crypto/x509"
"encoding/base64"
"encoding/pem"
"fmt"
"io/ioutil"
)
/*
This source code is referenced from: https://gist.github.com/miguelmota/3ea9286bd1d3c2a985b67cac4ba2130a
*/
// GenerateKeyPair generates a new key pair
func GenerateKeyPair(bits int) (*rsa.PrivateKey, *rsa.PublicKey, error) {
privkey, err := rsa.GenerateKey(rand.Reader, bits)
if err != nil {
return nil, nil, err
}
return privkey, &privkey.PublicKey, nil
}
// PrivateKeyToBytes private key to bytes
func PrivateKeyToBytes(priv *rsa.PrivateKey) ([]byte, error) {
priASN1, err := x509.MarshalPKCS8PrivateKey(priv)
if err != nil {
return nil, err
}
return pem.EncodeToMemory(
&pem.Block{
Type: "RSA PRIVATE KEY",
Bytes: priASN1,
},
), nil
}
// PublicKeyToBytes public key to bytes
func PublicKeyToBytes(pub *rsa.PublicKey) ([]byte, error) {
pubASN1, err := x509.MarshalPKIXPublicKey(pub)
if err != nil {
return nil, err
}
return pem.EncodeToMemory(&pem.Block{
Type: "RSA PUBLIC KEY",
Bytes: pubASN1,
}), nil
}
// BytesToPublicKey convert from bytes to public key
func BytesToPublicKey(pub []byte) (*rsa.PublicKey, error) {
block, _ := pem.Decode(pub)
if block == nil {
return nil, fmt.Errorf("There is no PEM data in this key")
}
enc := x509.IsEncryptedPEMBlock(block)
b := block.Bytes
var err error
if enc {
//log.Println("is encrypted pem block")
b, err = x509.DecryptPEMBlock(block, nil)
if err != nil {
return nil, err
}
}
ifc, err := x509.ParsePKIXPublicKey(b)
if err != nil {
return nil, err
}
key, ok := ifc.(*rsa.PublicKey)
if !ok {
return nil, fmt.Errorf("This key is not a rsa public key")
}
return key, nil
}
// BytesToPrivateKey convert from bytes to private key
func BytesToPrivateKey(priv []byte) (*rsa.PrivateKey, error) {
block, _ := pem.Decode(priv)
if block == nil {
return nil, fmt.Errorf("There is no PEM data in this key")
}
enc := x509.IsEncryptedPEMBlock(block)
b := block.Bytes
var err error
if enc {
b, err = x509.DecryptPEMBlock(block, nil)
if err != nil {
return nil, err
}
}
ifc, err := x509.ParsePKCS8PrivateKey(b)
if err != nil {
return nil, err
}
key, ok := ifc.(*rsa.PrivateKey)
if !ok {
return nil, fmt.Errorf("This key is not a rsa private key")
}
return key, nil
}
// PublicKeyFromFile read file and convert to public key
func PublicKeyFromFile(filename string) (*rsa.PublicKey, error) {
pub, err := ioutil.ReadFile(filename)
if err != nil {
return nil, err
}
return BytesToPublicKey(pub)
}
// PrivateKeyFromFile read file and convert to private key
func PrivateKeyFromFile(filename string) (*rsa.PrivateKey, error) {
priv, err := ioutil.ReadFile(filename)
if err != nil {
return nil, err
}
return BytesToPrivateKey(priv)
}
// Encrypt given text with given *rsa.PublicKey
func Encrypt(pub *rsa.PublicKey, text string) (string, error) {
cipherText, err := rsa.EncryptPKCS1v15(rand.Reader, pub, []byte(text))
return string(cipherText), err
}
// EncryptToBase64 encrypt rsa and encode to base64
func EncryptToBase64(pub *rsa.PublicKey, text string) (string, error) {
cipherText, err := Encrypt(pub, text)
if err != nil {
return "", err
}
return base64.StdEncoding.EncodeToString([]byte(cipherText)), nil
}
// Decrypt given ciptherText with given *rsa.PrivateKey
func Decrypt(priv *rsa.PrivateKey, cipherText string) (string, error) {
text, err := rsa.DecryptPKCS1v15(rand.Reader, priv, []byte(cipherText))
return string(text), err
}