Repository navigation
Exception when using privateEncrypt/privateDecrypt with certain encrypted keys #40814
Description
Activity
- addedcryptoIssues and PRs related to the crypto subsystem.Issues and PRs related to the crypto subsystem.
on Nov 15, 2021 - changed the title
[-]Exception when using `privateEncrypt/privateDecrypt` on certain key types[/-][+]Exception when using `privateEncrypt`/`privateDecrypt` with certain encrypted keys[/+]on Nov 16, 2021 Thank you for the report. This is an interesting one. I've been debugging this for a while now and something seems very wrong here.
Most spectacularly, in Node.js 17 (both on Windows and Ubuntu), the first attempt to load an
aes-128-ecbencrypted key appears to fail, but the second succeeds:==256055== Memcheck, a memory error detector ==256055== Copyright (C) 2002-2017, and GNU GPL'd, by Julian Seward et al. ==256055== Using Valgrind-3.15.0 and LibVEX; rerun with -h for copyright info ==256055== Command: node ==256055== Welcome to Node.js v17.1.0. Type ".help" for more information. > let {privateKey, publicKey} = crypto.generateKeyPairSync("rsa", { ... modulusLength: 2048, ... publicKeyEncoding: { ..... type: "spki", ..... format: "pem" ..... }, ... privateKeyEncoding: { ..... type: 'pkcs8', ..... format: 'pem', ..... cipher: "aes-128-ecb", ..... passphrase: "abcdef" ..... } ... }); undefined > crypto.createPrivateKey({ key: privateKey, passphrase: 'abcdef' }) Uncaught Error: error:0300007A:digital envelope routines::cipher parameter error at Object.createPrivateKey (node:internal/crypto/keys:608:12) { library: 'digital envelope routines', reason: 'cipher parameter error', code: 'ERR_OSSL_EVP_CIPHER_PARAMETER_ERROR' } > crypto.createPrivateKey({ key: privateKey, passphrase: 'abcdef' }) PrivateKeyObject { [Symbol(kKeyType)]: 'private' } > (To exit, press Ctrl+C again or Ctrl+D or type .exit) > ==256055== ==256055== HEAP SUMMARY: ==256055== in use at exit: 1,011,381 bytes in 2,199 blocks ==256055== total heap usage: 84,213 allocs, 82,014 frees, 51,234,514 bytes allocated ==256055== ==256055== LEAK SUMMARY: ==256055== definitely lost: 0 bytes in 0 blocks ==256055== indirectly lost: 0 bytes in 0 blocks ==256055== possibly lost: 416 bytes in 3 blocks ==256055== still reachable: 1,010,965 bytes in 2,196 blocks ==256055== of which reachable via heuristic: ==256055== stdstring : 7,429 bytes in 161 blocks ==256055== suppressed: 0 bytes in 0 blocks ==256055== Rerun with --leak-check=full to see details of leaked memory ==256055== ==256055== For lists of detected and suppressed errors, rerun with: -s ==256055== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0)- addedconfirmed-bugIssues and PRs for confirmed bugs.Issues and PRs for confirmed bugs.
on Nov 16, 2021 I'm seeing something similar on node 16.3.1 on Ubuntu 20.04, but with a sightly different error:
Error: error:0D0C5006:asn1 encoding routines:ASN1_item_verify:EVP lib
at Object.createPrivateKey (node:internal/crypto/keys:608:12)
at readPrivateKeyBuffer (/opt/ct/node_modules/@configuredthings/sfjs-language/lib/parser/sfjsCrypto.js:51:22)
at readPrivateKeyFile (/opt/ct/node_modules/@configuredthings/sfjs-language/lib/parser/sfjsCrypto.js:43:12)
at decryptDoc (/opt/ct/node_modules/@configuredthings/sfjs-language/lib/parser/sfjsCrypto.js:748:55)
at ConfigGateway. (/opt/ct/node_modules/@configuredthings/sfjs-components/lib/ConfigGateway/ConfigGateway.js:132:66)
at ConfigGateway. (/opt/ct/node_modules/@configuredthings/sfjs-components/lib/ConfigGateway/ConfigGateway.js:59:103)
at FileMonitor. (/opt/ct/node_modules/@configuredthings/sfjs-components/lib/Abstract/FileMonitor.js:185:17)
at FileMonitor. (/opt/ct/node_modules/@configuredthings/sfjs-components/lib/Abstract/FileMonitor.js:166:18)
at FSWatcher.emit (node:events:390:28)
at FSWatcher.emitWithAll (/opt/ct/node_modules/chokidar/index.js:540:8) {
opensslErrorStack: [ 'error:0D0C5006:asn1 encoding routines:ASN1_item_verify:EVP lib' ],
library: 'asn1 encoding routines',
function: 'ASN1_item_verify',
reason: 'EVP lib',
code: 'ERR_OSSL_ASN1_EVP_LIB'
}It doesn't seem to be a first or second call that always fails, I'm getting this both after a successful call and when this is the fist call.
What I have seen is that catching the exception and retrying the call always seems to work.try { res = crypto.createPrivateKey(key); } catch(err) { console.log("*** FAILED") console.error(err) try { res = crypto.createPrivateKey(key); } catch(err) { console.log("*** FAILED Again") console.error(err) throw err; } } return res; }Reacted by Simon Arnell- added a commit that references this issue
on Oct 29, 2022 - added a commit that references this issue
on Nov 1, 2022 Alright, fix seemingly works, but for only ECB ciphers, other ciphers like -ccm -ctr -ocb -xts variants and other cipher types are still broken with more or less the same error... or a variant of it
I used the following snippet to test all ciphers given bycrypto.getCiphers()const crypto = require("crypto"); crypto.getCiphers().forEach((cipherString) => { console.log(`Testing: ${cipherString}`); if(cipherString == "des3-wrap" || cipherString == "aes128-wrap" || cipherString == "aes192-wrap" || cipherString == "aes256-wrap" || cipherString == "id-aes128-wrap" || cipherString == "id-aes128-wrap-pad" || cipherString == "id-aes192-wrap" || cipherString == "id-aes192-wrap-pad" || cipherString == "id-aes256-wrap" || cipherString == "id-aes256-wrap-pad") { console.log(`\x1b[33m[SKIPPED] ${cipherString} due to segmentation fault`); console.log("\x1b[37m"); // turn text back to white return; } try { let { privateKey, publicKey } = crypto.generateKeyPairSync("rsa", { modulusLength: 2048, publicKeyEncoding: { type: "spki", format: "pem" }, privateKeyEncoding: { type: 'pkcs8', format: 'pem', cipher: cipherString, passphrase: "abcdef" } }); const encryptedString = crypto.privateEncrypt({ key: privateKey, passphrase: "abcdef" }, Buffer.from("The quick brown fox jumps over the lazy dog")).toString("base64"); const decryptedString = crypto.publicDecrypt(publicKey, Buffer.from(encryptedString, "base64")).toString(); console.log(`\x1b[32m[PASS]`); console.log(`Encrypted: ${encryptedString}`); console.log(`Decrypted: ${decryptedString}`); } catch(err) { console.log(`\x1b[31m[FAILED] ${err.stack}`); } console.log("\x1b[37m"); // turn text back to white });
Broken ciphers:
aes-128-ccm - error:0300006B:digital envelope routines::unsupported cipher aes-128-ctr - error:0680006C:asn1 encoding routines::cipher has no object identifier aes-128-gcm - error:0300007A:digital envelope routines::cipher parameter error aes-128-ocb - error:0680006C:asn1 encoding routines::cipher has no object identifier aes-128-xts - error:0300006B:digital envelope routines::unsupported cipher aes-192-ccm - error:0300006B:digital envelope routines::unsupported cipher aes-192-ctr - error:0680006C:asn1 encoding routines::cipher has no object identifier aes-192-gcm - error:0300007A:digital envelope routines::cipher parameter error aes-192-ocb - error:0680006C:asn1 encoding routines::cipher has no object identifier aes-256-ccm - error:0300006B:digital envelope routines::unsupported cipher aes-256-ctr - error:0680006C:asn1 encoding routines::cipher has no object identifier aes-256-gcm - error:0300007A:digital envelope routines::cipher parameter error aes-256-ocb - error:0680006C:asn1 encoding routines::cipher has no object identifier aes-256-xts - error:0300006B:digital envelope routines::unsupported cipher aria-128-ccm - error:0300006B:digital envelope routines::unsupported cipher aria-128-cfb1 - error:0680006C:asn1 encoding routines::cipher has no object identifier aria-128-cfb8 - error:0680006C:asn1 encoding routines::cipher has no object identifier aria-128-gcm - error:0300007A:digital envelope routines::cipher parameter error aria-192-ccm - error:0300006B:digital envelope routines::unsupported cipher aria-192-cfb1 - error:0680006C:asn1 encoding routines::cipher has no object identifier aria-192-cfb8 - error:0680006C:asn1 encoding routines::cipher has no object identifier aria-192-gcm - error:0300007A:digital envelope routines::cipher parameter error aria-256-ccm - error:0300006B:digital envelope routines::unsupported cipher aria-256-cfb1 - error:0680006C:asn1 encoding routines::cipher has no object identifier aria-256-cfb8 - error:0680006C:asn1 encoding routines::cipher has no object identifier aria-256-gcm - error:0300007A:digital envelope routines::cipher parameter error camellia-128-cfb1 - error:0680006C:asn1 encoding routines::cipher has no object identifier camellia-128-cfb8 - error:0680006C:asn1 encoding routines::cipher has no object identifier camellia-192-cfb1 - error:0680006C:asn1 encoding routines::cipher has no object identifier camellia-192-cfb8 - error:0680006C:asn1 encoding routines::cipher has no object identifier camellia-256-cfb1 - error:0680006C:asn1 encoding routines::cipher has no object identifier camellia-256-cfb8 - error:0680006C:asn1 encoding routines::cipher has no object identifier chacha20 - error:0680006C:asn1 encoding routines::cipher has no object identifier chacha20-poly1305 - error:0680006C:asn1 encoding routines::cipher has no object identifier des-ede-cbc - error:0680006C:asn1 encoding routines::cipher has no object identifier des-ede-cfb - error:0680006C:asn1 encoding routines::cipher has no object identifier des-ede-ofb - error:0680006C:asn1 encoding routines::cipher has no object identifier des-ede3 - error:0680006C:asn1 encoding routines::cipher has no object identifier des-ede3-cfb - error:0308010C:digital envelope routines::unsupported des-ede3-cfb1 - error:0308010C:digital envelope routines::unsupported des-ede3-cfb8 - error:0308010C:digital envelope routines::unsupported des-ede3-ecb - error:0680006C:asn1 encoding routines::cipher has no object identifier des-ede3-ofb - error:0680006C:asn1 encoding routines::cipher has no object identifier id-aes128-CCM - error:0300006B:digital envelope routines::unsupported cipher id-aes128-GCM - error:0300007A:digital envelope routines::cipher parameter error id-aes192-CCM - error:0300006B:digital envelope routines::unsupported cipher id-aes192-GCM - error:0300007A:digital envelope routines::cipher parameter error id-aes256-CCM - error:0300006B:digital envelope routines::unsupported cipher id-aes256-GCM - error:0300007A:digital envelope routines::cipher parameter error id-smime-alg-CMS3DESwrap - error:1C800066:Provider routines::cipher operation failedAdditionally, the following ciphers throw an Segmentation fault:
aes128-wrap aes192-wrap aes256-wrap id-aes128-wrap id-aes128-wrap-pad id-aes192-wrap id-aes192-wrap-pad id-aes256-wrap id-aes256-wrap-padWith the exception of
des3-wrapwho fails witherror:1C800066:Provider routines::cipher operation failedbefore throwing the following as I try a few more times to encrypt:corrupted size vs. prev_size Aborted (core dumped)Versions i tried:
- v20.0.0-nightly2022110286088ab78e
- v20.0.0-nightly20221101590cf569fe
I'm not really sure if these would apply for an separate issue, or it should be an continuation of this issue... or even if it should be valid, in my opinion it is since I would expect this to work with all ciphers at
crypto.getCiphers()at least.@PANCHO7532B you should probably open a new issue, or a directly a PR if you know what is the fix.
- added a commit that references this issue
on Nov 10, 2022
Version
v16.13.0
Platform
Linux EURO01 5.4.0-88-generic #99-Ubuntu SMP Thu Sep 23 17:29:00 UTC 2021 x86_64 x86_64 x86_64 GNU/Linux
Subsystem
crypto
What steps will reproduce the bug?
aes-128-ecboraes-128-ocbCode:
How often does it reproduce? Is there a required condition?
This only happens with some ciphers, some like
aes-128-ccmoraes-128-cbcand other variants works just fine, other ciphers fail with an errorWhat is the expected behavior?
An successful encryption/decryption with the specified ciphers
What do you see instead?
Additional information
In v14.17.3 (the version i had previously) Node.JS would crash with a core dump on some ciphers (like GCM based ciphers)