-
Notifications
You must be signed in to change notification settings - Fork 22
/
key.go
150 lines (116 loc) · 3.22 KB
/
key.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
package curve25519
import (
"fmt"
"errors"
"encoding/asn1"
"crypto/x509/pkix"
"golang.org/x/crypto/curve25519"
)
var (
// DH 公钥 oid
oidPublicKeyDH = asn1.ObjectIdentifier{1, 3, 132, 1, 12}
)
// 私钥 - 包装
type pkcs8 struct {
Version int
Algo pkix.AlgorithmIdentifier
PrivateKey []byte
}
// 公钥 - 包装
type pkixPublicKey struct {
Algo pkix.AlgorithmIdentifier
BitString asn1.BitString
}
// 公钥信息 - 解析
type publicKeyInfo struct {
Raw asn1.RawContent
Algorithm pkix.AlgorithmIdentifier
PublicKey asn1.BitString
}
// 包装公钥
func MarshalPublicKey(key *PublicKey) ([]byte, error) {
var publicKeyBytes []byte
var publicKeyAlgorithm pkix.AlgorithmIdentifier
var err error
// 创建数据
paramBytes, err := asn1.Marshal([]byte(""))
if err != nil {
return nil, errors.New("curve25519: failed to marshal algo param: " + err.Error())
}
publicKeyAlgorithm.Algorithm = oidPublicKeyDH
publicKeyAlgorithm.Parameters.FullBytes = paramBytes
publicKeyBytes = key.Y
pkix := pkixPublicKey{
Algo: publicKeyAlgorithm,
BitString: asn1.BitString{
Bytes: publicKeyBytes,
BitLength: 8 * len(publicKeyBytes),
},
}
return asn1.Marshal(pkix)
}
// 解析公钥
func ParsePublicKey(derBytes []byte) (*PublicKey, error) {
var pki publicKeyInfo
rest, err := asn1.Unmarshal(derBytes, &pki)
if err != nil {
return nil, err
}
if len(rest) > 0 {
err = asn1.SyntaxError{Msg: "trailing data"}
return nil, err
}
algoEq := pki.Algorithm.Algorithm.Equal(oidPublicKeyDH)
if !algoEq {
err = errors.New("curve25519: unknown public key algorithm")
return nil, err
}
// 解析
keyData := &pki
y := []byte(keyData.PublicKey.RightAlign())
pub := &PublicKey{}
pub.Y = y
return pub, nil
}
// ====================
// 包装私钥
func MarshalPrivateKey(key *PrivateKey) ([]byte, error) {
var privKey pkcs8
// 创建数据
paramBytes, err := asn1.Marshal([]byte(""))
if err != nil {
return nil, errors.New("curve25519: failed to marshal algo param: " + err.Error())
}
privKey.Algo = pkix.AlgorithmIdentifier{
Algorithm: oidPublicKeyDH,
Parameters: asn1.RawValue{
FullBytes: paramBytes,
},
}
privKey.PrivateKey = key.X
return asn1.Marshal(privKey)
}
// 解析私钥
func ParsePrivateKey(derBytes []byte) (*PrivateKey, error) {
var privKey pkcs8
var err error
_, err = asn1.Unmarshal(derBytes, &privKey)
if err != nil {
return nil, err
}
switch {
case privKey.Algo.Algorithm.Equal(oidPublicKeyDH):
x := privKey.PrivateKey
priv := &PrivateKey{}
priv.X = x
var pri, pub [32]byte
copy(pri[:], x)
curve25519.ScalarBaseMult(&pub, &pri)
// 算出 Y 值
priv.Y = pub[:]
return priv, nil
default:
err = fmt.Errorf("curve25519: PKCS#8 wrapping contained private key with unknown algorithm: %v", privKey.Algo.Algorithm)
return nil, err
}
}