PeculiarVentures / PKI.js

PKI.js is a pure JavaScript library implementing the formats that are used in PKI applications (signing, encryption, certificate requests, OCSP and TSP requests/responses). It is built on WebCrypto (Web Cryptography API) and requires no plug-ins.
http://pkijs.org
Other
1.3k stars 204 forks source link

Cannot decrypt CMS #246

Open microshine opened 5 years ago

microshine commented 5 years ago

I've got EnvelopedData with RSA encryption algorithm. I've got an exception on decryption

Exception

Error: Object's schema was not verified against input data for RSAESOAEPParams
      at RSAESOAEPParams.fromSchema (packages/protocol/node_modules/pkijs/src/RSAESOAEPParams.js:169:10)
      at new fromSchema (packages/protocol/node_modules/pkijs/src/RSAESOAEPParams.js:38:9)
      at SubKeyTransRecipientInfo.currentSequence.then (packages/protocol/node_modules/pkijs/src/EnvelopedData.js:1429:27)

CMS ASN.1 structure

image

As you can see parameters for RSA encryption algorithm are null. Should it use the default hash algorithm in this case?

This is correct CMS, I can decrypt it using C# EnvelopedCms

PKIjs source code

https://github.com/PeculiarVentures/PKI.js/blob/master/src/EnvelopedData.js#L1428

microshine commented 5 years ago

You can find a similar CMS here

ASN1 structure

image

microshine commented 5 years ago

RFC3560

RSAES-OAEP-params  ::=  SEQUENCE  {
     hashFunc    [0] AlgorithmIdentifier DEFAULT sha1Identifier,
     maskGenFunc [1] AlgorithmIdentifier DEFAULT mgf1SHA1Identifier,
     pSourceFunc [2] AlgorithmIdentifier DEFAULT
                         pSpecifiedEmptyIdentifier  }

https://tools.ietf.org/html/rfc3560#section-3

microshine commented 5 years ago

I found a way to do decrypt a message using NodeJs Crypto API rsaEncryption(1.2.840.113549.1.1.1) means RSA_PKCS1_PADDING, not RSA-OAEP

const crypto = require("crypto");

const encRaw = Buffer.from("76e5ea6e1df52471454f790923f60e2baa7adf5017fe0a36c0af3e32f6390d570e1d592375ba6035fdf4ffa70764b797ab54d0ab1efe89cf31d7fc98240a4d08c2476b7eb4c2d92355b8bf60e3897c3fcbfe09f20c7b159d9a9c4a6b2ce5021dd313e492afa762c24930f97f03a429f7b2b1e1d6088651d60e323835807c6fefe7952f74e5da29e8e327ea46e69a0a6684272f022bf18ec602ffcd10a62666b35a51ec7c7d101096f663ddfa0924a86bdbcde0433b4f71dc42bfd9facf329558026f8667f1a71c3365e09843a12339d8aaf31987b0d800e53fd0835e990096cb145e278153faf1188cd5713c6fcd289cb77d80515e1d200139b8ccac4d3bcebc", "hex");
const dec = crypto.privateDecrypt({
  key: SCEP_CLIENT_PRIVATE_KEY_PEM,
  padding: 1, // RSA_PKCS1_PADDING
}, encRaw);
YuryStrozhevsky commented 5 years ago

So, in fact what you have is an very-very old encryption scheme using RSAES-PKCS1-v1_5 encryption algorithm (it is not connected with RSA-OAEP and OAEP parameters at all). And I should say the RSAES-PKCS1-v1_5 is not supported in WebCrypto (and thus in PKI.js). But thanks, I will append an additional check for this case in order to provide a correct alert.

microshine commented 5 years ago

I'm going to add RSAES-PKCS1-v1_5 algorithm to PeculiarVentures WebCrypto libraries. Looks like this mechanism is still used

taylorcenters commented 3 years ago

Hi, has this support been added? The apple mail client and Thunderbird sends S/MIME messages with PKCS1_PADDING and I need support for that algorithm.

rmhrisk commented 3 years ago

@taylorcenters peculiar/webcrypto supports this algorithm; try setEngine