importKey
The importKey() imports a key from an external, portable format, and gives you a
CryptoKey object that can be used with the Web Crypto API.
Usage
importKey(format, keyData, algorithm, extractable, keyUsages)Parameters
Supported algorithms
Supported formats
For Ed25519 and X25519, import public keys as raw, spki, or jwk, and private keys as pkcs8 or jwk. Use verify only for Ed25519 public keys, sign only for Ed25519 private keys, no usages for X25519 public keys, and deriveBits or deriveKey for X25519 private keys. An OKP JWK requires kty: 'OKP', the matching crv (Ed25519 or X25519), and the public x value. A private JWK also includes d. If present, key_ops, use, and ext must agree with the requested usages and extractability. Invalid formats raise NotSupportedError; malformed key data raises DataError.
ECDHandECDSAalgorithms have support forpkcs8,spki,rawandjwkformats.RSA-OAEP,RSASSA-PKCS1-v1_5andRSA-PSSalgorithms have support forpkcs8,spkiandjwkformats.AES-*andHMACalgorithms have currently support forrawandjwkformats.PBKDF2algorithm has support forrawformat only.Ed25519andX25519public keys supportraw,spki, andjwk; their private keys supportpkcs8andjwk. Therawformat is for public keys only.
PBKDF2 constraints
When importing a key for the PBKDF2 algorithm, the following constraints apply:
extractablemust befalse. Attempting to set it totruethrows aSyntaxError.- Only the
rawformat is supported. Other formats throw aNotSupportedError. - Only
deriveBitsandderiveKeyusages are allowed. Other usages throw aSyntaxError.
Return Value
A Promise that resolves with the imported key as a
CryptoKey object.
Throws
Examples
Round-trip key export/import
export default async function () {
/**
* Generate a symmetric key using the AES-CBC algorithm.
*/
const generatedKey = await crypto.subtle.generateKey(
{
name: 'AES-CBC',
length: '256',
},
true,
['encrypt', 'decrypt']
);
/**
* Export the key in raw format.
*/
const exportedKey = await crypto.subtle.exportKey('raw', generatedKey);
/**
* Reimport the key in raw format to verify its integrity.
*/
const importedKey = await crypto.subtle.importKey('raw', exportedKey, 'AES-CBC', true, [
'encrypt',
'decrypt',
]);
console.log(JSON.stringify(importedKey));
}Import a static raw key and decrypt transmitted data
This example demonstrates how to import a static raw key and decrypt some transmitted data in base64. The transmitted data in this example represents an initialization vector and encoded data, and in a real-world scenario, it can be a response body or other data received from a request.
import { b64decode } from 'k6/encoding';
export default async function () {
const transmittedData = base64Decode(
'whzEN310mrlWIH/icf0dMquRZ2ENyfOzkvPuu92WR/9F8dbeFM8EGUVNIhaS'
);
// keyData is the key used to decrypt the data, which is usually stored in a secure location
// for this example, we are using a static key
const keyData = new Uint8Array([
109, 151, 76, 33, 232, 253, 176, 90, 94, 40, 146, 227, 139, 208, 245, 139, 69, 215, 55, 197, 43,
122, 160, 178, 228, 104, 4, 115, 138, 159, 119, 49,
]);
try {
const result = await decrypt(keyData, transmittedData);
// should output decrypted message
// INFO[0000] result: 'my secret message' source=console
console.log("result: '" + result + "'");
} catch (e) {
console.log('Error: ' + JSON.stringify(e));
}
}
const decrypt = async (keyData, transmittedData) => {
const initializeVectorLength = 12;
// the first 12 bytes are the initialization vector
const iv = new Uint8Array(transmittedData.subarray(0, initializeVectorLength));
// the rest of the transmitted data is the encrypted data
const encryptedData = new Uint8Array(transmittedData.subarray(initializeVectorLength));
const importedKey = await crypto.subtle.importKey(
'raw',
keyData,
{ name: 'AES-GCM', length: '256' },
true,
['decrypt']
);
const plain = await crypto.subtle.decrypt(
{ name: 'AES-GCM', iv: iv },
importedKey,
encryptedData
);
return new TextDecoder().decode(plain);
};
const base64Decode = (base64String) => {
return new Uint8Array(b64decode(base64String));
};Import a static JWK key and decrypt transmitted data
This example is similar to the previous one. It demonstrates how to import a static jwk key and decrypt some transmitted data (which contains the initialization vector and encoded data) in base64.
import { b64decode } from 'k6/encoding';
export default async function () {
// transmitted data is the base64 of the initialization vector + encrypted data
// that unusually transmitted over the network
const transmittedData = base64Decode(
'drCfxl4O+5FcrHe8Bs0CvKlw3gZpv+S5if3zn7c4BJzHJ35QDFV4sJB0pbDT'
);
// keyData is the key used to decrypt the data, which is usually stored in a secure location
// for this example, we are using a static key
const jwkKeyData = {
kty: 'oct',
ext: true,
key_ops: ['decrypt', 'encrypt'],
alg: 'A256GCM',
k: '9Id_8iG6FkGOWmc1S203vGVnTExtpDGxdQN7v7OV9Uc',
};
try {
const result = await decrypt(jwkKeyData, transmittedData);
// should output decrypted message
// INFO[0000] result: 'my secret message' source=console
console.log("result: '" + result + "'");
} catch (e) {
console.log('Error: ' + JSON.stringify(e));
}
}
const decrypt = async (keyData, transmittedData) => {
const initializeVectorLength = 12;
// the first 12 bytes are the initialization vector
const iv = new Uint8Array(transmittedData.subarray(0, initializeVectorLength));
// the rest of the transmitted data is the encrypted data
const encryptedData = new Uint8Array(transmittedData.subarray(initializeVectorLength));
const importedKey = await crypto.subtle.importKey(
'jwk',
keyData,
{ name: 'AES-GCM', length: 256 },
true,
['encrypt', 'decrypt']
);
const plain = await crypto.subtle.decrypt(
{ name: 'AES-GCM', iv: iv },
importedKey,
encryptedData
);
return new TextDecoder().decode(plain);
};
const base64Decode = (base64String) => {
return new Uint8Array(b64decode(base64String));
};Import a password for PBKDF2 key derivation
This example demonstrates how to import a password as key material for PBKDF2 key derivation.
export default async function () {
const password = new TextEncoder().encode('my secret password');
// Import the password as a key for PBKDF2
// Note: extractable must be false for PBKDF2
const baseKey = await crypto.subtle.importKey('raw', password, 'PBKDF2', false, [
'deriveBits',
'deriveKey',
]);
console.log('imported PBKDF2 key: ' + JSON.stringify(baseKey));
// Now you can use this key with deriveBits or deriveKey
const salt = crypto.getRandomValues(new Uint8Array(16));
const derivedBits = await crypto.subtle.deriveBits(
{
name: 'PBKDF2',
hash: 'SHA-256',
salt: salt,
iterations: 310000,
},
baseKey,
256
);
console.log('derived bits: ' + arrayBufferToHex(derivedBits));
}
function arrayBufferToHex(buffer) {
return [...new Uint8Array(buffer)].map((x) => x.toString(16).padStart(2, '0')).join('');
}
