-
Notifications
You must be signed in to change notification settings - Fork 274
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
RSA OAEP encryption with label #1726
Comments
@indutny any ideas? |
WebCrypt returns correct decrypted message. NodeJs throws error
Message was encrypted in Chrome WebCrypto decryptconst privateKeyJwk = {
alg: "RSA-OAEP-256",
d: "fSHfoQe74aFcDMGNyzHkNrx2-ngPL63VSdgCxX4jlgIAQ6w7gyVTb2i48ZLv_z1fQSN8I3YWNj_TBon9WcFt87WDglTxjYLLpz9QkAMfPU1hz8zHThEU0p2FTkQZvrMh3eSg6JpsqYz2uRYtKS7v0P6HkAxqYH77RUA_ok-kdDFWRLt63hGX8tiuiXVX6VGcSe0nDhnAmbhWQPZxHmt5QRsdzpre-iewu1GS4tWt86DwGJ5I9ZHMWU1Ft_ZhnXK9sEdhBTLK-AraMRv44QJWW2FEZk1OwltH_71UXMxShVyIO2u1QpNcMPffhlw-Xc9yEeo9Ok4uMKrZ2zJxGoQumQ",
dp: "BQwwuNd1g4jgksTmk5M51nKxukVVRo5dpSbZR1xMgCB6pRqWrrzWSRaKbQgTS9QzGobp4171ioX0ecCv2MKzMlQfwzTU6nXQtgTXsgvz7wAujp8Yy7svRviyLnsE66gPYr0e_slUrLxnwJjdngmqaskn5ntwxMfNgRYuXB3K780",
dq: "2E5ip-h59PH3w5V-xQjTh3-2dkceE8wCRfglxWze2KkiRES7uggclBoLn3PGC-GpZ_u7ulddjfF5M1KRaZgVIMOAsxppyTxbzvY7_InVOSlYS7mKmMm7JYoP03NQRl1AFgtRBVcfN5NjmCiVooMaYapZbbcSBiya0quwpJaxv8E",
e: "AQAB",
ext: true,
key_ops: ["decrypt"],
kty: "RSA",
n: "-svrcrqSZaVGdDXaIRU0P2uLZwObQSsrNKT6Kdxi9aOWupmVKSnduv8eOuOByFC4gHq8t59vSqpSXSA7J2DJlvJNDToJDcohSgfX2QJZxT2RasC6GgLLSPoGnySZwHuDtw2q-KCxJ3KER2hKtv7XX_Zr81ki5qMLbJ-XzPMIikgZf_XehWCacNmFLZlylUfv0OwJOz5dmyyT1BAGsZT4AYPtvUKp7L6BWZnoLd9Dtf-qFefGDXTglugXAISZl9VgaH26pD5AbBwTM84jquBfVvY5EVyMH5qE9NCO_zAHKxFEFnqZ0CXo7jFM6Yu_nWedrMLv-MpB9VETouL_T0UjKw",
p: "_tuqNnhg1kPeAd5XqZNo3DWuJOSxe2SgDYJBIEMHlBzygZ-2GrpiNDsSdHZmifWIn8HCIIMjZhBenG7DJS-4aZRVEd4Z5O1MGMMyqlWXqHRGw_mS5ltRScHnYaquFkhj9EQwGuMZQhYviDVLH88tc32SRUsxWadN4fWiksRANzc",
q: "--uYmFNszuvlKn8Z0Li0l31C2Qv1Dve6yU9SKwfO0dCp84MX8SsfEFW-mwnaAJ4MtY9WyuC8jGf5ww5cbMpZNQemR-TDPM6ZWIVmWrjR8CAbUa2O-ANLHYDcilBgWCL33NJkq6yaq94O5swp-iTRN9nWCYmkta0GVFHUi8nyRa0",
qi: "qAUmxSdqa4S_fculRVx3sPXQwdcgwkq0s9PYob-i_zlTpDmx5LeaP1oF2smkhTDwlLdpU6omtc9iQWApJqc93ud-YReJ5ymRLDjDFc-kXx_e1RY9zgzAMrjYjUDcNOdtywx8Pjo5cYnrk1d7MbQ6bSRE2gXcoooKRQ636KAkAg4",
}
const encryptedBlob = "7FkwmlAy0aWQphok3SphAu6lsDBtWi17fR9wlLgHAd5MHYZJ/zh9C7kJuoGnSD/ZN81GSCtlmWO+Vjmqsy3Qjfuhx125R3kWuL1aKIsdMKGrGCNhYxTPOvHwVH0uZVqvpUCp/NQS1c8qEZ5VaTg1TDuQd6hAM8L6pPEdVzFNiei4re6XGVLZTGG040pNHrCqv9iQcxKaM87yUpylTfRl1N13esd+zHcouBHWG9kMxjAnNU9467V4K1q4/YoRjAVQ644+2KP2fcupTIRbcqD/WqvofOV1T/7AiGzeo4vUiU++XTBAr08MEyPTnFLgmAhzIfAwLOaoL0PvteKXfPfkFg==";
function fromBinary(text) {
const stringLength = text.length;
const resultView = new Uint8Array(stringLength);
for (let i = 0; i < stringLength; i++) {
resultView[i] = text.charCodeAt(i);
}
return resultView.buffer;
}
function fromBase64(base64Text) {
base64Text = base64Text.replace(/\n/g, "").replace(/\r/g, "").replace(/\t/g, "").replace(/\s/g, "");
if (typeof atob !== "undefined") {
return fromBinary(atob(base64Text));
} else {
return new Uint8Array(Buffer.from(base64Text, "base64")).buffer;
}
}
async function main() {
const key = await crypto.subtle.importKey("jwk", privateKeyJwk, { name: "RSA-OAEP", hash: "SHA-256" }, false, ["decrypt"]);
const data = await crypto.subtle.decrypt("RSA-OAEP", key, fromBase64(encryptedBlob));
console.log(new Uint8Array(data)); // [1, 2, 3, 4, 5, 6, 7, 8, 9, 0]
}
main()
.catch((err) => {
console.error(err);
}); NodeJS decryptconst crypto = require("crypto");
const privateKeyBlob = "MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQD6y+tyupJlpUZ0NdohFTQ/a4tnA5tBKys0pPop3GL1o5a6mZUpKd26/x4644HIULiAery3n29KqlJdIDsnYMmW8k0NOgkNyiFKB9fZAlnFPZFqwLoaAstI+gafJJnAe4O3Dar4oLEncoRHaEq2/tdf9mvzWSLmowtsn5fM8wiKSBl/9d6FYJpw2YUtmXKVR+/Q7Ak7Pl2bLJPUEAaxlPgBg+29QqnsvoFZmegt30O1/6oV58YNdOCW6BcAhJmX1WBofbqkPkBsHBMzziOq4F9W9jkRXIwfmoT00I7/MAcrEUQWepnQJejuMUzpi7+dZ52swu/4ykH1UROi4v9PRSMrAgMBAAECggEAfSHfoQe74aFcDMGNyzHkNrx2+ngPL63VSdgCxX4jlgIAQ6w7gyVTb2i48ZLv/z1fQSN8I3YWNj/TBon9WcFt87WDglTxjYLLpz9QkAMfPU1hz8zHThEU0p2FTkQZvrMh3eSg6JpsqYz2uRYtKS7v0P6HkAxqYH77RUA/ok+kdDFWRLt63hGX8tiuiXVX6VGcSe0nDhnAmbhWQPZxHmt5QRsdzpre+iewu1GS4tWt86DwGJ5I9ZHMWU1Ft/ZhnXK9sEdhBTLK+AraMRv44QJWW2FEZk1OwltH/71UXMxShVyIO2u1QpNcMPffhlw+Xc9yEeo9Ok4uMKrZ2zJxGoQumQKBgQD+26o2eGDWQ94B3lepk2jcNa4k5LF7ZKANgkEgQweUHPKBn7YaumI0OxJ0dmaJ9YifwcIggyNmEF6cbsMlL7hplFUR3hnk7UwYwzKqVZeodEbD+ZLmW1FJwedhqq4WSGP0RDAa4xlCFi+INUsfzy1zfZJFSzFZp03h9aKSxEA3NwKBgQD765iYU2zO6+UqfxnQuLSXfULZC/UO97rJT1IrB87R0KnzgxfxKx8QVb6bCdoAngy1j1bK4LyMZ/nDDlxsylk1B6ZH5MM8zplYhWZauNHwIBtRrY74A0sdgNyKUGBYIvfc0mSrrJqr3g7mzCn6JNE32dYJiaS1rQZUUdSLyfJFrQKBgAUMMLjXdYOI4JLE5pOTOdZysbpFVUaOXaUm2UdcTIAgeqUalq681kkWim0IE0vUMxqG6eNe9YqF9HnAr9jCszJUH8M01Op10LYE17IL8+8ALo6fGMu7L0b4si57BOuoD2K9Hv7JVKy8Z8CY3Z4JqmrJJ+Z7cMTHzYEWLlwdyu/NAoGBANhOYqfoefTx98OVfsUI04d/tnZHHhPMAkX4JcVs3tipIkREu7oIHJQaC59zxgvhqWf7u7pXXY3xeTNSkWmYFSDDgLMaack8W872O/yJ1TkpWEu5ipjJuyWKD9NzUEZdQBYLUQVXHzeTY5golaKDGmGqWW23EgYsmtKrsKSWsb/BAoGBAKgFJsUnamuEv33LpUVcd7D10MHXIMJKtLPT2KG/ov85U6Q5seS3mj9aBdrJpIUw8JS3aVOqJrXPYkFgKSanPd7nfmEXiecpkSw4wxXPpF8f3tUWPc4MwDK42I1A3DTnbcsMfD46OXGJ65NXezG0Om0kRNoF3KKKCkUOt+igJAIO";
const encryptedBlob = "7FkwmlAy0aWQphok3SphAu6lsDBtWi17fR9wlLgHAd5MHYZJ/zh9C7kJuoGnSD/ZN81GSCtlmWO+Vjmqsy3Qjfuhx125R3kWuL1aKIsdMKGrGCNhYxTPOvHwVH0uZVqvpUCp/NQS1c8qEZ5VaTg1TDuQd6hAM8L6pPEdVzFNiei4re6XGVLZTGG040pNHrCqv9iQcxKaM87yUpylTfRl1N13esd+zHcouBHWG9kMxjAnNU9467V4K1q4/YoRjAVQ644+2KP2fcupTIRbcqD/WqvofOV1T/7AiGzeo4vUiU++XTBAr08MEyPTnFLgmAhzIfAwLOaoL0PvteKXfPfkFg==";
const encrypted = Buffer.from(encryptedBlob, "base64");
const msg = crypto.privateDecrypt(
{
key: `-----BEGIN PRIVATE KEY-----\n${privateKeyBlob}\n-----END PRIVATE KEY-----`,
padding: crypto.constants.RSA_PKCS1_OAEP_PADDING,
},
encrypted,
);
console.log(msg); |
cc @nodejs/crypto looks like a missing feature. |
@indutny any chance to fix it? |
@microshine Its a reasonable feature, I can't think why we wouldn't accept a PR. If you don't want to work on it, you'll have to wait until someone picks this up. |
@sam-github I'll check if I can do PR. Which branch should I use for PR? I did one more test and found that NodeJS uses SHA-1 for RSA-OAEP encryption without Here is WebCrypto example which allows to decrypt encrypted message from NodeJS const key = await crypto.subtle.importKey("jwk", privateKeyJwk, { name: "RSA-OAEP", hash: "SHA-1" }, false, ["decrypt"]);
const data = await crypto.subtle.decrypt("RSA-OAEP", key, fromBase64(encryptedBlob)); |
@microshine There are instructions for creating PRs in the main repository. Usually, you should create a PR against the In your WebCrypto example, do you supply the label during decryption? |
@tniessen thank you I don't supply the label const data = await crypto.subtle.decrypt("RSA-OAEP", key, fromBase64(encryptedBlob));
// ^^^^^^^^^^ with label it will look like const data = await crypto.subtle.decrypt({name: "RSA-OAEP", label: new Uint8Arrau([1, 2, 3, 4, 5])}, key, fromBase64(encryptedBlob)); |
@microshine That's what I thought. So the difference in this case is that node throws without the tag while WebCrypto silently ignores it, is that right? |
This has been implemented in Node.js and is available in recent releases. |
@microshine thanks for this insight, I've been fighting with the similar problem for a week! |
The options object for
that can be specified among the |
Is it possible to set label for RSA OAEP mechanism like WebCrypto does?
Chromium uses
EVP_PKEY_CTX_set0_rsa_oaep_label
function (source). But I can't find this function in NodeJS sourceThe text was updated successfully, but these errors were encountered: