Why am I consistently getting the error message "Data provided to an operation does not meet requirements" when using my own public key with window.crypto.subtle.importKey
, but not with a generated public key?
// .env file
PUBLIC_KEY=$'-----BEGIN PUBLIC KEY-----nMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDE70mr7SEMIvUuLKf1g3/UdIVTVnpD7niRC/P4eT+fkn7YN7xLv9Su5MJ1ths+W/IsP0LVC5k+ZOUSV62rMsmQrhgF0xz2kG1RfUpX0DfTzsYNzMKC5ydx3K1aomDent16SWSTmCXDtDIw+YOmwltVhV55zoD9ylOVlnvkj0NutQIDAQABn-----END PUBLIC KEY-----'
var plainText="some text"
/**
*
* @param {String} Algorithm
* @param {Object} Data Must be [ArrayBuffer,TypedArray]
* @param? {Object} ImportedPubkey Must be [ArrayBuffer,TypedArray]
* @returns Promise object (CipherKey) cipher text
*/
async function encrypt(algorithm, data, importedPubkey) {
let pubKey;
if (importedPubkey) {
// pubkey provided
pubKey = await crypto.subtle.importKey(
"pkcs8",
importedPubkey,
{
name: algorithm,
modulusLength: 1024,
publicExponent: new Uint8Array([1, 0, 1]),
hash: { name: 'SHA-256' },
},
true,
['encrypt']
);
} else {
// generate new key pair
let keyPair = await window.crypto.subtle.generateKey(
{
name: algorithm,
modulusLength: 1024,
publicExponent: new Uint8Array([1, 0, 1]),
hash: { name: 'SHA-256' },
},
true,
['encrypt', 'decrypt']
);
pubKey = keyPair.publicKey;
}
const cipherText = await crypto.subtle.encrypt(
{
name: algorithm
},
pubKey,
data
);
return cipherText
};
// encode pubkey & plaintext
const encoder = new TextEncoder()
const plainTextEncoded = encoder.encode(plainText);
const publicKeyEncoded = encoder.encode(process.env.PUBLIC_KEY)
encrypt('RSA-OAEP', plainTextEncoded, publicKeyEncoded)
.then(cipherText => {
// convert cipher to ArrayBuffer
const cipherTextArrayBuffer = new Uint8Array(cipherText);
// encode ArrayBuffer to Base64
const base64Encoded = btoa(String.fromCharCode.apply(null, cipherTextArrayBuffer));
doNextStep(base64Encoded)
})
.catch(e => console.log(e))
I suspect that the public key is invalid. So I’ve tried using generatedKey from code above
encrypt('RSA-OAEP', plainTextEncoded)
.then(cipherText => {
// convert cipher to ArrayBuffer
const cipherTextArrayBuffer = new Uint8Array(cipherText);
// encode ArrayBuffer to Base64
const base64Encoded = btoa(String.fromCharCode.apply(null, cipherTextArrayBuffer));
doNextStep(base64Encoded)
})
.catch(e => console.log(e))
The result is as expected (plainText encrypted). If that is indeed the case, how you store it to ensure that importKey()
accepts it?
2
Answers
enter link description here
you can see on Manual Replace,
Cheers… 🍻
USE node-rsa
}