skip to Main Content

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


  1. enter link description here

    you can see on Manual Replace,
    Cheers… 🍻

    Login or Signup to reply.
  2. USE node-rsa

    //create cipher node rsa
    const cipher = new nodeRSA({ b: 512 });
    const keyPrivate = key.private;
    const pubKey = key.public;
    
    cipher.importKey(pubKey, "pkcs1-public");
    const text = password
    const encrypted = cipher.encrypt(text, "base64");
    
    const decipher = new nodeRSA(keyPrivate, "pkcs1");
    const decrypted = decipher.decrypt(encrypted, "utf8");
    
    console.log("decrypted: ", decrypted);
    
    return setPasswordEncrypt(encrypted);
    

    }

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search