Skip to content

Commit 35ae19c

Browse files
committed
refactor(#29): updated readme, added examples, minor fixes
1 parent bd5a97b commit 35ae19c

File tree

6 files changed

+268
-15
lines changed

6 files changed

+268
-15
lines changed

.vscode/launch.json

+15
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
{
2+
// Use IntelliSense to learn about possible attributes.
3+
// Hover to view descriptions of existing attributes.
4+
// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
5+
"version": "0.2.0",
6+
"configurations": [
7+
{
8+
"name": "hmac",
9+
"type": "go",
10+
"request": "launch",
11+
"mode": "auto",
12+
"program": "examples/hmac/main.go"
13+
}
14+
]
15+
}

README.md

+35-11
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,7 @@ See specific algorithms for the parameter types to be passed in.
6565

6666
The **ECDSA** algorithm is the implementation of operations described in [§23](https://www.w3.org/TR/WebCryptoAPI/#ecdsa) of the W3C specification.
6767

68-
`import "github.com/armortal/webcrypto-go/algorithms/ecdsa"`.
68+
`import "github.com/armortal/webcrypto-go/algorithms/ecdsa"`
6969

7070
#### Parameter Definitions
7171

@@ -102,6 +102,8 @@ As specified in [§23.6](https://www.w3.org/TR/WebCryptoAPI/#EcKeyImportParams-d
102102
package main
103103

104104
import (
105+
"fmt"
106+
105107
"github.com/armortal/webcrypto-go"
106108
"github.com/armortal/webcrypto-go/algorithms/ecdsa"
107109
)
@@ -123,15 +125,15 @@ func main() {
123125
}
124126

125127
// key returned is a webcrypto.CryptoKeyPair
126-
ckp := key.(webcrypto.CryptoKeyPair)
128+
cryptoKey := key.(webcrypto.CryptoKeyPair)
127129

128130
// sign some data with the private key
129131
sig, err := webcrypto.Subtle().Sign(&webcrypto.Algorithm{
130132
Name: "ECDSA",
131133
Params: &ecdsa.Params{
132134
Hash: "SHA-256",
133135
},
134-
}, ckp.PrivateKey(), []byte("test"))
136+
}, cryptoKey.PrivateKey(), []byte("test"))
135137
if err != nil {
136138
panic(err)
137139
}
@@ -142,27 +144,48 @@ func main() {
142144
Params: &ecdsa.Params{
143145
Hash: "SHA-256",
144146
},
145-
}, ckp.PublicKey(), sig, []byte("test"))
147+
}, cryptoKey.PublicKey(), sig, []byte("test"))
146148
if err != nil {
147149
panic(err)
148150
}
149151

150152
if !ok {
151-
// didn't verify - do something
153+
panic("signature didn't verify")
152154
}
153155

154156
// export the public/private key as webcrypto.JsonWebKey
155-
out, err := webcrypto.Subtle().ExportKey(webcrypto.Jwk, ckp.PrivateKey())
157+
out, err := webcrypto.Subtle().ExportKey(webcrypto.Jwk, cryptoKey.PrivateKey())
156158
if err != nil {
157159
panic(err)
158160
}
159161

160-
jwk := out.(webcrypto.JsonWebKey)
161-
162162
// do something with jwk
163+
jwk := out.(*webcrypto.JsonWebKey)
164+
165+
// export the key as PKCS8
166+
out, err = webcrypto.Subtle().ExportKey(webcrypto.PKCS8, cryptoKey.PrivateKey())
167+
if err != nil {
168+
panic(err)
169+
}
170+
171+
// do something with the pkcs8 key
172+
pkcs8 := out.([]byte)
173+
174+
// import a public/private key from a jwk
175+
in, err := webcrypto.Subtle().ImportKey(webcrypto.Jwk, jwk, &webcrypto.Algorithm{
176+
Name: "ECDSA",
177+
Params: &ecdsa.KeyImportParams{
178+
NamedCurve: "P-256",
179+
},
180+
}, true, []webcrypto.KeyUsage{
181+
webcrypto.Sign,
182+
})
183+
if err != nil {
184+
panic(err)
185+
}
163186

164-
// import a public/private key
165-
ck, err := webcrypto.Subtle().ImportKey(webcrypto.Jwk, jwk, &webcrypto.Algorithm{
187+
// import a public/private key from PKCS8
188+
in, err = webcrypto.Subtle().ImportKey(webcrypto.PKCS8, pkcs8, &webcrypto.Algorithm{
166189
Name: "ECDSA",
167190
Params: &ecdsa.KeyImportParams{
168191
NamedCurve: "P-256",
@@ -175,14 +198,15 @@ func main() {
175198
}
176199

177200
// do something with the imported webcrypto.CryptoKey
201+
fmt.Println(in.Type())
178202
}
179203
```
180204

181205
### HMAC
182206

183207
The **HMAC** algorithm is the implementation of operations described in [§29](https://www.w3.org/TR/WebCryptoAPI/#hmac) of the W3C specification.
184208

185-
`import "github.com/armortal/webcrypto-go/algorithms/hmac"`.
209+
`import "github.com/armortal/webcrypto-go/algorithms/hmac"`
186210

187211
#### Parameter Definitions
188212

algorithms/ecdsa/ecdsa.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -269,7 +269,7 @@ func (s *subtleCrypto) ImportKey(format webcrypto.KeyFormat, keyData any, algori
269269
// the implementation in this library will take these values from the algorithm provided in the params.
270270
func importKeyPKCS8(keyData []byte, params *KeyImportParams, extractable bool, keyUsages []webcrypto.KeyUsage) (*CryptoKey, error) {
271271
if err := util.AreUsagesValid(
272-
[]webcrypto.KeyUsage{webcrypto.Decrypt, webcrypto.UnwrapKey}, keyUsages); err != nil {
272+
[]webcrypto.KeyUsage{webcrypto.Sign, webcrypto.Verify}, keyUsages); err != nil {
273273
return nil, err
274274
}
275275

algorithms/hmac/hmac.go

+3-3
Original file line numberDiff line numberDiff line change
@@ -74,8 +74,8 @@ type KeyAlgorithm struct {
7474
}
7575

7676
// Hash is the inner hash function to use.
77-
func (k *KeyAlgorithm) Hash() webcrypto.KeyAlgorithm {
78-
return nil
77+
func (k *KeyAlgorithm) Hash() string {
78+
return k.hash
7979
}
8080

8181
// Length is the length (in bits) of the key.
@@ -174,7 +174,7 @@ func exportKeyAsJsonWebKey(key *CryptoKey) (*webcrypto.JsonWebKey, error) {
174174
K: base64.RawURLEncoding.EncodeToString(key.secret),
175175
}
176176

177-
switch key.algorithm.Hash().Name() {
177+
switch key.algorithm.Hash() {
178178
case "SHA-1":
179179
jwk.Alg = "HS1"
180180
case "SHA-256":

examples/ecdsa/main.go

+101
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,101 @@
1+
package main
2+
3+
import (
4+
"fmt"
5+
6+
"github.com/armortal/webcrypto-go"
7+
"github.com/armortal/webcrypto-go/algorithms/ecdsa"
8+
)
9+
10+
func main() {
11+
// generate a new P-256 ECDSA key
12+
key, err := webcrypto.Subtle().GenerateKey(
13+
&webcrypto.Algorithm{
14+
Name: "ECDSA",
15+
Params: &ecdsa.KeyGenParams{
16+
NamedCurve: "P-256",
17+
},
18+
}, true, []webcrypto.KeyUsage{
19+
webcrypto.Sign,
20+
webcrypto.Verify,
21+
})
22+
if err != nil {
23+
panic(err)
24+
}
25+
26+
// key returned is a webcrypto.CryptoKeyPair
27+
cryptoKey := key.(webcrypto.CryptoKeyPair)
28+
29+
// sign some data with the private key
30+
sig, err := webcrypto.Subtle().Sign(&webcrypto.Algorithm{
31+
Name: "ECDSA",
32+
Params: &ecdsa.Params{
33+
Hash: "SHA-256",
34+
},
35+
}, cryptoKey.PrivateKey(), []byte("test"))
36+
if err != nil {
37+
panic(err)
38+
}
39+
40+
// verify the signature with the public key
41+
ok, err := webcrypto.Subtle().Verify(&webcrypto.Algorithm{
42+
Name: "ECDSA",
43+
Params: &ecdsa.Params{
44+
Hash: "SHA-256",
45+
},
46+
}, cryptoKey.PublicKey(), sig, []byte("test"))
47+
if err != nil {
48+
panic(err)
49+
}
50+
51+
if !ok {
52+
panic("signature didn't verify")
53+
}
54+
55+
// export the public/private key as webcrypto.JsonWebKey
56+
out, err := webcrypto.Subtle().ExportKey(webcrypto.Jwk, cryptoKey.PrivateKey())
57+
if err != nil {
58+
panic(err)
59+
}
60+
61+
// do something with jwk
62+
jwk := out.(*webcrypto.JsonWebKey)
63+
64+
// export the key as PKCS8
65+
out, err = webcrypto.Subtle().ExportKey(webcrypto.PKCS8, cryptoKey.PrivateKey())
66+
if err != nil {
67+
panic(err)
68+
}
69+
70+
// do something with the pkcs8 key
71+
pkcs8 := out.([]byte)
72+
73+
// import a public/private key from a jwk
74+
in, err := webcrypto.Subtle().ImportKey(webcrypto.Jwk, jwk, &webcrypto.Algorithm{
75+
Name: "ECDSA",
76+
Params: &ecdsa.KeyImportParams{
77+
NamedCurve: "P-256",
78+
},
79+
}, true, []webcrypto.KeyUsage{
80+
webcrypto.Sign,
81+
})
82+
if err != nil {
83+
panic(err)
84+
}
85+
86+
// import a public/private key from PKCS8
87+
in, err = webcrypto.Subtle().ImportKey(webcrypto.PKCS8, pkcs8, &webcrypto.Algorithm{
88+
Name: "ECDSA",
89+
Params: &ecdsa.KeyImportParams{
90+
NamedCurve: "P-256",
91+
},
92+
}, true, []webcrypto.KeyUsage{
93+
webcrypto.Sign,
94+
})
95+
if err != nil {
96+
panic(err)
97+
}
98+
99+
// do something with the imported webcrypto.CryptoKey
100+
fmt.Println(in.Type())
101+
}

examples/hmac/main.go

+113
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,113 @@
1+
package main
2+
3+
import (
4+
"fmt"
5+
6+
"github.com/armortal/webcrypto-go"
7+
"github.com/armortal/webcrypto-go/algorithms/hmac"
8+
)
9+
10+
func main() {
11+
// generate a new key
12+
key, err := webcrypto.Subtle().GenerateKey(
13+
&webcrypto.Algorithm{
14+
Name: "HMAC",
15+
Params: &hmac.KeyGenParams{
16+
Hash: "SHA-256",
17+
},
18+
}, true, []webcrypto.KeyUsage{
19+
webcrypto.Sign,
20+
webcrypto.Verify,
21+
})
22+
23+
if err != nil {
24+
panic(err)
25+
}
26+
27+
// the generated key returns a webcrypto.CryptoKey or
28+
// more specifically, a *hmac.CryptoKey
29+
cryptoKey := key.(webcrypto.CryptoKey)
30+
31+
// sign some data - no params required.
32+
sig, err := webcrypto.Subtle().Sign(&webcrypto.Algorithm{
33+
Name: "HMAC",
34+
}, cryptoKey, []byte("test"))
35+
36+
if err != nil {
37+
panic(err)
38+
}
39+
40+
// verify the signature
41+
ok, err := webcrypto.Subtle().Verify(&webcrypto.Algorithm{
42+
Name: "HMAC",
43+
}, cryptoKey, sig, []byte("test"))
44+
45+
if err != nil {
46+
panic(err)
47+
}
48+
49+
if !ok {
50+
panic("signature didn't verify")
51+
}
52+
53+
// export the key as *webcrypto.JsonWebKey
54+
out, err := webcrypto.Subtle().ExportKey(webcrypto.Jwk, cryptoKey)
55+
if err != nil {
56+
panic(err)
57+
}
58+
59+
jwk := out.(*webcrypto.JsonWebKey)
60+
// do something with jwk
61+
62+
// export the key as raw bytes
63+
out, err = webcrypto.Subtle().ExportKey(webcrypto.Raw, cryptoKey)
64+
if err != nil {
65+
panic(err)
66+
}
67+
68+
raw := out.([]byte)
69+
// do something with raw bytes
70+
71+
// import a key from a jwk
72+
in, err := webcrypto.Subtle().ImportKey(
73+
webcrypto.Jwk,
74+
jwk,
75+
&webcrypto.Algorithm{
76+
Name: "HMAC",
77+
Params: &hmac.ImportParams{
78+
Hash: "SHA-256",
79+
},
80+
},
81+
true,
82+
[]webcrypto.KeyUsage{
83+
webcrypto.Sign,
84+
webcrypto.Verify,
85+
})
86+
87+
if err != nil {
88+
panic(err)
89+
}
90+
91+
// import a key from raw bytes
92+
in, err = webcrypto.Subtle().ImportKey(
93+
webcrypto.Raw,
94+
raw,
95+
&webcrypto.Algorithm{
96+
Name: "HMAC",
97+
Params: &hmac.ImportParams{
98+
Hash: "SHA-256",
99+
},
100+
},
101+
true,
102+
[]webcrypto.KeyUsage{
103+
webcrypto.Sign,
104+
webcrypto.Verify,
105+
})
106+
107+
if err != nil {
108+
panic(err)
109+
}
110+
111+
// do something with your imported keys
112+
fmt.Println(in.Type())
113+
}

0 commit comments

Comments
 (0)