Создание подписи PKCS#1 v2.1 с помощью C#C#

Место общения программистов C#
Ответить
Anonymous
 Создание подписи PKCS#1 v2.1 с помощью C#

Сообщение Anonymous »

Я пытаюсь перенести эталонную реализацию, которая подписывает вызов с помощью сертификата PKCS#12, с Java на C#. Насколько я понимаю из ссылки, подпись должна быть подписью PKCS#1 v2.1 (комментариев мало, другой документации нет). Реализация Java использует Bouncy Castle, который был бы для меня вариантом, хотя, если бы я смог решить эту проблему с помощью системных библиотек, это было бы еще лучше.
Несмотря на то, что я пробовал много вещей, мне не удалось это сделать. создать подпись, которая будет принята целевым API.
Справочный код Java:

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

private byte[] signChallenge(final byte[] challenge) {
X509Certificate sigCert = ...;
PrivateKey sigKey = ...;

ContentSigner signer = new JcaContentSignerBuilder("SHA256withRSAandMGF1").setProvider("BC").build(sigKey);
CMSTypedData cmsData = new CMSProcessableByteArray(challenge);

CMSSignedDataGenerator cmsGenerator = new CMSSignedDataGenerator();
cmsGenerator.addSignerInfoGenerator(
new JcaSignerInfoGeneratorBuilder(
new JcaDigestCalculatorProviderBuilder().build()
).build(signer, sigCert)
);
Store certs = new JcaCertStore(Collections.singletonList(sigCert));
cmsGenerator.addCertificates(certs);

CMSSignedData cms = cmsGenerator.generate(cmsData, false);
byte[] signedMessage = cms.getEncoded();
return signedMessage;
}
Первая попытка переноса с помощью Bouncy Castle:

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

private byte[] SignChallenge(byte[] challenge)
{
var sigCert = DotNetUtilities.FromX509Certificate(Cert);
var sigKey = DotNetUtilities.GetRsaKeyPair(Cert.GetRSAPrivateKey()).Private;

var signer = SignerUtilities.InitSigner("SHA256withRSAandMGF1", true, sigKey, new());
var cmsData = new CmsProcessableByteArray(challenge);

var cmsGenerator = new CmsSignedDataGenerator();
var factory = new Asn1SignatureFactory("SHA256withRSAandMGF1", sigKey);
cmsGenerator.AddSignerInfoGenerator(new SignerInfoGeneratorBuilder().Build(factory, sigCert));
cmsGenerator.AddCertificate(sigCert);

var cms = cmsGenerator.Generate(cmsData, false);
var signedMessage = cms.GetEncoded();
return signedMessage;
}
Как видите, это в основном копия 1:1, за исключением двух строк, в которых используются классы Jca, специфичные для Java. В результате получается подпись, в которой первые ~30 байт совпадают, но после этого она больше не совпадает и имеет другую общую длину с одним и тем же вводом (2324 байта в Java против 2231 в C#).
Моя вторая попытка заключалась в использовании System.Security.Cryptography.Pkcs:

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

private byte[] SignChallenge(byte[] challenge)
{
var contentInfo = new System.Security.Cryptography.Pkcs.ContentInfo(challenge);

var signedCms = new SignedCms(contentInfo, true);
var signer = new CmsSigner(Cert);
signer.DigestAlgorithm = Oid.FromFriendlyName("SHA256", OidGroup.HashAlgorithm);
signer.SignaturePadding = RSASignaturePadding.Pss;

signedCms.ComputeSignature(signer);
var signedMessage = signedCms.Encode();
return signedMessage;
}
Это намного короче, но тоже не повезло.


Подробнее здесь: https://stackoverflow.com/questions/791 ... th-c-sharp
Ответить

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

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