@sd-jwt/crypto-browser 0.3.2-next.71 → 0.3.2-next.73

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.d.mts CHANGED
@@ -1,5 +1,14 @@
1
1
  declare const generateSalt: (length: number) => string;
2
2
  declare function digest(data: string, algorithm?: string): Promise<Uint8Array>;
3
3
  declare const getHasher: (algorithm?: string) => (data: string) => Promise<Uint8Array>;
4
+ declare const ES256: {
5
+ alg: string;
6
+ generateKeyPair(): Promise<{
7
+ publicKey: JsonWebKey;
8
+ privateKey: JsonWebKey;
9
+ }>;
10
+ getSigner(privateKeyJWK: object): Promise<(data: string) => Promise<string>>;
11
+ getVerifier(publicKeyJWK: object): Promise<(data: string, signatureBase64url: string) => Promise<boolean>>;
12
+ };
4
13
 
5
- export { digest, generateSalt, getHasher };
14
+ export { ES256, digest, generateSalt, getHasher };
package/dist/index.d.ts CHANGED
@@ -1,5 +1,14 @@
1
1
  declare const generateSalt: (length: number) => string;
2
2
  declare function digest(data: string, algorithm?: string): Promise<Uint8Array>;
3
3
  declare const getHasher: (algorithm?: string) => (data: string) => Promise<Uint8Array>;
4
+ declare const ES256: {
5
+ alg: string;
6
+ generateKeyPair(): Promise<{
7
+ publicKey: JsonWebKey;
8
+ privateKey: JsonWebKey;
9
+ }>;
10
+ getSigner(privateKeyJWK: object): Promise<(data: string) => Promise<string>>;
11
+ getVerifier(publicKeyJWK: object): Promise<(data: string, signatureBase64url: string) => Promise<boolean>>;
12
+ };
4
13
 
5
- export { digest, generateSalt, getHasher };
14
+ export { ES256, digest, generateSalt, getHasher };
package/dist/index.js CHANGED
@@ -40,6 +40,7 @@ var __async = (__this, __arguments, generator) => {
40
40
  // src/index.ts
41
41
  var src_exports = {};
42
42
  __export(src_exports, {
43
+ ES256: () => ES256,
43
44
  digest: () => digest,
44
45
  generateSalt: () => generateSalt,
45
46
  getHasher: () => getHasher
@@ -69,8 +70,99 @@ function digest(data, algorithm = "SHA-256") {
69
70
  var getHasher = (algorithm = "SHA-256") => {
70
71
  return (data) => digest(data, algorithm);
71
72
  };
73
+ var ES256 = {
74
+ alg: "ES256",
75
+ generateKeyPair() {
76
+ return __async(this, null, function* () {
77
+ const keyPair = yield window.crypto.subtle.generateKey(
78
+ {
79
+ name: "ECDSA",
80
+ namedCurve: "P-256"
81
+ // ES256
82
+ },
83
+ true,
84
+ // whether the key is extractable (i.e., can be used in exportKey)
85
+ ["sign", "verify"]
86
+ // can be used to sign and verify signatures
87
+ );
88
+ const publicKeyJWK = yield window.crypto.subtle.exportKey(
89
+ "jwk",
90
+ keyPair.publicKey
91
+ );
92
+ const privateKeyJWK = yield window.crypto.subtle.exportKey(
93
+ "jwk",
94
+ keyPair.privateKey
95
+ );
96
+ return { publicKey: publicKeyJWK, privateKey: privateKeyJWK };
97
+ });
98
+ },
99
+ getSigner(privateKeyJWK) {
100
+ return __async(this, null, function* () {
101
+ const privateKey = yield window.crypto.subtle.importKey(
102
+ "jwk",
103
+ privateKeyJWK,
104
+ {
105
+ name: "ECDSA",
106
+ namedCurve: "P-256"
107
+ // Must match the curve used to generate the key
108
+ },
109
+ true,
110
+ // whether the key is extractable (i.e., can be used in exportKey)
111
+ ["sign"]
112
+ );
113
+ return (data) => __async(this, null, function* () {
114
+ const encoder = new TextEncoder();
115
+ const signature = yield window.crypto.subtle.sign(
116
+ {
117
+ name: "ECDSA",
118
+ hash: { name: "SHA-256" }
119
+ // Required for ES256
120
+ },
121
+ privateKey,
122
+ encoder.encode(data)
123
+ );
124
+ return window.btoa(String.fromCharCode(...new Uint8Array(signature))).replace(/\+/g, "-").replace(/\//g, "_").replace(/=+$/, "");
125
+ });
126
+ });
127
+ },
128
+ getVerifier(publicKeyJWK) {
129
+ return __async(this, null, function* () {
130
+ const publicKey = yield window.crypto.subtle.importKey(
131
+ "jwk",
132
+ publicKeyJWK,
133
+ {
134
+ name: "ECDSA",
135
+ namedCurve: "P-256"
136
+ // Must match the curve used to generate the key
137
+ },
138
+ true,
139
+ // whether the key is extractable (i.e., can be used in exportKey)
140
+ ["verify"]
141
+ );
142
+ return (data, signatureBase64url) => __async(this, null, function* () {
143
+ const encoder = new TextEncoder();
144
+ const signature = Uint8Array.from(
145
+ atob(signatureBase64url.replace(/-/g, "+").replace(/_/g, "/")),
146
+ (c) => c.charCodeAt(0)
147
+ );
148
+ const isValid = yield window.crypto.subtle.verify(
149
+ {
150
+ name: "ECDSA",
151
+ hash: { name: "SHA-256" }
152
+ // Required for ES256
153
+ },
154
+ publicKey,
155
+ signature,
156
+ encoder.encode(data)
157
+ );
158
+ return isValid;
159
+ });
160
+ });
161
+ }
162
+ };
72
163
  // Annotate the CommonJS export names for ESM import in node:
73
164
  0 && (module.exports = {
165
+ ES256,
74
166
  digest,
75
167
  generateSalt,
76
168
  getHasher
package/dist/index.mjs CHANGED
@@ -42,7 +42,98 @@ function digest(data, algorithm = "SHA-256") {
42
42
  var getHasher = (algorithm = "SHA-256") => {
43
43
  return (data) => digest(data, algorithm);
44
44
  };
45
+ var ES256 = {
46
+ alg: "ES256",
47
+ generateKeyPair() {
48
+ return __async(this, null, function* () {
49
+ const keyPair = yield window.crypto.subtle.generateKey(
50
+ {
51
+ name: "ECDSA",
52
+ namedCurve: "P-256"
53
+ // ES256
54
+ },
55
+ true,
56
+ // whether the key is extractable (i.e., can be used in exportKey)
57
+ ["sign", "verify"]
58
+ // can be used to sign and verify signatures
59
+ );
60
+ const publicKeyJWK = yield window.crypto.subtle.exportKey(
61
+ "jwk",
62
+ keyPair.publicKey
63
+ );
64
+ const privateKeyJWK = yield window.crypto.subtle.exportKey(
65
+ "jwk",
66
+ keyPair.privateKey
67
+ );
68
+ return { publicKey: publicKeyJWK, privateKey: privateKeyJWK };
69
+ });
70
+ },
71
+ getSigner(privateKeyJWK) {
72
+ return __async(this, null, function* () {
73
+ const privateKey = yield window.crypto.subtle.importKey(
74
+ "jwk",
75
+ privateKeyJWK,
76
+ {
77
+ name: "ECDSA",
78
+ namedCurve: "P-256"
79
+ // Must match the curve used to generate the key
80
+ },
81
+ true,
82
+ // whether the key is extractable (i.e., can be used in exportKey)
83
+ ["sign"]
84
+ );
85
+ return (data) => __async(this, null, function* () {
86
+ const encoder = new TextEncoder();
87
+ const signature = yield window.crypto.subtle.sign(
88
+ {
89
+ name: "ECDSA",
90
+ hash: { name: "SHA-256" }
91
+ // Required for ES256
92
+ },
93
+ privateKey,
94
+ encoder.encode(data)
95
+ );
96
+ return window.btoa(String.fromCharCode(...new Uint8Array(signature))).replace(/\+/g, "-").replace(/\//g, "_").replace(/=+$/, "");
97
+ });
98
+ });
99
+ },
100
+ getVerifier(publicKeyJWK) {
101
+ return __async(this, null, function* () {
102
+ const publicKey = yield window.crypto.subtle.importKey(
103
+ "jwk",
104
+ publicKeyJWK,
105
+ {
106
+ name: "ECDSA",
107
+ namedCurve: "P-256"
108
+ // Must match the curve used to generate the key
109
+ },
110
+ true,
111
+ // whether the key is extractable (i.e., can be used in exportKey)
112
+ ["verify"]
113
+ );
114
+ return (data, signatureBase64url) => __async(this, null, function* () {
115
+ const encoder = new TextEncoder();
116
+ const signature = Uint8Array.from(
117
+ atob(signatureBase64url.replace(/-/g, "+").replace(/_/g, "/")),
118
+ (c) => c.charCodeAt(0)
119
+ );
120
+ const isValid = yield window.crypto.subtle.verify(
121
+ {
122
+ name: "ECDSA",
123
+ hash: { name: "SHA-256" }
124
+ // Required for ES256
125
+ },
126
+ publicKey,
127
+ signature,
128
+ encoder.encode(data)
129
+ );
130
+ return isValid;
131
+ });
132
+ });
133
+ }
134
+ };
45
135
  export {
136
+ ES256,
46
137
  digest,
47
138
  generateSalt,
48
139
  getHasher
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@sd-jwt/crypto-browser",
3
- "version": "0.3.2-next.71+0dbc55c",
3
+ "version": "0.3.2-next.73+2d8206e",
4
4
  "description": "sd-jwt draft 7 implementation in typescript",
5
5
  "main": "dist/index.js",
6
6
  "module": "dist/index.mjs",
@@ -49,5 +49,5 @@
49
49
  "esm"
50
50
  ]
51
51
  },
52
- "gitHead": "0dbc55ce2cd8fafe107422a28edafb61501416fd"
52
+ "gitHead": "2d8206e45a61630743be32fe8d490bf001d82a5e"
53
53
  }
package/src/crypto.ts CHANGED
@@ -25,3 +25,93 @@ export async function digest(
25
25
  export const getHasher = (algorithm = 'SHA-256') => {
26
26
  return (data: string) => digest(data, algorithm);
27
27
  };
28
+
29
+ export const ES256 = {
30
+ alg: 'ES256',
31
+
32
+ async generateKeyPair() {
33
+ const keyPair = await window.crypto.subtle.generateKey(
34
+ {
35
+ name: 'ECDSA',
36
+ namedCurve: 'P-256', // ES256
37
+ },
38
+ true, // whether the key is extractable (i.e., can be used in exportKey)
39
+ ['sign', 'verify'], // can be used to sign and verify signatures
40
+ );
41
+
42
+ // Export the public and private keys in JWK format
43
+ const publicKeyJWK = await window.crypto.subtle.exportKey(
44
+ 'jwk',
45
+ keyPair.publicKey,
46
+ );
47
+ const privateKeyJWK = await window.crypto.subtle.exportKey(
48
+ 'jwk',
49
+ keyPair.privateKey,
50
+ );
51
+
52
+ return { publicKey: publicKeyJWK, privateKey: privateKeyJWK };
53
+ },
54
+
55
+ async getSigner(privateKeyJWK: object) {
56
+ const privateKey = await window.crypto.subtle.importKey(
57
+ 'jwk',
58
+ privateKeyJWK,
59
+ {
60
+ name: 'ECDSA',
61
+ namedCurve: 'P-256', // Must match the curve used to generate the key
62
+ },
63
+ true, // whether the key is extractable (i.e., can be used in exportKey)
64
+ ['sign'],
65
+ );
66
+
67
+ return async (data: string) => {
68
+ const encoder = new TextEncoder();
69
+ const signature = await window.crypto.subtle.sign(
70
+ {
71
+ name: 'ECDSA',
72
+ hash: { name: 'SHA-256' }, // Required for ES256
73
+ },
74
+ privateKey,
75
+ encoder.encode(data),
76
+ );
77
+
78
+ return window
79
+ .btoa(String.fromCharCode(...new Uint8Array(signature)))
80
+ .replace(/\+/g, '-')
81
+ .replace(/\//g, '_')
82
+ .replace(/=+$/, ''); // Convert to base64url format
83
+ };
84
+ },
85
+
86
+ async getVerifier(publicKeyJWK: object) {
87
+ const publicKey = await window.crypto.subtle.importKey(
88
+ 'jwk',
89
+ publicKeyJWK,
90
+ {
91
+ name: 'ECDSA',
92
+ namedCurve: 'P-256', // Must match the curve used to generate the key
93
+ },
94
+ true, // whether the key is extractable (i.e., can be used in exportKey)
95
+ ['verify'],
96
+ );
97
+
98
+ return async (data: string, signatureBase64url: string) => {
99
+ const encoder = new TextEncoder();
100
+ const signature = Uint8Array.from(
101
+ atob(signatureBase64url.replace(/-/g, '+').replace(/_/g, '/')),
102
+ (c) => c.charCodeAt(0),
103
+ );
104
+ const isValid = await window.crypto.subtle.verify(
105
+ {
106
+ name: 'ECDSA',
107
+ hash: { name: 'SHA-256' }, // Required for ES256
108
+ },
109
+ publicKey,
110
+ signature,
111
+ encoder.encode(data),
112
+ );
113
+
114
+ return isValid;
115
+ };
116
+ },
117
+ };
@@ -1,5 +1,5 @@
1
- import { describe, expect, test, it } from 'vitest';
2
- import { generateSalt, digest, getHasher } from '../index';
1
+ import { describe, expect, test } from 'vitest';
2
+ import { generateSalt, digest, getHasher, ES256 } from '../index';
3
3
 
4
4
  // Extract the major version as a number
5
5
  const nodeVersionMajor = parseInt(
@@ -41,4 +41,25 @@ describe('This file is for utility functions', () => {
41
41
  const hash = await getHasher('SHA-512')('test1');
42
42
  expect(hash).toBeDefined();
43
43
  });
44
+
45
+ (nodeVersionMajor < 20 ? test.skip : test)('ES256 alg', () => {
46
+ expect(ES256.alg).toBe('ES256');
47
+ });
48
+
49
+ (nodeVersionMajor < 20 ? test.skip : test)('ES256', async () => {
50
+ const { privateKey, publicKey } = await ES256.generateKeyPair();
51
+ expect(privateKey).toBeDefined();
52
+ expect(publicKey).toBeDefined();
53
+ expect(typeof privateKey).toBe('object');
54
+ expect(typeof publicKey).toBe('object');
55
+
56
+ const data =
57
+ 'In cryptography, a salt is random data that is used as an additional input to a one-way function that hashes data, a password or passphrase.';
58
+ const signature = await (await ES256.getSigner(privateKey))(data);
59
+ expect(signature).toBeDefined();
60
+ expect(typeof signature).toBe('string');
61
+
62
+ const result = await (await ES256.getVerifier(publicKey))(data, signature);
63
+ expect(result).toBe(true);
64
+ });
44
65
  });