C# BouncyCastle CmsEnvelope key encryption algorithm RSA-OAEP (SHA256, MGF1SHA256)

1.1k views Asked by At

I'm using BouncyCastle (BC) API for C#.

After Hours going through this API hell i figured out how to sign/verify and encrypt/decrypt using CMS with BC. I have to encrypt the symmetric key for the CMSEnvelope with RSA-OAEP (SHA256 + MGF1 with SHA256) as key encryption algorithm. On default BC obviously uses RSA.

In RecipientInfo structure of the CMS envelope I have to use KeyTransRecipientInfo.

I can't figure out how to set the RSA-OAEP-algorithm to the recipientInfo:

    //Create Encrypted cms envelope
      X509Certificate otherscert = new X509CertificateParser().ReadCertificate(myCertBytes)
      CmsEnvelopedDataGenerator envDataGen = new CmsEnvelopedDataGenerator();
      envDataGen.AddKeyTransRecipient(othersCert); //setting Cert, but how the key encr. algorithm?
      CmsProcessableByteArray sData = new CmsProcessableByteArray(signedData.GetEncoded());
      var envData =  envDataGen.Generate(sData, CmsEnvelopedDataGenerator.Aes256Cbc); //generate the envelope

Now in the recipientInfo KeyEncryptionAlgOid is 1.2.840.113549.1.1.1 (RSA)

I need it to be 1.2.840.113549.1.1.7 (RSA-OAEP) with the mentioned key encryption parameters.

Any idea how to do that in BC's C#-API?


EDIT:

Now I got the Source from Git and did the following edits. The problem was not just setting the keyEncryptionAlgorithm to the recipient. BC's logic takes the certificates SubjectPublicKeyInfo-algorithm for key encryption.

in CMSEnvelopedGenerator.cs I added

public void AddKeyTransRecipientRsaOaep(
            X509Certificate cert, DerObjectIdentifier digest, DerObjectIdentifier mgf1digest, AlgorithmIdentifier pSource = null)
        {
            if (pSource == null)
            {
                pSource = new AlgorithmIdentifier(PkcsObjectIdentifiers.IdPSpecified, new DerOctetString(new byte[0]));
            }
            AlgorithmIdentifier hash = new AlgorithmIdentifier(digest, DerNull.Instance);
            AlgorithmIdentifier mask = new AlgorithmIdentifier(PkcsObjectIdentifiers.IdMgf1, mgf1digest);
            var rsaOaepParams = new RsaesOaepParameters(hash, mask, pSource);

            KeyTransRecipientInfoGenerator ktrig = new KeyTransRecipientInfoGenerator();
            ktrig.RecipientCert = cert;
            ktrig.AlgorithmId = new AlgorithmIdentifier(PkcsObjectIdentifiers.IdRsaesOaep, rsaOaepParams);

            recipientInfoGenerators.Add(ktrig);
        }

In KeyTransrecipientInfoGenerator.cs I added

private AlgorithmIdentifier keyEncryptionAlg;
    ...
 internal AlgorithmIdentifier AlgorithmId
        {
            set
            {
                keyEncryptionAlg = value;
            }
        }

...
protected virtual AlgorithmIdentifier AlgorithmDetails
        {
            get
            {
                if (keyEncryptionAlg == null)
                {
                    return info.AlgorithmID;
                }
                else
                {
                    return keyEncryptionAlg;
                }
            }
        }
//In the Generate() method I changed 
  keyEncryptionAlgorithm = AlgorithmDetails;
//to
  AlgorithmIdentifier keyEncryptionAlgorithm;
  if (this.keyEncryptionAlg != null)
  {
    keyEncryptionAlgorithm = this.keyEncryptionAlg;
  }
  else
  {
    keyEncryptionAlgorithm = AlgorithmDetails;
  }

Now the keyEncryption algorithm and parameters are set correctly and it encrypts without exception:

CmsEnvelopedDataGenerator envDataGen = new CmsEnvelopedDataGenerator();
envDataGen.AddKeyTransRecipientRsaOaep(othersCert, NistObjectIdentifiers.IdSha256, NistObjectIdentifiers.IdSha256);
CmsProcessableByteArray sData = new CmsProcessableByteArray(signedData.GetEncoded());
            var envData =  envDataGen.Generate(sData, CmsEnvelopedDataGenerator.Aes256Cbc);

Reading the Envelope with BC or NetCore3 works fine. The RecipientInfos are set as intended (keyEncryptionAlgorithm, params).

But Decryption fails on both... :(

0

There are 0 answers