How to generate PKCS #7 signature in C# equivalent to openssl smime -sign -binary -noattr -nosmimecap -outform DER

5 days ago 12
ARTICLE AD BOX

My problem: I need to digitally sign RDP files before distribution since Microsoft change in April 2026.

I have an RSA code signing certificate stored in HSM (Azure Key Vault) and hence can't use rdpsign.exe.

I found a python implementation nfedera/rdpsign, which uses openssl to create and append the digital signature. Using this along with AzureKeyVaultManagedHSMEngine I'm able to sign .rdp files.
The OpenSSL command is structured openssl smime -sign -binary -outform DER -noattr -nosmimecap -signer 'mycert.crt' -inkey 'managedhsm:<keyvault>:<keyname>'.

I'd like to remove the dependency on Python and OpenSSL in my signing flow and am looking to implement the whole solution in a single C# .NET application. Based on my reading, it seemed as though BouncyCastle was the library to use for this. But I've hit a dead end, which I'm sure is to do with my (lack of) understanding of PKCS / CMS.

Given:

RSA signed SHA 256 digest signedDigest:byte[] Public certificate `mycert.crt'

How can I produce a signature result:byte[] which matches the output of the above OpenSSL command?
Use of BouncyCastle is optional.

The following is a code excerpt which I've tried to use to generate the signature.

using Org.BouncyCastle.Asn1.Pkcs; // Picked this as it matched openssl smime option var digestOid = "2.16.840.1.101.3.4.2.1"; //SHA256 var digestAlg = new AlgorithmIdentifier(new DerObjectIdentifier(digestOid), DerNull.Instance); var digestAlgs = new DerSet(digestAlg); var path = "./path/to/mycert.crt"; var cert = new X509CertificateParser().ReadCertificate(File.ReadAllBytes(path)); var signedDigest = new DerOctetString(signedDigest); var certVec = new Asn1EncodableVector(); certVec.Add(Asn1Object.FromByteArray(cert.GetEncoded())); var certs = new BerSet(certVec); var signerInfo = new SignerInfo( DerInteger.One, new IssuerAndSerialNumber(cert.IssuerDN, cert.SerialNumber), digestAlg, null, new AlgorithmIdentifier(PkcsObjectIdentifiers.RsaEncryption, DerNull.Instance), digestSig, null ); var contentInfo = new ContentInfo(PkcsObjectIdentifiers.Data, null); var signedData = new SignedData(DerInteger.One, digestAlgs, contentInfo, certs, null, new DerSet(signerInfo)); var finalContentInfo = new ContentInfo(PkcsObjectIdentifiers.SignedData, signedData); var result = finalContentInfo.GetEncoded();

Thanks in advance!

Read Entire Article