Как сгенерировать подпись PKCS #7 на C#, эквивалентную openssl smime -sign -binary -noattr -nosmimecap -outform DERC#

Место общения программистов C#
Anonymous
Как сгенерировать подпись PKCS #7 на C#, эквивалентную openssl smime -sign -binary -noattr -nosmimecap -outform DER

Сообщение Anonymous »

Моя проблема: мне нужно подписать файлы RDP цифровой подписью перед их распространением после изменений Microsoft в апреле 2026 года.
У меня есть сертификат подписи кода RSA, хранящийся в HSM (Azure Key Vault), и поэтому я не могу использовать rdpsign.exe.
Я нашел реализацию Python nfedera/rdpsign, которая использует openssl для создания и добавления цифровой подписи. Используя это вместе с AzureKeyVaultManagedHSMEngine, я могу подписывать файлы .rdp.

Команда OpenSSL имеет структуру openssl smime -sign -binary -outform DER -noattr -nosmimecap -signer 'mycert.crt' -inkey 'managedhsm::'.
Я бы Мне хотелось бы удалить зависимость от Python и OpenSSL в моем процессе подписи, и я хочу реализовать все решение в одном приложении C# .NET. Судя по моему прочтению, мне показалось, что для этого можно использовать библиотеку BouncyCastle. Но я зашёл в тупик, что, я уверен, связано с моим (недостаточным) пониманием PKCS/CMS.
При условии:
  • RSA подписал дайджест SHA 256 rawSignedDigest:byte[]
  • Открытый сертификат `mycert.crt'
Как можно Я получаю результат подписи: байт[], который соответствует выводу указанной выше команды OpenSSL?

Использование BouncyCastle не является обязательным.
Ниже приведен отрывок кода, который я пытался использовать для создания подписи.

Код: Выделить всё

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(rawSignedDigest);
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();
Заранее спасибо!

Вернуться в «C#»