Recently I am trying to find a way to encrypt data on PHP with a Public Key generated on javascript using window.crypto.subtle.generateKey()
async function GenerateKeys() {
let key = await window.crypto.subtle.generateKey(
{
name: "RSA-OAEP",
modulusLength: 4096,
publicExponent: new Uint8Array([0x01, 0x00, 0x01]),
hash: {name: "SHA-256"}
},
true,
["encrypt", "decrypt"]
)
let pvkey = await window.crypto.subtle.exportKey(
"pkcs8",
key.privateKey
)
let pbkey = await window.crypto.subtle.exportKey(
"spki",
key.publicKey
)
let pemPvKey = `-----BEGIN PRIVATE KEY-----\n${window.btoa(ab2str(pvkey))}\n-----END PRIVATE KEY-----`;
let pemPbKey = `-----BEGIN PUBLIC KEY-----\n${window.btoa(ab2str(pbkey))}\n-----END PUBLIC KEY-----`;
return [pemPvKey, pemPbKey]
}
I then send the public key to my PHP script and generate data
$pbkey = "-----BEGIN PUBLIC KEY-----
MIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEA52N7Q/kQxNrVaGCLOlD0IgrSROPWt029GTqRKMdFQSFMAZPD0V5TZPLDylbtmvLhDajKugYpjHfDGD44cXiYy1jZeVCiFas09gAGBKmgFY4Ixsl/+opF2hlPjvnugn2aPKpSLgoX9f1DpXBDEpuHJ+AVSTxL+C3uE1PgQPYy2ots15Km4W2AnV+p81UfLdafStQ40gbkUOHvzFkwizazm4q1Scjh2Fc+RR6FXy+ySp54yuRqHuMS8QTdXVMBChqs5lNwuu6V+BEryXMFbDx2fW9qCWShVTc2lq4KzvXRE/65L0sttMA7oP/WzsVW3zeNFgla8g4dxvCftwrwGviMay9N+vsa902TClR2xj7/JSzQXSW0E4Am4ZB4bCJh04f08M0nMBY6yWWV3+QpBG+9CeXHfwPrdqT2OR5N7Jq+xslCfbf4D/9itjDdvaBZP5Z6BYiOF3QzeTk+V2rfAWZdOUcuWAdP3gczQKdJM11bTxOKNCiYmBu773aDXCNFpaHDatqUgnNrVp7guOP1owOdd7qxWsplzylQUcWuhuWczs7/X/UPwT7vBTkg0pb8Ujrr+KyNmsxsJTefg1z4xcbxtgqgoDRxXu92V9iVl1HVssAM8IZdc+naEIyOjt+3OPZkaCwts38U7nYUDd96ovHjMs0hFlTxqsltwyfPFAVygLUCAwEAAQ==
-----END PUBLIC KEY-----";
openssl_public_encrypt("secret", $encrypted, $pbkey, OPENSSL_PKCS1_OAEP_PADDING );
echo base64_encode($encrypted);
Finally, I use the generated cipher on javascript by using decrypt function (the key is stored in localstorage btw in pkcs8 format)
function FormatPrivateKey(pemPvKey) {
return pemPvKey.replace("-----BEGIN PRIVATE KEY-----", "").replace("-----END PRIVATE KEY-----", "").replace(/[\r\n]/gm, "");
}
function GetKeys() {
const pvkey = localStorage.getItem("pvkey");
const pbkey = localStorage.getItem("pbkey");
return [pvkey, pbkey]
}
async function Decrypt(message) {
const keys = GetKeys();
let pemPvKey = keys[0];
const pvkey = await window.crypto.subtle.importKey(
"pkcs8",
str2ab(window.atob(FormatPrivateKey(pemPvKey))),
{
name: "RSA-OAEP",
hash: {name: "SHA-256"}
},
false,
["decrypt"]
);
return await window.crypto.subtle.decrypt(
{
name: "RSA-OAEP"
},
pvkey,
str2ab(window.atob(message))
);
}
When I try to decrypt the data, I receive this error: Uncaught DOMException: The operation failed for an operation-specific reason
I do not know why this happens.