0 votes

I was not able to get this to work with .net core 2.2

I updated my code from

X509Certificate2 signerCert =
    new X509Certificate2(signingCert, fromAddress);
var aes128id = new Oid(CommonOids.Aes128);


EncryptionConfiguration configuration = new EncryptionConfiguration()
{
    Algorithm = aes128id,
    RecipientIdentifierType = SubjectIdentifierType.SubjectKeyIdentifier
};

To

X509Certificate2 signerCert =
    new X509Certificate2(signingCert, fromAddress);
var aes256Oid = new Oid(CommonOids.Aes256);
_logger.LogDebug("Using AES-256 OID: {OidValue} - {OidName}", 
    aes256Oid.Value, aes256Oid.FriendlyName);

EncryptionConfiguration configuration = new EncryptionConfiguration()
{
    Algorithm = aes256Oid,
    RecipientIdentifierType = SubjectIdentifierType.SubjectKeyIdentifier
};
_logger.LogDebug("RecipientIdentifierTypeo: {RecipientType}",
    configuration.RecipientIdentifierType);

I verified that the subjectkeyIdentifier is set, and I am getting:

Encryption Algorithm OID: 
    2.16.840.1.101.3.4.1.42(AES-256/CBC)
Key Encryption Algorithm OID: 
    1.2.840.113549.1.1.1(RSAES-PKCS1-v1_5)

Is there something I am missing or do I need to get a newer version
I'm using Mail.dll version 3.0.19134.1431 on .NET Standard 2.0

related to an answer for: Using RSA encryption
by (210 points)

1 Answer

0 votes

On .net framework (e.g. 4.5, 4.8) you'll get RSAES_OAEP, on .net 6-10 you'll get RSA.

This is because on .net framework CmsEnvelope is implemented using Windows Security Api and on .net core it's not.

My understanding is that it's not possible on .net core.

There is a way to do that using BouncyCastle.Cryptography package:

public class SMIMEBouncyCastleEncryptor : ISMIMEEncryptor
{
    public byte[] Encrypt(
        byte[] plain, 
        EncryptionConfiguration configuration)
    {
        AlgorithmIdentifier oaepAlgId =
            new AlgorithmIdentifier(
                PkcsObjectIdentifiers.IdRsaesOaep,
                new RsaesOaepParameters(
                    new AlgorithmIdentifier(
                        OiwObjectIdentifiers.IdSha1),//digest
                    new AlgorithmIdentifier(
                        PkcsObjectIdentifiers.IdMgf1, 
                        new AlgorithmIdentifier(
                            OiwObjectIdentifiers.IdSha1)),//mgf
                    new AlgorithmIdentifier(
                        PkcsObjectIdentifiers.IdPSpecified, 
                        DerNull.Instance) // PSpecified
                )
            );
        CmsEnvelopedDataGenerator generator = 
            new CmsEnvelopedDataGenerator();

        foreach (X509Certificate2 certificate2 in 
            configuration.Certificates)
        {
            X509Certificate cert = 
                DotNetUtilities.FromX509Certificate(
                    certificate2
            );

            IKeyWrapper keyWrapper = new Asn1KeyWrapper(
                    oaepAlgId, 
                    cert.GetPublicKey()
            );

            generator.AddRecipientInfoGenerator(
                new KeyTransRecipientInfoGenerator(
                    cert, 
                    keyWrapper)
            );
        }
        return generator.Generate(
            new CmsProcessableByteArray(plain), 
            CmsEnvelopedGenerator.Aes256Cbc).GetEncoded();
    }
}

You can then plug-in custom Encrypt using CryptoContext:

CryptoContext.SMIMEEncryptor = 
    new SMIMEBouncyCastleEncryptor();

X509Certificate2 cert = ...;

MailBuilder builder = new MailBuilder();
builder.Text = "test";
builder.EncryptWith(cert);
byte[] eml = builder.Create().Render();

// parse
IMail encrypted = new MailBuilder
{
    SMIMEConfiguration =
    {
        DecryptAutomatically = false
    }
}.CreateFromEml(eml);


// Key exchange algorithm used for particular recipient:
EnvelopedCms cms = encrypted.GetEnvelopedCms();
Oid oid = cms.RecipientInfos[0].KeyEncryptionAlgorithm.Oid;

Assert.AreEqual("1.2.840.113549.1.1.7", oid.Value);
Assert.AreEqual("RSAES_OAEP", oid.FriendlyName);

// Encryption algorithm used:
Assert.AreEqual("aes256", 
    cms.ContentEncryptionAlgorithm.Oid.FriendlyName);

Assert.AreEqual("test", 
    encrypted.Decrypt(cert).Text);
by (304k points)
...