Статус: Новичок
Группы: Участники
Зарегистрирован: 12.01.2016(UTC) Сообщений: 4
|
Есть следующий код: Код:byte[] encodedCMS = ...GetBytes...;
var cms = new SignedCms();
try
{
// Распаковка - нет проблем
cms.Decode(encodedCMS);
// Проверяем количество подписей - нет проблем, SignerInfos.Count == 1
if (cms.SignerInfos.Count!=1)
throw new Exception("Количество подписавших не равно 1");
// Получаем данные сертификата из подписи
var si = cms.SignerInfos[0];
var sid = si.SignerIdentifier; // Нет проблем, данные правильные:
// sid.IssuerName = [CN=УЦ Федерального казначейства, O=Федеральное казначейство, C=RU, L=Москва, STREET="улица Ильинка, дом 7", ОГРН=1047797019830, ИНН=007710568760, S=77 г. Москва, E=uc_fk@roskazna.ru, OID.1.2.840.113549.1.9.2=Server CA]
// sid.SerialNumber = [0BFE1D]
var cert = si.Certificate; // ПРОБЛЕМА:
// cert.SubjectName = [CN=УЦ Федерального казначейства, O=Федеральное казначейство, C=RU, L=Москва, STREET="улица Ильинка, дом 7", ОГРН=1047797019830, ИНН=007710568760, S=77 г. Москва, E=uc_fk@roskazna.ru, OID.1.2.840.113549.1.9.2=Server CA]
// cert.SerialNumber = [01]
// cert.IssuerName = [CN=УЦ Федерального казначейства, O=Федеральное казначейство, C=RU, L=Москва, STREET="улица Ильинка, дом 7", ОГРН=1047797019830, ИНН=007710568760, S=77 г. Москва, E=uc_fk@roskazna.ru, OID.1.2.840.113549.1.9.2=Server CA]
// Проверка подписи - ПРОБЛЕМА: HRes(-2146889714) Не найден автор исходной подписи.\r\n
cms.CheckSignature(true);
} catch (Exception ex)
{
// Получаем ошибку:
// HRes(-2146889714) Не найден автор исходной подписи.\r\n
// в System.Security.Cryptography.Pkcs.SignerInfo.Verify(X509Certificate2Collection extraStore, X509Certificate2 certificate, Boolean verifySignatureOnly)
// в System.Security.Cryptography.Pkcs.SignerInfo.CheckSignature(X509Certificate2Collection extraStore, Boolean verifySignatureOnly)
// в System.Security.Cryptography.Pkcs.SignedCms.CheckSignatures(SignerInfoCollection signers, X509Certificate2Collection extraStore, Boolean verifySignatureOnly)
// в System.Security.Cryptography.Pkcs.SignedCms.CheckSignature(X509Certificate2Collection extraStore, Boolean verifySignatureOnly)
// в System.Security.Cryptography.Pkcs.SignedCms.CheckSignature(Boolean verifySignatureOnly)
}
При детальной отладке выяснилось, что проблема в si.Certificate - вместо сертификата, который использовался для подписи получаем сертификат УЦ. При изучении исходников .Net видим, что поиск сертификата при обращении к System.Security.Cryptography.Pkcs.SignerInfo.Certificate идет следующим образом: Код:public X509Certificate2 Certificate
{
get
{
if (this.m_certificate == null)
this.m_certificate = PkcsUtils.FindCertificate(this.SignerIdentifier, this.m_signedCms.Certificates);
return this.m_certificate;
}
}
Смотрим System.Security.Cryptography.Pkcs.PkcsUtils.FindCertificate: Код:internal static X509Certificate2 FindCertificate(SubjectIdentifier identifier, X509Certificate2Collection certificates)
{
X509Certificate2 x509Certificate2 = (X509Certificate2) null;
if (certificates != null && certificates.Count > 0)
{
switch (identifier.Type)
{
case SubjectIdentifierType.IssuerAndSerialNumber:
X509Certificate2Collection certificate2Collection1 = certificates.Find(X509FindType.FindByIssuerDistinguishedName, (object) ((X509IssuerSerial) identifier.Value).IssuerName, false);
if (certificate2Collection1.Count > 0)
{
X509Certificate2Collection certificate2Collection2 = certificate2Collection1.Find(X509FindType.FindBySerialNumber, (object) ((X509IssuerSerial) identifier.Value).SerialNumber, false);
if (certificate2Collection2.Count > 0)
{
x509Certificate2 = certificate2Collection2[0];
break;
}
break;
}
break;
case SubjectIdentifierType.SubjectKeyIdentifier:
X509Certificate2Collection certificate2Collection3 = certificates.Find(X509FindType.FindBySubjectKeyIdentifier, identifier.Value, false);
if (certificate2Collection3.Count > 0)
{
x509Certificate2 = certificate2Collection3[0];
break;
}
break;
}
}
return x509Certificate2;
}
Проверяем cms.SignerInfos[0].SignerIdentifier и видим корректные данные: Код:
IssuerName = [CN=УЦ Федерального казначейства, O=Федеральное казначейство, C=RU, L=Москва, STREET="улица Ильинка, дом 7", ОГРН=1047797019830, ИНН=007710568760, S=77 г. Москва, E=uc_fk@roskazna.ru, OID.1.2.840.113549.1.9.2=Server CA]
SerialNumber = [0BFE1D]
Проверяем cms.Certificates и видим 2 сертификата: Код:[0].SubjectName = [CN=УЦ Федерального казначейства, O=Федеральное казначейство, C=RU, L=Москва, STREET="улица Ильинка, дом 7", ОГРН=1047797019830, ИНН=007710568760, S=77 г. Москва, E=uc_fk@roskazna.ru, OID.1.2.840.113549.1.9.2=Server CA]
[0].SerialNumber = [01]
[0].IssuerName = [CN=УЦ Федерального казначейства, O=Федеральное казначейство, C=RU, L=Москва, STREET="улица Ильинка, дом 7", ОГРН=1047797019830, ИНН=007710568760, S=77 г. Москва, E=uc_fk@roskazna.ru, OID.1.2.840.113549.1.9.2=Server CA]
[1].SubjectName = [CN=Бунеев Валерий Леонтьевич, OID.1.2.840.113549.1.9.2=1.2.643.3.61.1.1.6.502710.3.4.2.1, T=Председатель, SN=Бунеев, G=Валерий Леонтьевич, OU=Руководство, O=Избирательная комиссия го Воронеж, L=Воронеж, S=36 Воронежская область, C=RU, E=vgik227241@yandex.ru, ОГРН=1073668014056, СНИЛС=05943640481, ИНН=3666150124]
[1].SerialNumber = [0BFE1D]
[1].IssuerName = [CN=УЦ Федерального казначейства, O=Федеральное казначейство, C=RU, L=Москва, STREET="улица Ильинка, дом 7", ОГРН=1047797019830, ИНН=007710568760, S=77 г. Москва, E=uc_fk@roskazna.ru, OID.1.2.840.113549.1.9.2=Server CA]
Вся информация корректна. Эмулируем поиск сертификата System.Security.Cryptography.Pkcs.PkcsUtils.FindCertificate: Код:
var res = cms.Certificates
.Find(X509FindType.FindByIssuerDistinguishedName, (object) ((System.Security.Cryptography.Xml.X509IssuerSerial) cms.SignerInfos[0].SignerIdentifier.Value).IssuerName, false)
.Find(X509FindType.FindBySerialNumber, (object) ((System.Security.Cryptography.Xml.X509IssuerSerial) cms.SignerInfos[0].SignerIdentifier.Value).SerialNumber, false);
получаем res.Count = 2: Код:[0].SubjectName = [CN=УЦ Федерального казначейства, O=Федеральное казначейство, C=RU, L=Москва, STREET="улица Ильинка, дом 7", ОГРН=1047797019830, ИНН=007710568760, S=77 г. Москва, E=uc_fk@roskazna.ru, OID.1.2.840.113549.1.9.2=Server CA]
[0].SerialNumber = [01]
[0].IssuerName = [CN=УЦ Федерального казначейства, O=Федеральное казначейство, C=RU, L=Москва, STREET="улица Ильинка, дом 7", ОГРН=1047797019830, ИНН=007710568760, S=77 г. Москва, E=uc_fk@roskazna.ru, OID.1.2.840.113549.1.9.2=Server CA]
[1].SubjectName = [CN=Бунеев Валерий Леонтьевич, OID.1.2.840.113549.1.9.2=1.2.643.3.61.1.1.6.502710.3.4.2.1, T=Председатель, SN=Бунеев, G=Валерий Леонтьевич, OU=Руководство, O=Избирательная комиссия го Воронеж, L=Воронеж, S=36 Воронежская область, C=RU, E=vgik227241@yandex.ru, ОГРН=1073668014056, СНИЛС=05943640481, ИНН=3666150124]
[1].SerialNumber = [0BFE1D]
[1].IssuerName = [CN=УЦ Федерального казначейства, O=Федеральное казначейство, C=RU, L=Москва, STREET="улица Ильинка, дом 7", ОГРН=1047797019830, ИНН=007710568760, S=77 г. Москва, E=uc_fk@roskazna.ru, OID.1.2.840.113549.1.9.2=Server CA]
что и приводит к проблеме с var cert = si.Certificate. Данная проблема проявляется с несколькими сертификатами, выданными с использованием именно этого сертификата УЦФК, с остальными сертификатами УЦ такой проблемы не наблюдается. Установлен CSP 4.0 + CryptoPro.NET, ЭП была создана с использованием BrowserPlugin (код взят с тестовой страницы сайта), утилиты проверки ЭП показывают правильный сертификат создателя подписи. Так как из .NET вызовы на получение данных сертификатов и вызов методов поиска уходит в неуправляемый код, то самостоятельно добраться до проблемы не получается, проблема наблюдается только с ГОСТ сертификатами. В чем и где может быть проблема и как можно решить данную проблему? В файле  data.zip (23kb) загружен 4 раз(а).:
- base64EncodedCMS.cms - проверяемая ЭП
- osinfo.xml - данные о системе
- user.cer - открытая часть сертификата пользователя, создавшего ЭП
- УЦФК.cer - открытая часть сертификата УЦ
Отредактировано пользователем 12 января 2016 г. 20:26:47(UTC)
| Причина: Не указана
|