Make private key extractable too.

Main reason: https://bugzilla.mozilla.org/show_bug.cgi?id=1133698

Unfortunately, because of this bug Firefox cannot save non-exportable
keys to IndexedDB. As a workaround, we call exportKey before saving and
store JsonWebKey instead. We use importKey again while reading the key
from the database.

Extra reason for this change - during testing isomorphic-webcrypto
complains about keys read from IndexedDB.

While being less secure, this could also help users export their keys if
they want to migrate their identities to another computer...
This commit is contained in:
Jerko Steiner 2020-01-07 18:08:56 +01:00
parent 46e751cea3
commit 023c2f640b
2 changed files with 9 additions and 14 deletions

View File

@ -1,4 +1,4 @@
import { exportPublicKey, encrypt, decrypt, generateECDHKeyPair, deriveECDHKey, hasWebCryptoAPI, importPublicKey } from './index'
import { exportKey, encrypt, decrypt, generateECDHKeyPair, deriveECDHKey, hasWebCryptoAPI, importKey } from './index'
describe('crypto', () => {
@ -27,11 +27,11 @@ describe('crypto', () => {
})
})
describe('exportPublicKey and importPublicKey', () => {
describe('exportKey and importKey', () => {
it('exports public key', async () => {
const value = await exportPublicKey(keypair1.publicKey)
const value = await exportKey(keypair1.publicKey)
console.log(value)
const key = await importPublicKey(value)
const key = await importKey(value)
expect(key).toBeTruthy()
expect(key).toEqual(keypair1.publicKey)
})

View File

@ -13,7 +13,7 @@ export async function generateECDHKeyPair() {
name: 'ECDH',
namedCurve: 'P-256',
},
/* extractable */ false,
/* extractable */ true,
['deriveKey'],
)
return key
@ -34,7 +34,7 @@ export async function deriveECDHKey(params: {
name: 'AES-CTR',
length: 256,
},
/* extractable */ false,
/* extractable */ true,
['encrypt', 'decrypt'],
)
@ -68,13 +68,8 @@ export async function decrypt(key: CryptoKey, data: string): Promise<string> {
return ab2str(decrypted)
}
export async function exportPublicKey(key: CryptoKey) {
export async function exportKey(key: CryptoKey) {
return await window.crypto.subtle.exportKey('jwk', key)
// const pkcs8 = await window.crypto.subtle.exportKey('pkcs8', key)
// const base64 = window.btoa(ab2str(pkcs8, Uint8Array))
// const value =
// `-----BEGIN PUBLIC KEY-----\n${base64}\n-----END PUBLIC KEY-----`
// return value
}
function ab2str(
@ -85,7 +80,7 @@ function ab2str(
null, new ArrayType(buf) as unknown as number[])
}
export async function importPublicKey(keyData: JsonWebKey) {
export async function importKey(keyData: JsonWebKey) {
if (keyData.kty !== 'EC' || keyData.crv !== 'P-256') {
throw new Error(`Unsupported key type: ${keyData.kty}, crv: ${keyData.crv}`)
}
@ -97,7 +92,7 @@ export async function importPublicKey(keyData: JsonWebKey) {
namedCurve: keyData.crv,
},
/* extractable */ true,
[],
keyData.key_ops || [],
)
return key
}