Skip to content

crypto.privateDecrypt keeps failing after "Passphrase required" error #32240

Closed
@nahuel

Description

@nahuel
  • Version: v13.10.1
  • Platform: Ubuntu 18.04
  • Subsystem: crypto

If you call crypto.privateDecrypt(...) with an passphrase-encrypted private RSA key PEM but without providing a passphrase, it correctly raises TypeError: Passphrase required for encrypted key. But after that, if you try to call it again with an unencrypted private RSA key PEM, then the same error is raised. It seems like the first call corrupts some internal state (maybe openssl one) breaking subsequent calls. Example follows:

// 1- Generate RSA key pair
const crypto = require('crypto')
const pair = crypto.generateKeyPairSync('rsa', { modulusLength : 1024 })

// 2- Create a PEM uncrypted and the same one but encrypted with a passphrase
const privPEM        = pair.privateKey.export({ type : 'pkcs1', format : 'pem'})
const privPEMcrypted = pair.privateKey.export({ type : 'pkcs1', format : 'pem', 
                                                cipher : 'aes128', passphrase : 'mysecret'})

// 3- Encrypt some data with public Key, works OK.
const dataEncrypted = crypto.publicEncrypt(pair.publicKey, Buffer.from("raw data"))

// 4- Try to decrypt it using the uncrypted Priv PEM (FIRST TIME)
const decrypt = (pem) => crypto.privateDecrypt(pem, dataEncrypted).toString()

// As expected, this works ok:
console.log('decrypt privPEM 1:', decrypt(privPEM)) 

// 5- Now try to decrypt it using the crypted Priv PEM but WITHOUT specifing a
// passphrase. This will expectedly fail raising an exception:
try { 
    decrypt(privPEMcrypted)
    // => TypeError: Passphrase required for encrypted key
} catch(e) {
    console.log('Ok, I expected this error:', e)
}

// 6- Now repeat the SAME step 4, this will FAIL with the same 'Passphrase
// required for encrypted key' error from step 5, but this PEM is uncrypted, so
// we found a bug.
console.log("\n\nNow this must not fail... but it does:")

console.log('decrypt privPEM 2:', decrypt(privPEM))
// => TypeError: Passphrase required for encrypted key

Output:

$ node test-crypto-bug.js 
decrypt privPEM 1: raw data
Ok, I expected this error: TypeError: Passphrase required for encrypted key
    at Object.privateDecrypt (internal/crypto/cipher.js:63:12)
    at decrypt (/tmp/test-crypto-bug.js:14:33)
    at Object.<anonymous> (/tmp/test-crypto-bug.js:22:5)
    at Module._compile (internal/modules/cjs/loader.js:1147:30)
    at Object.Module._extensions..js (internal/modules/cjs/loader.js:1167:10)
    at Module.load (internal/modules/cjs/loader.js:996:32)
    at Function.Module._load (internal/modules/cjs/loader.js:896:14)
    at Function.executeUserEntryPoint [as runMain] (internal/modules/run_main.js:71:12)
    at internal/main/run_main_module.js:17:47 {
  code: 'ERR_MISSING_PASSPHRASE'
}


Now this must not fail... but it does:
internal/crypto/cipher.js:63
    return method(data, format, type, passphrase, buffer, padding, oaepHash,
           ^

TypeError: Passphrase required for encrypted key
    at Object.privateDecrypt (internal/crypto/cipher.js:63:12)
    at decrypt (/tmp/test-crypto-bug.js:14:33)
    at Object.<anonymous> (/tmp/test-crypto-bug.js:33:35)
    at Module._compile (internal/modules/cjs/loader.js:1147:30)
    at Object.Module._extensions..js (internal/modules/cjs/loader.js:1167:10)
    at Module.load (internal/modules/cjs/loader.js:996:32)
    at Function.Module._load (internal/modules/cjs/loader.js:896:14)
    at Function.executeUserEntryPoint [as runMain] (internal/modules/run_main.js:71:12)
    at internal/main/run_main_module.js:17:47 {
  code: 'ERR_MISSING_PASSPHRASE'
}
/tmp$ 

Metadata

Metadata

Assignees

No one assigned

    Labels

    confirmed-bugIssues with confirmed bugs.cryptoIssues and PRs related to the crypto subsystem.

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions