/
rsa.go
152 lines (128 loc) · 3.87 KB
/
rsa.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
145
146
147
148
149
150
151
152
package crypto
import (
"crypto"
"crypto/rand"
"crypto/rsa"
"crypto/x509"
"errors"
"io"
pb "github.com/ipsn/go-ipfs/gxlibs/github.com/libp2p/go-libp2p-crypto/pb"
sha256 "github.com/minio/sha256-simd"
)
// ErrRsaKeyTooSmall is returned when trying to generate or parse an RSA key
// that's smaller than 512 bits. Keys need to be larger enough to sign a 256bit
// hash so this is a reasonable absolute minimum.
var ErrRsaKeyTooSmall = errors.New("rsa keys must be >= 512 bits to be useful")
// RsaPrivateKey is an rsa private key
type RsaPrivateKey struct {
sk *rsa.PrivateKey
pk *rsa.PublicKey
}
// RsaPublicKey is an rsa public key
type RsaPublicKey struct {
k *rsa.PublicKey
}
// GenerateRSAKeyPair generates a new rsa private and public key
func GenerateRSAKeyPair(bits int, src io.Reader) (PrivKey, PubKey, error) {
if bits < 512 {
return nil, nil, ErrRsaKeyTooSmall
}
priv, err := rsa.GenerateKey(src, bits)
if err != nil {
return nil, nil, err
}
pk := &priv.PublicKey
return &RsaPrivateKey{sk: priv}, &RsaPublicKey{pk}, nil
}
// Verify compares a signature against input data
func (pk *RsaPublicKey) Verify(data, sig []byte) (bool, error) {
hashed := sha256.Sum256(data)
err := rsa.VerifyPKCS1v15(pk.k, crypto.SHA256, hashed[:], sig)
if err != nil {
return false, err
}
return true, nil
}
func (pk *RsaPublicKey) Type() pb.KeyType {
return pb.KeyType_RSA
}
// Bytes returns protobuf bytes of a public key
func (pk *RsaPublicKey) Bytes() ([]byte, error) {
return MarshalPublicKey(pk)
}
func (pk *RsaPublicKey) Raw() ([]byte, error) {
return x509.MarshalPKIXPublicKey(pk.k)
}
// Encrypt returns encrypted bytes from the inpu data
func (pk *RsaPublicKey) Encrypt(b []byte) ([]byte, error) {
return rsa.EncryptPKCS1v15(rand.Reader, pk.k, b)
}
// Equals checks whether this key is equal to another
func (pk *RsaPublicKey) Equals(k Key) bool {
return KeyEqual(pk, k)
}
// Sign returns a signature of the input data
func (sk *RsaPrivateKey) Sign(message []byte) ([]byte, error) {
hashed := sha256.Sum256(message)
return rsa.SignPKCS1v15(rand.Reader, sk.sk, crypto.SHA256, hashed[:])
}
// GetPublic returns a public key
func (sk *RsaPrivateKey) GetPublic() PubKey {
if sk.pk == nil {
sk.pk = &sk.sk.PublicKey
}
return &RsaPublicKey{sk.pk}
}
// Decrypt returns decrypted bytes of the input encrypted bytes
func (sk *RsaPrivateKey) Decrypt(b []byte) ([]byte, error) {
return rsa.DecryptPKCS1v15(rand.Reader, sk.sk, b)
}
func (sk *RsaPrivateKey) Type() pb.KeyType {
return pb.KeyType_RSA
}
// Bytes returns protobuf bytes from a private key
func (sk *RsaPrivateKey) Bytes() ([]byte, error) {
return MarshalPrivateKey(sk)
}
func (sk *RsaPrivateKey) Raw() ([]byte, error) {
b := x509.MarshalPKCS1PrivateKey(sk.sk)
return b, nil
}
// Equals checks whether this key is equal to another
func (sk *RsaPrivateKey) Equals(k Key) bool {
return KeyEqual(sk, k)
}
// UnmarshalRsaPrivateKey returns a private key from the input x509 bytes
func UnmarshalRsaPrivateKey(b []byte) (PrivKey, error) {
sk, err := x509.ParsePKCS1PrivateKey(b)
if err != nil {
return nil, err
}
if sk.N.BitLen() < 512 {
return nil, ErrRsaKeyTooSmall
}
return &RsaPrivateKey{sk: sk}, nil
}
// MarshalRsaPrivateKey returns the x509 bytes of the private key
func MarshalRsaPrivateKey(k *RsaPrivateKey) []byte {
return x509.MarshalPKCS1PrivateKey(k.sk)
}
// UnmarshalRsaPublicKey returns a public key from the input x509 bytes
func UnmarshalRsaPublicKey(b []byte) (PubKey, error) {
pub, err := x509.ParsePKIXPublicKey(b)
if err != nil {
return nil, err
}
pk, ok := pub.(*rsa.PublicKey)
if !ok {
return nil, errors.New("not actually an rsa public key")
}
if pk.N.BitLen() < 512 {
return nil, ErrRsaKeyTooSmall
}
return &RsaPublicKey{pk}, nil
}
// MarshalRsaPublicKey returns the x509 bytes from the public key
func MarshalRsaPublicKey(k *RsaPublicKey) ([]byte, error) {
return x509.MarshalPKIXPublicKey(k.k)
}