Создание CMS подписи
Отсоединённая подпись
// Создание отсоединённой подписи
public static void CreateDetachedSignedCmsWithStore2012_256()
{
byte[] signature;
using (var gostCert = GetGost2012_256Certificate())
{
var contentInfo = new ContentInfo(bytesToHash);
var signedCms = new CpSignedCms(contentInfo, true);
CpCmsSigner cmsSigner = new CpCmsSigner(gostCert);
// Опционально добавляем подписанные атрибуты.
cmsSigner.SignedAttributes.Add(new Pkcs9SigningTime(DateTime.Now));
cmsSigner.SignedAttributes.Add(new PkcsSigningCertificateV2(gostCert));
// Вычисляем и кодируем подпись в массив байт.
signedCms.ComputeSignature(cmsSigner);
signature = signedCms.Encode();
Console.WriteLine($"CMS Sign: {Convert.ToBase64String(signature)}");
}
// Создаем объект ContentInfo по сообщению.
// Это необходимо для создания объекта SignedCms.
ContentInfo contentInfoVerify = new ContentInfo(bytesToHash);
// Создаем SignedCms для декодирования и проверки.
CpSignedCms signedCmsVerify = new CpSignedCms(contentInfoVerify, true);
// Декодируем подпись
signedCmsVerify.Decode(signature);
// Проверяем подпись
signedCmsVerify.CheckSignature(true);
}
Присоединённая подпись
// Создание присодинённой подписи
public static void CreateAttachedSignedCmsWithStore2012_256()
{
byte[] signature;
using (var gostCert = GetGost2012_256Certificate())
{
var key = gostCert.GetGost3410_2012_256PrivateKey();
var contentInfo = new ContentInfo(bytesToHash);
var signedCms = new CpSignedCms(contentInfo, false);
CpCmsSigner cmsSigner = new CpCmsSigner(gostCert);
// Опционально добавляем подписанные атрибуты.
cmsSigner.SignedAttributes.Add(new Pkcs9SigningTime(DateTime.Now));
cmsSigner.SignedAttributes.Add(new PkcsSigningCertificateV2(gostCert));
// Вычисляем и кодируем подпись в массив байт.
signedCms.ComputeSignature(cmsSigner);
signature = signedCms.Encode();
Console.WriteLine($"CMS Sign: {Convert.ToBase64String(signature)}");
}
// Создаем SignedCms для декодирования и проверки.
CpSignedCms signedCmsVerify = new CpSignedCms();
// Декодируем подпись
signedCmsVerify.Decode(signature);
// Проверяем подпись
signedCmsVerify.CheckSignature(true);
}
Использование контейнера с паролем в cms подписи
string password = "111";
SecureString secureString = new SecureString();
foreach (char walk in password)
{
secureString.AppendChar(walk);
}
Gost3410_2012_256CryptoServiceProvider privateKey = cert.PrivateKey as Gost3410_2012_256CryptoServiceProvider;
privateKey.SetContainerPassword(secureString);
var cmsSigner = new CmsSigner(SubjectIdentifierType.IssuerAndSerialNumber, cert, privateKey);
Аналогичный вызов без SetContainerPassword
- будет кидать окошко с вводом пароля под Windows, или запрашивать ввод в консоли для Unix.
Вспомогательные функции
private static CpX509Certificate2 GetGost2012_256Certificate()
{
using (var store = new CpX509Store(StoreName.My, StoreLocation.CurrentUser))
{
store.Open(OpenFlags.ReadOnly);
// Замените test_gost_256_client_2022 на SubjectName вашего сертификата.
return store.Certificates.Find(X509FindType.FindBySubjectName, "test_gost_256_client_2022", false)[0];
}
}