Closed gnarea closed 2 years ago
I've just managed to replicate this issue with this EnvelopedData
value generated with the certificate above, using the latest openssl
as follows:
echo -n "hello" | openssl cms -encrypt -aes-128-cbc -in - -outform PEM /tmp/recipient-cert.pem
Since I get the error above regardless of whether the EnvelopedData
is produced with openssl
or Bouncy Castle, I think that confirms it's a bug in PKI.js.
(BTW, I had to patch PKI.js locally to work around #335 so that I could test this)
I've done some further debugging on this and I've managed to narrow down the issue to the KDF, or the input that EnvelopedData.decrypt()
passes to it:
As suggested by the error above, the problem occurs when decrypting/unwrapping the AES key in an EnvelopedData
generated with Bouncy Castle or OpenSSL:
@peculiar/webcrypto
: We get the error above.node-webcrypto-ossl
: The unwrapKey()
method "works" but it returns an array buffer where each byte is a 00
. This causes the payload decryption to fail with Error: 140102613321280:error:06065064:digital envelope routines:EVP_DecryptFinal_ex:bad decrypt:../deps/openssl/openssl/crypto/evp/evp_enc.c:610:
. I've also triple-checked that BouncyCastle and OpenSSL can decrypt each other's EnvelopedData
values, and they can. So I don't think this is a problem with Bouncy Castle or OpenSSL.
I'm going to try to spend more time on this later this week but if anyone can give me a hand with this I'd really appreciate it.
I finally found the problem! 🎉
Bouncy Castle and OpenSSL are compliant with RFC 5753, so they leave algorithmParams
absent when encrypting with AES.
The reason why Bouncy Castle and OpenSSL can decrypt EnvelopedData
values produced by PKI.js is because they have fallbacks for non-compliant implementations using NULL
. Here's what BC does, for example:
Would you be open to a PR that implemented an RFC5753-compliant fallback?
Yes, we could match bouncy/OpenSSL in the PR
Whilst testing the interoperability of #333, I discovered that PKI.js fails to decrypt
EnvelopedData
values generated by other tools (e.g., BouncyCastle) when using ECDH keys. The other tools, however, can decrypt values produced by PKI.js.For example, if I try to decrypt this
EnvelopedData
with this private key and this certificate, all produced with Bouncy Castle, I'd get the following error:The only reference to this error I could find was from @microshine in an unrelated issue, which I think could mean that there's either an integrity issue caused by the BouncyCastle code or there's indeed a bug in PKI.js -- assuming the errors have the same root cause. (I'm using Node.js 12.18 and
@peculiar/webcrypto
1.1.7.)However, OpenSSL has no issue decrypting the
EnvelopedData
value above (the expected plaintext ishello
):Repro script
You can reproduce the issue above with this Jest test: