-
Notifications
You must be signed in to change notification settings - Fork 1
/
asymmetricencryption.go
139 lines (112 loc) · 3.09 KB
/
asymmetricencryption.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
package method
import (
"crypto"
"crypto/ecdsa"
"crypto/elliptic"
"crypto/rand"
"crypto/rsa"
"errors"
"git.golaxy.org/framework/net/gtp"
)
// Signer 签名器
type Signer interface {
// GenerateKey 生成私钥
GenerateKey() (crypto.PrivateKey, error)
// Sign 签名
Sign(priv crypto.PrivateKey, data []byte) ([]byte, error)
// Verify 验证签名
Verify(pub crypto.PublicKey, data, sig []byte) error
}
// NewSigner 创建签名器
func NewSigner(ae gtp.AsymmetricEncryption, padding gtp.PaddingMode, hash gtp.Hash) (Signer, error) {
switch ae {
case gtp.AsymmetricEncryption_RSA_256:
switch padding {
case gtp.PaddingMode_Pkcs1v15, gtp.PaddingMode_PSS:
break
default:
return nil, errors.New("invalid padding mode")
}
var cryptoHash crypto.Hash
switch hash {
case gtp.Hash_SHA256:
cryptoHash = crypto.SHA256
default:
return nil, errors.New("invalid hash method")
}
return _RSA256Signer{padding: padding, hash: cryptoHash}, nil
case gtp.AsymmetricEncryption_ECDSA_P256:
return _ECDSAP256Signer{}, nil
default:
return nil, ErrInvalidMethod
}
}
type _RSA256Signer struct {
padding gtp.PaddingMode
hash crypto.Hash
}
func (s _RSA256Signer) GenerateKey() (crypto.PrivateKey, error) {
return rsa.GenerateKey(rand.Reader, 256)
}
func (s _RSA256Signer) Sign(priv crypto.PrivateKey, data []byte) ([]byte, error) {
rsaPriv, ok := priv.(*rsa.PrivateKey)
if !ok {
return nil, errors.New("invalid private key")
}
if !s.hash.Available() {
return nil, errors.New("invalid hash method")
}
hash := s.hash.New()
hash.Write(data)
hashed := hash.Sum(nil)
switch s.padding {
case gtp.PaddingMode_Pkcs1v15:
return rsa.SignPKCS1v15(rand.Reader, rsaPriv, s.hash, hashed)
case gtp.PaddingMode_PSS:
return rsa.SignPSS(rand.Reader, rsaPriv, s.hash, hashed, nil)
default:
return nil, errors.New("invalid padding mode")
}
}
func (s _RSA256Signer) Verify(pub crypto.PublicKey, data, sig []byte) error {
rsaPub, ok := pub.(*rsa.PublicKey)
if !ok {
return errors.New("invalid public key")
}
hash := s.hash.New()
hash.Write(data)
hashed := hash.Sum(nil)
switch s.padding {
case gtp.PaddingMode_Pkcs1v15:
return rsa.VerifyPKCS1v15(rsaPub, s.hash, hashed, sig)
case gtp.PaddingMode_PSS:
return rsa.VerifyPSS(rsaPub, s.hash, hashed, sig, nil)
default:
return errors.New("invalid padding mode")
}
}
type _ECDSAP256Signer struct {
hash crypto.Hash
}
func (s _ECDSAP256Signer) GenerateKey() (crypto.PrivateKey, error) {
return ecdsa.GenerateKey(elliptic.P256(), rand.Reader)
}
func (s _ECDSAP256Signer) Sign(priv crypto.PrivateKey, data []byte) ([]byte, error) {
ecdsaPriv, ok := priv.(*ecdsa.PrivateKey)
if !ok {
return nil, errors.New("invalid private key")
}
hash := s.hash.New()
hash.Write(data)
hashed := hash.Sum(nil)
return ecdsa.SignASN1(rand.Reader, ecdsaPriv, hashed)
}
func (s _ECDSAP256Signer) Verify(pub crypto.PublicKey, data, sig []byte) error {
hash := s.hash.New()
hash.Write(data)
hashed := hash.Sum(nil)
if ecdsa.VerifyASN1(pub.(*ecdsa.PublicKey), hashed, sig) {
return nil
}
return errors.New("crypto/ecdsa: verification error")
}