@libp2p/keychain 4.1.6 → 5.0.0-1210884ed
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.min.js +3 -3
- package/dist/src/index.d.ts +31 -51
- package/dist/src/index.d.ts.map +1 -1
- package/dist/src/index.js +2 -2
- package/dist/src/index.js.map +1 -1
- package/dist/src/keychain.d.ts +9 -54
- package/dist/src/keychain.d.ts.map +1 -1
- package/dist/src/keychain.js +100 -255
- package/dist/src/keychain.js.map +1 -1
- package/dist/src/utils/constants.d.ts +4 -0
- package/dist/src/utils/constants.d.ts.map +1 -0
- package/dist/src/utils/constants.js +4 -0
- package/dist/src/utils/constants.js.map +1 -0
- package/dist/src/utils/export.d.ts +33 -0
- package/dist/src/utils/export.d.ts.map +1 -0
- package/dist/src/utils/export.js +183 -0
- package/dist/src/utils/export.js.map +1 -0
- package/dist/src/utils/import.d.ts +15 -0
- package/dist/src/utils/import.d.ts.map +1 -0
- package/dist/src/utils/import.js +137 -0
- package/dist/src/utils/import.js.map +1 -0
- package/package.json +9 -9
- package/src/index.ts +33 -56
- package/src/keychain.ts +113 -278
- package/src/utils/constants.ts +3 -0
- package/src/utils/export.ts +210 -0
- package/src/utils/import.ts +174 -0
- package/dist/src/errors.d.ts +0 -18
- package/dist/src/errors.d.ts.map +0 -1
- package/dist/src/errors.js +0 -19
- package/dist/src/errors.js.map +0 -1
- package/dist/src/util.d.ts +0 -12
- package/dist/src/util.d.ts.map +0 -1
- package/dist/src/util.js +0 -17
- package/dist/src/util.js.map +0 -1
- package/dist/typedoc-urls.json +0 -14
- package/src/errors.ts +0 -17
- package/src/util.ts +0 -16
|
@@ -0,0 +1,183 @@
|
|
|
1
|
+
import { randomBytes } from '@libp2p/crypto';
|
|
2
|
+
import { AES_GCM } from '@libp2p/crypto/ciphers';
|
|
3
|
+
import { privateKeyToProtobuf } from '@libp2p/crypto/keys';
|
|
4
|
+
import webcrypto from '@libp2p/crypto/webcrypto';
|
|
5
|
+
import { InvalidParametersError, UnsupportedKeyTypeError } from '@libp2p/interface';
|
|
6
|
+
import { pbkdf2Async } from '@noble/hashes/pbkdf2';
|
|
7
|
+
import { sha512 } from '@noble/hashes/sha512';
|
|
8
|
+
import * as asn1js from 'asn1js';
|
|
9
|
+
import { base64 } from 'multiformats/bases/base64';
|
|
10
|
+
import { toString as uint8ArrayToString } from 'uint8arrays/to-string';
|
|
11
|
+
import { ITERATIONS, KEY_SIZE, SALT_LENGTH } from './constants.js';
|
|
12
|
+
/**
|
|
13
|
+
* Exports the given PrivateKey as a base64 encoded string.
|
|
14
|
+
* The PrivateKey is encrypted via a password derived PBKDF2 key
|
|
15
|
+
* leveraging the aes-gcm cipher algorithm.
|
|
16
|
+
*/
|
|
17
|
+
export async function exporter(privateKey, password) {
|
|
18
|
+
const cipher = AES_GCM.create();
|
|
19
|
+
const encryptedKey = await cipher.encrypt(privateKey, password);
|
|
20
|
+
return base64.encode(encryptedKey);
|
|
21
|
+
}
|
|
22
|
+
/**
|
|
23
|
+
* Converts an exported private key into its representative object.
|
|
24
|
+
*
|
|
25
|
+
* Supported formats are 'pem' (RSA only) and 'libp2p-key'.
|
|
26
|
+
*/
|
|
27
|
+
export async function exportPrivateKey(key, password, format) {
|
|
28
|
+
if (key.type === 'RSA') {
|
|
29
|
+
return exportRSAPrivateKey(key, password, format);
|
|
30
|
+
}
|
|
31
|
+
if (key.type === 'Ed25519') {
|
|
32
|
+
return exportEd25519PrivateKey(key, password, format);
|
|
33
|
+
}
|
|
34
|
+
if (key.type === 'secp256k1') {
|
|
35
|
+
return exportSecp256k1PrivateKey(key, password, format);
|
|
36
|
+
}
|
|
37
|
+
throw new UnsupportedKeyTypeError();
|
|
38
|
+
}
|
|
39
|
+
/**
|
|
40
|
+
* Exports the key into a password protected `format`
|
|
41
|
+
*/
|
|
42
|
+
export async function exportEd25519PrivateKey(key, password, format = 'libp2p-key') {
|
|
43
|
+
if (format === 'libp2p-key') {
|
|
44
|
+
return exporter(privateKeyToProtobuf(key), password);
|
|
45
|
+
}
|
|
46
|
+
else {
|
|
47
|
+
throw new InvalidParametersError(`export format '${format}' is not supported`);
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
/**
|
|
51
|
+
* Exports the key into a password protected `format`
|
|
52
|
+
*/
|
|
53
|
+
export async function exportSecp256k1PrivateKey(key, password, format = 'libp2p-key') {
|
|
54
|
+
if (format === 'libp2p-key') {
|
|
55
|
+
return exporter(privateKeyToProtobuf(key), password);
|
|
56
|
+
}
|
|
57
|
+
else {
|
|
58
|
+
throw new InvalidParametersError('Export format is not supported');
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
/**
|
|
62
|
+
* Exports the key as libp2p-key - a aes-gcm encrypted value with the key
|
|
63
|
+
* derived from the password.
|
|
64
|
+
*
|
|
65
|
+
* To export it as a password protected PEM file, please use the `exportPEM`
|
|
66
|
+
* function from `@libp2p/rsa`.
|
|
67
|
+
*/
|
|
68
|
+
export async function exportRSAPrivateKey(key, password, format = 'pkcs-8') {
|
|
69
|
+
if (format === 'pkcs-8') {
|
|
70
|
+
return exportToPem(key, password);
|
|
71
|
+
}
|
|
72
|
+
else if (format === 'libp2p-key') {
|
|
73
|
+
return exporter(privateKeyToProtobuf(key), password);
|
|
74
|
+
}
|
|
75
|
+
else {
|
|
76
|
+
throw new InvalidParametersError('Export format is not supported');
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
export async function exportToPem(privateKey, password) {
|
|
80
|
+
const crypto = webcrypto.get();
|
|
81
|
+
// PrivateKeyInfo
|
|
82
|
+
const keyWrapper = new asn1js.Sequence({
|
|
83
|
+
value: [
|
|
84
|
+
// version (0)
|
|
85
|
+
new asn1js.Integer({ value: 0 }),
|
|
86
|
+
// privateKeyAlgorithm
|
|
87
|
+
new asn1js.Sequence({
|
|
88
|
+
value: [
|
|
89
|
+
// rsaEncryption OID
|
|
90
|
+
new asn1js.ObjectIdentifier({
|
|
91
|
+
value: '1.2.840.113549.1.1.1'
|
|
92
|
+
}),
|
|
93
|
+
new asn1js.Null()
|
|
94
|
+
]
|
|
95
|
+
}),
|
|
96
|
+
// PrivateKey
|
|
97
|
+
new asn1js.OctetString({
|
|
98
|
+
valueHex: privateKey.raw
|
|
99
|
+
})
|
|
100
|
+
]
|
|
101
|
+
});
|
|
102
|
+
const keyBuf = keyWrapper.toBER();
|
|
103
|
+
const keyArr = new Uint8Array(keyBuf, 0, keyBuf.byteLength);
|
|
104
|
+
const salt = randomBytes(SALT_LENGTH);
|
|
105
|
+
const encryptionKey = await pbkdf2Async(sha512, password, salt, {
|
|
106
|
+
c: ITERATIONS,
|
|
107
|
+
dkLen: KEY_SIZE
|
|
108
|
+
});
|
|
109
|
+
const iv = randomBytes(16);
|
|
110
|
+
const cryptoKey = await crypto.subtle.importKey('raw', encryptionKey, 'AES-CBC', false, ['encrypt']);
|
|
111
|
+
const encrypted = await crypto.subtle.encrypt({
|
|
112
|
+
name: 'AES-CBC',
|
|
113
|
+
iv
|
|
114
|
+
}, cryptoKey, keyArr);
|
|
115
|
+
const pbkdf2Params = new asn1js.Sequence({
|
|
116
|
+
value: [
|
|
117
|
+
// salt
|
|
118
|
+
new asn1js.OctetString({ valueHex: salt }),
|
|
119
|
+
// iteration count
|
|
120
|
+
new asn1js.Integer({ value: ITERATIONS }),
|
|
121
|
+
// key length
|
|
122
|
+
new asn1js.Integer({ value: KEY_SIZE }),
|
|
123
|
+
// AlgorithmIdentifier
|
|
124
|
+
new asn1js.Sequence({
|
|
125
|
+
value: [
|
|
126
|
+
// hmacWithSHA512
|
|
127
|
+
new asn1js.ObjectIdentifier({ value: '1.2.840.113549.2.11' }),
|
|
128
|
+
new asn1js.Null()
|
|
129
|
+
]
|
|
130
|
+
})
|
|
131
|
+
]
|
|
132
|
+
});
|
|
133
|
+
const encryptionAlgorithm = new asn1js.Sequence({
|
|
134
|
+
value: [
|
|
135
|
+
// pkcs5PBES2
|
|
136
|
+
new asn1js.ObjectIdentifier({
|
|
137
|
+
value: '1.2.840.113549.1.5.13'
|
|
138
|
+
}),
|
|
139
|
+
new asn1js.Sequence({
|
|
140
|
+
value: [
|
|
141
|
+
// keyDerivationFunc
|
|
142
|
+
new asn1js.Sequence({
|
|
143
|
+
value: [
|
|
144
|
+
// pkcs5PBKDF2
|
|
145
|
+
new asn1js.ObjectIdentifier({
|
|
146
|
+
value: '1.2.840.113549.1.5.12'
|
|
147
|
+
}),
|
|
148
|
+
// PBKDF2-params
|
|
149
|
+
pbkdf2Params
|
|
150
|
+
]
|
|
151
|
+
}),
|
|
152
|
+
// encryptionScheme
|
|
153
|
+
new asn1js.Sequence({
|
|
154
|
+
value: [
|
|
155
|
+
// aes256-CBC
|
|
156
|
+
new asn1js.ObjectIdentifier({
|
|
157
|
+
value: '2.16.840.1.101.3.4.1.42'
|
|
158
|
+
}),
|
|
159
|
+
// iv
|
|
160
|
+
new asn1js.OctetString({
|
|
161
|
+
valueHex: iv
|
|
162
|
+
})
|
|
163
|
+
]
|
|
164
|
+
})
|
|
165
|
+
]
|
|
166
|
+
})
|
|
167
|
+
]
|
|
168
|
+
});
|
|
169
|
+
const finalWrapper = new asn1js.Sequence({
|
|
170
|
+
value: [
|
|
171
|
+
encryptionAlgorithm,
|
|
172
|
+
new asn1js.OctetString({ valueHex: encrypted })
|
|
173
|
+
]
|
|
174
|
+
});
|
|
175
|
+
const finalWrapperBuf = finalWrapper.toBER();
|
|
176
|
+
const finalWrapperArr = new Uint8Array(finalWrapperBuf, 0, finalWrapperBuf.byteLength);
|
|
177
|
+
return [
|
|
178
|
+
'-----BEGIN ENCRYPTED PRIVATE KEY-----',
|
|
179
|
+
...uint8ArrayToString(finalWrapperArr, 'base64pad').split(/(.{64})/).filter(Boolean),
|
|
180
|
+
'-----END ENCRYPTED PRIVATE KEY-----'
|
|
181
|
+
].join('\n');
|
|
182
|
+
}
|
|
183
|
+
//# sourceMappingURL=export.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"export.js","sourceRoot":"","sources":["../../../src/utils/export.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import type { PrivateKey, RSAPrivateKey } from '@libp2p/interface';
|
|
2
|
+
/**
|
|
3
|
+
* Converts an exported private key into its representative object.
|
|
4
|
+
*
|
|
5
|
+
* Supported formats are 'pem' (RSA only) and 'libp2p-key'.
|
|
6
|
+
*/
|
|
7
|
+
export declare function importPrivateKey(encryptedKey: string, password: string): Promise<PrivateKey>;
|
|
8
|
+
/**
|
|
9
|
+
* Attempts to decrypt a base64 encoded PrivateKey string
|
|
10
|
+
* with the given password. The privateKey must have been exported
|
|
11
|
+
* using the same password and underlying cipher (aes-gcm)
|
|
12
|
+
*/
|
|
13
|
+
export declare function importer(privateKey: string, password: string): Promise<Uint8Array>;
|
|
14
|
+
export declare function importFromPem(pem: string, password: string): Promise<RSAPrivateKey>;
|
|
15
|
+
//# sourceMappingURL=import.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"import.d.ts","sourceRoot":"","sources":["../../../src/utils/import.ts"],"names":[],"mappings":"AAUA,OAAO,KAAK,EAAE,UAAU,EAAE,aAAa,EAAE,MAAM,mBAAmB,CAAA;AAElE;;;;GAIG;AACH,wBAAsB,gBAAgB,CAAE,YAAY,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,UAAU,CAAC,CAanG;AAED;;;;GAIG;AACH,wBAAsB,QAAQ,CAAE,UAAU,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,UAAU,CAAC,CAIzF;AAED,wBAAsB,aAAa,CAAE,GAAG,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,aAAa,CAAC,CAiE1F"}
|
|
@@ -0,0 +1,137 @@
|
|
|
1
|
+
import { AES_GCM } from '@libp2p/crypto/ciphers';
|
|
2
|
+
import { privateKeyFromProtobuf, privateKeyFromRaw } from '@libp2p/crypto/keys';
|
|
3
|
+
import webcrypto from '@libp2p/crypto/webcrypto';
|
|
4
|
+
import { InvalidParametersError } from '@libp2p/interface';
|
|
5
|
+
import { pbkdf2Async } from '@noble/hashes/pbkdf2';
|
|
6
|
+
import { sha512 } from '@noble/hashes/sha512';
|
|
7
|
+
import * as asn1js from 'asn1js';
|
|
8
|
+
import { base64 } from 'multiformats/bases/base64';
|
|
9
|
+
import { fromString as uint8ArrayFromString } from 'uint8arrays/from-string';
|
|
10
|
+
import { ITERATIONS, KEY_SIZE } from './constants.js';
|
|
11
|
+
/**
|
|
12
|
+
* Converts an exported private key into its representative object.
|
|
13
|
+
*
|
|
14
|
+
* Supported formats are 'pem' (RSA only) and 'libp2p-key'.
|
|
15
|
+
*/
|
|
16
|
+
export async function importPrivateKey(encryptedKey, password) {
|
|
17
|
+
try {
|
|
18
|
+
const key = await importer(encryptedKey, password);
|
|
19
|
+
return privateKeyFromProtobuf(key);
|
|
20
|
+
}
|
|
21
|
+
catch {
|
|
22
|
+
// Ignore and try the old pem decrypt
|
|
23
|
+
}
|
|
24
|
+
if (!encryptedKey.includes('BEGIN')) {
|
|
25
|
+
throw new InvalidParametersError('Encrypted key was not a libp2p-key or a PEM file');
|
|
26
|
+
}
|
|
27
|
+
return importFromPem(encryptedKey, password);
|
|
28
|
+
}
|
|
29
|
+
/**
|
|
30
|
+
* Attempts to decrypt a base64 encoded PrivateKey string
|
|
31
|
+
* with the given password. The privateKey must have been exported
|
|
32
|
+
* using the same password and underlying cipher (aes-gcm)
|
|
33
|
+
*/
|
|
34
|
+
export async function importer(privateKey, password) {
|
|
35
|
+
const encryptedKey = base64.decode(privateKey);
|
|
36
|
+
const cipher = AES_GCM.create();
|
|
37
|
+
return cipher.decrypt(encryptedKey, password);
|
|
38
|
+
}
|
|
39
|
+
export async function importFromPem(pem, password) {
|
|
40
|
+
const crypto = webcrypto.get();
|
|
41
|
+
let plaintext;
|
|
42
|
+
if (pem.includes('-----BEGIN ENCRYPTED PRIVATE KEY-----')) {
|
|
43
|
+
const key = uint8ArrayFromString(pem
|
|
44
|
+
.replace('-----BEGIN ENCRYPTED PRIVATE KEY-----', '')
|
|
45
|
+
.replace('-----END ENCRYPTED PRIVATE KEY-----', '')
|
|
46
|
+
.replace(/\n/g, '')
|
|
47
|
+
.trim(), 'base64pad');
|
|
48
|
+
const { result } = asn1js.fromBER(key);
|
|
49
|
+
const { iv, salt, iterations, keySize, cipherText } = findEncryptedPEMData(result);
|
|
50
|
+
const encryptionKey = await pbkdf2Async(sha512, password, salt, {
|
|
51
|
+
c: iterations,
|
|
52
|
+
dkLen: keySize
|
|
53
|
+
});
|
|
54
|
+
const cryptoKey = await crypto.subtle.importKey('raw', encryptionKey, 'AES-CBC', false, ['decrypt']);
|
|
55
|
+
const decrypted = toUint8Array(await crypto.subtle.decrypt({
|
|
56
|
+
name: 'AES-CBC',
|
|
57
|
+
iv
|
|
58
|
+
}, cryptoKey, cipherText));
|
|
59
|
+
const { result: decryptedResult } = asn1js.fromBER(decrypted);
|
|
60
|
+
plaintext = findPEMData(decryptedResult);
|
|
61
|
+
}
|
|
62
|
+
else if (pem.includes('-----BEGIN PRIVATE KEY-----')) {
|
|
63
|
+
const key = uint8ArrayFromString(pem
|
|
64
|
+
.replace('-----BEGIN PRIVATE KEY-----', '')
|
|
65
|
+
.replace('-----END PRIVATE KEY-----', '')
|
|
66
|
+
.replace(/\n/g, '')
|
|
67
|
+
.trim(), 'base64pad');
|
|
68
|
+
const { result } = asn1js.fromBER(key);
|
|
69
|
+
plaintext = findPEMData(result);
|
|
70
|
+
}
|
|
71
|
+
else {
|
|
72
|
+
throw new InvalidParametersError('Could not parse private key from PEM data');
|
|
73
|
+
}
|
|
74
|
+
const key = privateKeyFromRaw(plaintext);
|
|
75
|
+
if (key.type !== 'RSA') {
|
|
76
|
+
throw new InvalidParametersError('Could not parse RSA private key from PEM data');
|
|
77
|
+
}
|
|
78
|
+
return key;
|
|
79
|
+
}
|
|
80
|
+
function findEncryptedPEMData(root) {
|
|
81
|
+
const encryptionAlgorithm = root.valueBlock.value[0];
|
|
82
|
+
const scheme = encryptionAlgorithm.valueBlock.value[0].toString();
|
|
83
|
+
if (scheme !== 'OBJECT IDENTIFIER : 1.2.840.113549.1.5.13') {
|
|
84
|
+
throw new InvalidParametersError('Only pkcs5PBES2 encrypted private keys are supported');
|
|
85
|
+
}
|
|
86
|
+
const keyDerivationFunc = encryptionAlgorithm.valueBlock.value[1].valueBlock.value[0];
|
|
87
|
+
const keyDerivationFuncName = keyDerivationFunc.valueBlock.value[0].toString();
|
|
88
|
+
if (keyDerivationFuncName !== 'OBJECT IDENTIFIER : 1.2.840.113549.1.5.12') {
|
|
89
|
+
throw new InvalidParametersError('Only pkcs5PBKDF2 key derivation functions are supported');
|
|
90
|
+
}
|
|
91
|
+
const pbkdf2Params = keyDerivationFunc.valueBlock.value[1];
|
|
92
|
+
const salt = toUint8Array(pbkdf2Params.valueBlock.value[0].getValue());
|
|
93
|
+
let iterations = ITERATIONS;
|
|
94
|
+
let keySize = KEY_SIZE;
|
|
95
|
+
if (pbkdf2Params.valueBlock.value.length === 3) {
|
|
96
|
+
iterations = Number(pbkdf2Params.valueBlock.value[1].toBigInt());
|
|
97
|
+
keySize = Number((pbkdf2Params.valueBlock.value[2]).toBigInt());
|
|
98
|
+
}
|
|
99
|
+
else if (pbkdf2Params.valueBlock.value.length === 2) {
|
|
100
|
+
throw new InvalidParametersError('Could not derive key size and iterations from PEM file - please use @libp2p/rsa to re-import your key');
|
|
101
|
+
}
|
|
102
|
+
const encryptionScheme = encryptionAlgorithm.valueBlock.value[1].valueBlock.value[1];
|
|
103
|
+
const encryptionSchemeName = encryptionScheme.valueBlock.value[0].toString();
|
|
104
|
+
if (encryptionSchemeName === 'OBJECT IDENTIFIER : 1.2.840.113549.3.7') {
|
|
105
|
+
// des-EDE3-CBC
|
|
106
|
+
}
|
|
107
|
+
else if (encryptionSchemeName === 'OBJECT IDENTIFIER : 1.3.14.3.2.7') {
|
|
108
|
+
// des-CBC
|
|
109
|
+
}
|
|
110
|
+
else if (encryptionSchemeName === 'OBJECT IDENTIFIER : 2.16.840.1.101.3.4.1.2') {
|
|
111
|
+
// aes128-CBC
|
|
112
|
+
}
|
|
113
|
+
else if (encryptionSchemeName === 'OBJECT IDENTIFIER : 2.16.840.1.101.3.4.1.22') {
|
|
114
|
+
// aes192-CBC
|
|
115
|
+
}
|
|
116
|
+
else if (encryptionSchemeName === 'OBJECT IDENTIFIER : 2.16.840.1.101.3.4.1.42') {
|
|
117
|
+
// aes256-CBC
|
|
118
|
+
}
|
|
119
|
+
else {
|
|
120
|
+
throw new InvalidParametersError('Only AES-CBC encryption schemes are supported');
|
|
121
|
+
}
|
|
122
|
+
const iv = toUint8Array(encryptionScheme.valueBlock.value[1].getValue());
|
|
123
|
+
return {
|
|
124
|
+
cipherText: toUint8Array(root.valueBlock.value[1].getValue()),
|
|
125
|
+
salt,
|
|
126
|
+
iterations,
|
|
127
|
+
keySize,
|
|
128
|
+
iv
|
|
129
|
+
};
|
|
130
|
+
}
|
|
131
|
+
function findPEMData(seq) {
|
|
132
|
+
return toUint8Array(seq.valueBlock.value[2].getValue());
|
|
133
|
+
}
|
|
134
|
+
function toUint8Array(buf) {
|
|
135
|
+
return new Uint8Array(buf, 0, buf.byteLength);
|
|
136
|
+
}
|
|
137
|
+
//# sourceMappingURL=import.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"import.js","sourceRoot":"","sources":["../../../src/utils/import.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@libp2p/keychain",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "5.0.0-1210884ed",
|
|
4
4
|
"description": "Key management and cryptographically protected messages",
|
|
5
5
|
"license": "Apache-2.0 OR MIT",
|
|
6
6
|
"homepage": "https://github.com/libp2p/js-libp2p/tree/main/packages/keychain#readme",
|
|
@@ -59,20 +59,20 @@
|
|
|
59
59
|
"test:electron-main": "aegir test -t electron-main"
|
|
60
60
|
},
|
|
61
61
|
"dependencies": {
|
|
62
|
-
"@libp2p/crypto": "
|
|
63
|
-
"@libp2p/interface": "
|
|
64
|
-
"@
|
|
65
|
-
"
|
|
62
|
+
"@libp2p/crypto": "5.0.0-1210884ed",
|
|
63
|
+
"@libp2p/interface": "2.0.0-1210884ed",
|
|
64
|
+
"@noble/hashes": "^1.5.0",
|
|
65
|
+
"asn1js": "^3.0.5",
|
|
66
|
+
"interface-datastore": "^8.3.0",
|
|
66
67
|
"merge-options": "^3.0.4",
|
|
67
|
-
"multiformats": "^13.
|
|
68
|
+
"multiformats": "^13.2.2",
|
|
68
69
|
"sanitize-filename": "^1.6.3",
|
|
69
70
|
"uint8arrays": "^5.1.0"
|
|
70
71
|
},
|
|
71
72
|
"devDependencies": {
|
|
72
|
-
"@libp2p/logger": "
|
|
73
|
-
"@libp2p/peer-id-factory": "^4.2.4",
|
|
73
|
+
"@libp2p/logger": "5.0.0-1210884ed",
|
|
74
74
|
"aegir": "^44.0.1",
|
|
75
|
-
"datastore-core": "^
|
|
75
|
+
"datastore-core": "^10.0.0"
|
|
76
76
|
},
|
|
77
77
|
"sideEffects": false
|
|
78
78
|
}
|
package/src/index.ts
CHANGED
|
@@ -51,10 +51,9 @@
|
|
|
51
51
|
* A key benefit is that now the key chain can be used in browser with the [js-datastore-level](https://github.com/ipfs/js-datastore-level) implementation.
|
|
52
52
|
*/
|
|
53
53
|
|
|
54
|
-
import {
|
|
55
|
-
import type { ComponentLogger,
|
|
54
|
+
import { Keychain as KeychainClass } from './keychain.js'
|
|
55
|
+
import type { ComponentLogger, PrivateKey } from '@libp2p/interface'
|
|
56
56
|
import type { Datastore } from 'interface-datastore'
|
|
57
|
-
import type { Multibase } from 'multiformats/bases/interface.js'
|
|
58
57
|
|
|
59
58
|
export interface DEKConfig {
|
|
60
59
|
hash: string
|
|
@@ -87,73 +86,63 @@ export interface KeyInfo {
|
|
|
87
86
|
|
|
88
87
|
export interface Keychain {
|
|
89
88
|
/**
|
|
90
|
-
*
|
|
89
|
+
* Find a key by name
|
|
91
90
|
*
|
|
92
91
|
* @example
|
|
93
92
|
*
|
|
94
93
|
* ```TypeScript
|
|
95
|
-
*
|
|
96
|
-
* const pemKey = await libp2p.services.keychain.exportKey('keyTest', 'password123')
|
|
97
|
-
* ```
|
|
98
|
-
*/
|
|
99
|
-
exportKey(name: string, password: string): Promise<Multibase<'m'>>
|
|
100
|
-
|
|
101
|
-
/**
|
|
102
|
-
* Import a new key from a PEM encoded PKCS #8 string.
|
|
103
|
-
*
|
|
104
|
-
* @example
|
|
94
|
+
* import { generateKeyPair } from '@libp2p/crypto/keys'
|
|
105
95
|
*
|
|
106
|
-
*
|
|
107
|
-
* await libp2p.
|
|
108
|
-
* const
|
|
109
|
-
* const keyInfo = await libp2p.services.keychain.importKey('keyTestImport', pemKey, 'password123')
|
|
96
|
+
* const key = await generateKeyPair('Ed25519')
|
|
97
|
+
* const keyInfo = await libp2p.keychain.importKey('my-key', key)
|
|
98
|
+
* const keyInfo2 = await libp2p.keychain.findKeyByName(keyInfo.name)
|
|
110
99
|
* ```
|
|
111
100
|
*/
|
|
112
|
-
|
|
101
|
+
findKeyByName(name: string): Promise<KeyInfo>
|
|
113
102
|
|
|
114
103
|
/**
|
|
115
|
-
*
|
|
104
|
+
* Find a key by id
|
|
116
105
|
*
|
|
117
106
|
* @example
|
|
118
107
|
*
|
|
119
108
|
* ```TypeScript
|
|
120
|
-
*
|
|
121
|
-
* ```
|
|
122
|
-
*/
|
|
123
|
-
importPeer(name: string, peerId: PeerId): Promise<KeyInfo>
|
|
124
|
-
|
|
125
|
-
/**
|
|
126
|
-
* Export an existing key as a PeerId
|
|
127
|
-
*
|
|
128
|
-
* @example
|
|
109
|
+
* import { generateKeyPair } from '@libp2p/crypto/keys'
|
|
129
110
|
*
|
|
130
|
-
*
|
|
131
|
-
* const
|
|
111
|
+
* const key = await generateKeyPair('Ed25519')
|
|
112
|
+
* const keyInfo = await libp2p.keychain.importKey('my-key', key)
|
|
113
|
+
* const keyInfo2 = await libp2p.keychain.findKeyById(keyInfo.id)
|
|
132
114
|
* ```
|
|
133
115
|
*/
|
|
134
|
-
|
|
116
|
+
findKeyById (id: string): Promise<KeyInfo>
|
|
135
117
|
|
|
136
118
|
/**
|
|
137
|
-
*
|
|
119
|
+
* Import a new private key.
|
|
138
120
|
*
|
|
139
121
|
* @example
|
|
140
122
|
*
|
|
141
123
|
* ```TypeScript
|
|
142
|
-
*
|
|
124
|
+
* import { generateKeyPair } from '@libp2p/crypto/keys'
|
|
125
|
+
*
|
|
126
|
+
* const key = await generateKeyPair('Ed25519')
|
|
127
|
+
* const keyInfo = await libp2p.keychain.importKey('my-key', key)
|
|
143
128
|
* ```
|
|
144
129
|
*/
|
|
145
|
-
|
|
130
|
+
importKey(name: string, key: PrivateKey): Promise<KeyInfo>
|
|
146
131
|
|
|
147
132
|
/**
|
|
148
|
-
*
|
|
133
|
+
* Export an existing private key.
|
|
149
134
|
*
|
|
150
135
|
* @example
|
|
151
136
|
*
|
|
152
137
|
* ```TypeScript
|
|
153
|
-
*
|
|
138
|
+
* import { generateKeyPair } from '@libp2p/crypto/keys'
|
|
139
|
+
*
|
|
140
|
+
* const key = await generateKeyPair('Ed25519')
|
|
141
|
+
* const keyInfo = await libp2p.keychain.importKey('my-key', key)
|
|
142
|
+
* const key = await libp2p.keychain.exportKey(keyInfo.id)
|
|
154
143
|
* ```
|
|
155
144
|
*/
|
|
156
|
-
|
|
145
|
+
exportKey(name: string): Promise<PrivateKey>
|
|
157
146
|
|
|
158
147
|
/**
|
|
159
148
|
* Removes a key from the keychain.
|
|
@@ -168,7 +157,8 @@ export interface Keychain {
|
|
|
168
157
|
removeKey(name: string): Promise<KeyInfo>
|
|
169
158
|
|
|
170
159
|
/**
|
|
171
|
-
* Rename a key in the keychain.
|
|
160
|
+
* Rename a key in the keychain. This is done in a batch commit with rollback
|
|
161
|
+
* so errors thrown during the operation will not cause key loss.
|
|
172
162
|
*
|
|
173
163
|
* @example
|
|
174
164
|
*
|
|
@@ -180,28 +170,15 @@ export interface Keychain {
|
|
|
180
170
|
renameKey(oldName: string, newName: string): Promise<KeyInfo>
|
|
181
171
|
|
|
182
172
|
/**
|
|
183
|
-
*
|
|
184
|
-
*
|
|
185
|
-
* @example
|
|
186
|
-
*
|
|
187
|
-
* ```TypeScript
|
|
188
|
-
* const keyInfo = await libp2p.services.keychain.createKey('keyTest', 'RSA', 4096)
|
|
189
|
-
* const keyInfo2 = await libp2p.services.keychain.findKeyById(keyInfo.id)
|
|
190
|
-
* ```
|
|
191
|
-
*/
|
|
192
|
-
findKeyById(id: string): Promise<KeyInfo>
|
|
193
|
-
|
|
194
|
-
/**
|
|
195
|
-
* Find a key by it's name.
|
|
173
|
+
* List all the keys.
|
|
196
174
|
*
|
|
197
175
|
* @example
|
|
198
176
|
*
|
|
199
177
|
* ```TypeScript
|
|
200
|
-
* const
|
|
201
|
-
* const keyInfo2 = await libp2p.services.keychain.findKeyByName('keyTest')
|
|
178
|
+
* const keyInfos = await libp2p.keychain.listKeys()
|
|
202
179
|
* ```
|
|
203
180
|
*/
|
|
204
|
-
|
|
181
|
+
listKeys(): Promise<KeyInfo[]>
|
|
205
182
|
|
|
206
183
|
/**
|
|
207
184
|
* Rotate keychain password and re-encrypt all associated keys
|
|
@@ -217,6 +194,6 @@ export interface Keychain {
|
|
|
217
194
|
|
|
218
195
|
export function keychain (init: KeychainInit = {}): (components: KeychainComponents) => Keychain {
|
|
219
196
|
return (components: KeychainComponents) => {
|
|
220
|
-
return new
|
|
197
|
+
return new KeychainClass(components, init)
|
|
221
198
|
}
|
|
222
199
|
}
|