-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathcrypto_asymmetric.go
127 lines (106 loc) Β· 2.75 KB
/
crypto_asymmetric.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
package cryptography
import (
"crypto/rand"
"crypto/rsa"
"fmt"
)
// asymmetric represents an asymmetric cryptography driver.
type asymmetric struct {
key *RSAKey
publicKey *rsa.PublicKey
signer HashingAlgo
}
// NewAsymmetric creates a new asymmetric encryption driver with a private key.
func NewAsymmetric(key RSAKey, signer HashingAlgo) Cryptography {
return &asymmetric{
key: &key,
signer: signer,
}
}
// NewAsymmetricClient creates a new asymmetric encryption driver with a public key.
func NewAsymmetricClient(public *rsa.PublicKey, signer HashingAlgo) Cryptography {
return &asymmetric{
publicKey: public,
signer: signer,
}
}
// PublicKey returns the public key associated with the driver.
func (a *asymmetric) PublicKey() *rsa.PublicKey {
if a.publicKey != nil {
return a.publicKey
}
if a.key != nil {
return a.key.PublicKey()
}
return nil
}
func (a *asymmetric) Sign(data []byte) ([]byte, error) {
if a.key == nil {
return nil, fmt.Errorf("no private key provided")
}
constructor := HashingInstance(a.signer)
if constructor == nil {
return nil, fmt.Errorf("invalid hashing algorithm")
}
hasher := constructor()
if _, err := hasher.Write(data); err != nil {
return nil, err
}
return rsa.SignPKCS1v15(
rand.Reader, a.key.PrivateKey(),
HashingAlg(a.signer), hasher.Sum(nil),
)
}
func (a *asymmetric) ValidateSignature(data []byte, signature []byte) (bool, error) {
constructor := HashingInstance(a.signer)
if constructor == nil {
return false, fmt.Errorf("invalid hashing algorithm")
}
hasher := constructor()
if _, err := hasher.Write(data); err != nil {
return false, err
}
err := rsa.VerifyPKCS1v15(
a.PublicKey(), HashingAlg(a.signer),
hasher.Sum(nil), signature,
)
return err == nil, err
}
func (a *asymmetric) Encrypt(data []byte) ([]byte, error) {
constructor := HashingInstance(a.signer)
if constructor == nil {
return nil, fmt.Errorf("invalid hashing algorithm")
}
return rsa.EncryptOAEP(
constructor(), rand.Reader,
a.PublicKey(), data, nil,
)
}
func (a *asymmetric) Decrypt(data []byte) ([]byte, error) {
if a.key == nil {
return nil, fmt.Errorf("no private key provided")
}
constructor := HashingInstance(a.signer)
if constructor == nil {
return nil, fmt.Errorf("invalid hashing algorithm")
}
return rsa.DecryptOAEP(
constructor(), rand.Reader,
a.key.PrivateKey(), data, nil,
)
}
func (a *asymmetric) EncryptBase64(data []byte) (string, error) {
encrypted, err := a.Encrypt(data)
if err != nil {
return "", err
}
encoded, err := base64Encode(encrypted)
return string(encoded), err
}
func (a *asymmetric) DecryptBase64(encrypted string) ([]byte, error) {
raw, err := base64Decode([]byte(encrypted))
if err != nil {
return nil, err
}
return a.Decrypt(raw)
}