Ключевое слово в защите информации
КЛЮЧЕВОЕ СЛОВО
в защите информации
Получить ГОСТ TLS-сертификат для домена (SSL-сертификат)
Добро пожаловать, Гость! Чтобы использовать все возможности Вход или Регистрация.

Уведомление

Icon
Error

3 Страницы<123
Опции
К последнему сообщению К первому непрочитанному
Offline Tsitrus  
#21 Оставлено : 10 июля 2019 г. 15:54:29(UTC)
Tsitrus

Статус: Новичок

Группы: Участники
Зарегистрирован: 08.07.2019(UTC)
Сообщений: 1

Добрый день!
Использую пример выше для валидации подписи в PDF файле по госту Р 34.10-2012
В строке signedCms.CheckSignature(false) падает с ошибкой
An unhandled exception of type 'System.Security.Cryptography.CryptographicException' occurred in System.Security.Cryptography.Pkcs.dll: 'Unknown algorithm '1.2.643.7.1.1.1.1

System.Security.Cryptography.Pkcs обновил до 4.6.0-preview6.19303.8

Буду признателен за помощь.
Oshibka.png (58kb) загружен 16 раз(а).
Offline LONG11  
#22 Оставлено : 23 мая 2020 г. 16:14:39(UTC)
LONG11

Статус: Активный участник

Группы: Участники
Зарегистрирован: 05.04.2020(UTC)
Сообщений: 45
Российская Федерация
Откуда: Москва

Сказал(а) «Спасибо»: 24 раз
Всем добрый день. Подниму тему.
Если пользоваться примером для проверки подписи, то можно столкнуться с такой ситуацией:

Подписываем документ дважды: с уровнем сертификации PDF файла = CERTIFIED_NO_CHANGES_ALLOWED.
Ну вот типа ошиблись и подписали 2 раза с таким уровнем. Ведь позволяет, - позволяет.

При использовании алгоритма ГОСТ 2012, мы не можем использовать последующую проверку валидности подписей:
PdfPKCS7 pk = acroFields.VerifySignature(signatureName);
так как это вызовет ошибку распознания digest "1.2.643.7.1.1.2.2"

Именно поэтому используем, приведенный вами везде в примере код:

// Создаем SignedCms для декодирования и проверки.
SignedCms signedCms = new SignedCms(contentInfo, true);
// Декодируем подпись
signedCms.Decode(signatureBytes);
bool checkResult;
try
{
signedCms.CheckSignature(true);
checkResult = true;
}
catch (Exception)
{
checkResult = false;
}

Но, обратите внимание на иллюстрацию. Этот метод покажет, что подпись действительна (выделено зеленым).
checkResult = true - будет всегда.
И в тоже время, что документ был изменен с момента последнего подписания, то есть недействителен.
Oshibka.jpg (60kb) загружен 25 раз(а).

Если бы использовали: PdfPKCS7 pk = acroFields.VerifySignature(signatureName); - он бы корректно отображал, что документ был изменен.
Но по причине ГОСТ 2012 мы использовать его не можем.

Как получать программно, что имеющиеся подписи в документе, хоть и действительны, но документ является недействительным?

Образец документа, если нужно могу прислать в личку сотрудникам.

Offline LONG11  
#23 Оставлено : 25 мая 2020 г. 18:22:33(UTC)
LONG11

Статус: Активный участник

Группы: Участники
Зарегистрирован: 05.04.2020(UTC)
Сообщений: 45
Российская Федерация
Откуда: Москва

Сказал(а) «Спасибо»: 24 раз
ping

Вопрос то очень актуальный.
Offline Артём Макаров  
#24 Оставлено : 26 мая 2020 г. 9:13:16(UTC)
Артём Макаров

Статус: Сотрудник

Группы: Участники
Зарегистрирован: 20.02.2017(UTC)
Сообщений: 205

Сказал(а) «Спасибо»: 4 раз
Поблагодарили: 54 раз в 53 постах
Добрый день.

Дважды подписал документ через пример формирования pdf подписи с выставленным `CERTIFIED_NO_CHANGES_ALLOWED`.

Выполняю проверку по примеру выше, получаю корректный результат:

Код:
Signature name: Signature1
Signature covers whole document: False
Document revision: 1 of 2
Document modified: True
Certificate [Subject]
  CN=Gost_2012_256_Test

[Issuer]
  CN=Gost_2012_256_Test

[Serial Number]
  75119D8C51055AA24574ADEE5DFB6ABC

[Not Before]
  28.11.2017 10:56:35

[Not After]
  20.03.2040 10:31:00

[Thumbprint]
  2E83C566E18EC8EBC253C933184AAD1CF989788F

CAPI Validation: True
Date: 26.05.2020 5:42:45


Signature name: Signature2
Signature covers whole document: True
Document revision: 2 of 2
Document modified: False
Certificate [Subject]
  CN=Gost_2012_256_Test

[Issuer]
  CN=Gost_2012_256_Test

[Serial Number]
  75119D8C51055AA24574ADEE5DFB6ABC

[Not Before]
  28.11.2017 10:56:35

[Not After]
  20.03.2040 10:31:00

[Thumbprint]
  2E83C566E18EC8EBC253C933184AAD1CF989788F

CAPI Validation: True
Date: 26.05.2020 5:44:24


Результат проверки подписи документа (после вызова `signedCms.CheckSignature(true);`) записан в выводе в поле `Document modified`, первая подпись недействительна, вторая - действительна.
Поле `CAPI Validation` отвечает за проверку сертификата подписи, не самой подписи.

Запустите пожалуйста пример проверки на вашем подписанном файле и пришлите вывод, аналогичный моему. Также пришлите pdf файл на почту makarov@cryptopro.ru
Техническую поддержку оказываем тут
Наша база знаний
thanks 1 пользователь поблагодарил Артём Макаров за этот пост.
LONG11 оставлено 27.05.2020(UTC)
Offline LONG11  
#25 Оставлено : 27 мая 2020 г. 16:23:25(UTC)
LONG11

Статус: Активный участник

Группы: Участники
Зарегистрирован: 05.04.2020(UTC)
Сообщений: 45
Российская Федерация
Откуда: Москва

Сказал(а) «Спасибо»: 24 раз
Артем, добрый день.
Файл выслал.
Offline Георгий Садофьев  
#26 Оставлено : 28 мая 2020 г. 9:11:54(UTC)
Георгий Садофьев

Статус: Сотрудник

Группы: Участники
Зарегистрирован: 14.10.2011(UTC)
Сообщений: 130
Мужчина

Поблагодарили: 26 раз в 25 постах
Добрый день!

Приведённый выше способ проверяет только целостность документа, но не проверяет ограничения, накладываемые PDF-подписью на подписываемый документ.
Проверка ограничений должна выполняться отдельно от проверки целостности.

Вот ссылки на полезные примеры проверки подписи:
https://itextpdf.com/en/resources/examples/itext-7/digital-signatures-chapter-5

Код для получения ограничений подписи:

Код:

/* Every new signature can add more restrictions to a document, but it can't take away previous restrictions.
* So if you want to retrieve information about signatures restrictions, you need to pass
* the SignaturePermissions instance of the previous signature, or null if there was none.
*/
var perms = new SignaturePermissions(sigDict, /*previous permissions*/null);
Console.Out.WriteLine("Signature type: " + (perms.Certification ? "certification" : "approval"));
Console.Out.WriteLine("Filling out fields allowed: " + perms.FillInAllowed);
Console.Out.WriteLine("Adding annotations allowed: " + perms.AnnotationsAllowed);  



Здесь интересно поле perms.FillInAllowed - оно показывает, разрешено ли заполнение полей (в т.ч. добавление новых подписей) в документ, соответственно, если тип подписи perms.Certification == true и perms.FillInAllowed == false, то последующие подписи нарушают ограничения, накладываемые данной подписью, эту информацию можно отображать при проверке.

Желательно при подписи PDF документа проверять текущие ограничения и не добавлять последующие подписи, если это нарушит эти ограничения.

Более полная информация по цифровым подписям в PDF содержится в книге:
https://itextpdf.com/en/resources/books/digital-signatures-pdf
Техническую поддержку оказываем тут
Наша база знаний
thanks 1 пользователь поблагодарил Георгий Садофьев за этот пост.
LONG11 оставлено 28.05.2020(UTC)
Offline LONG11  
#27 Оставлено : 28 мая 2020 г. 12:53:54(UTC)
LONG11

Статус: Активный участник

Группы: Участники
Зарегистрирован: 05.04.2020(UTC)
Сообщений: 45
Российская Федерация
Откуда: Москва

Сказал(а) «Спасибо»: 24 раз
Да,именно эти моменты я контролирую.
ОК, будем иметь ввиду. Спасибо.
Offline benchstyle  
#28 Оставлено : 1 июня 2020 г. 10:14:02(UTC)
benchstyle

Статус: Участник

Группы: Участники
Зарегистрирован: 26.04.2020(UTC)
Сообщений: 10
Откуда: Муром

Сказал(а) «Спасибо»: 1 раз
Здравствуйте, взял готовый пример от iText7, экспортировал сертификат с тестового УЦ Криптопро для Гост 2012:

Цитата:

string Certificate = @"C:\Templates\MyCert.pfx";
char[] PASSWORD = "12345".ToCharArray();

string DEST = @"C:\Templates\result.pdf";
string SRC = @"C:\Templates\doc.pdf";

FileStream fs = new FileStream(Certificate, FileMode.Open, FileAccess.Read);
Pkcs12Store pk12 = new Pkcs12Store();
pk12.Load(fs, PASSWORD);
string alias = null;
foreach (object a in pk12.Aliases)
{
alias = ((string)a);
if (pk12.IsKeyEntry(alias))
{
break;
}
}

ICipherParameters pk = pk12.GetKey(alias).Key;

X509CertificateEntry[] ce = pk12.GetCertificateChain(alias);
X509Certificate[] chain = new X509Certificate[ce.Length];
for (int k = 0; k < ce.Length; ++k)
{
chain[k] = ce[k].Certificate;
}

PdfReader reader = new PdfReader(SRC);
PdfSigner signer = new PdfSigner(reader, new FileStream(DEST, FileMode.Create), true);

PdfSignatureAppearance appearance = signer.GetSignatureAppearance();
appearance.SetReason("My reason to sign...")
.SetLocation("Lahore")
.SetPageRect(new Rectangle(36, 648, 200, 100))
.SetPageNumber(1);
signer.SetFieldName("MyFieldName");

IExternalSignature pks = new PrivateKeySignature(pk, DigestAlgorithms.SHA256);

signer.SignDetached(pks, chain, null, null, null, 0, PdfSigner.CryptoStandard.CMS);


Получаю исключение - System.ArgumentNullException: 'Ссылка на строку не ссылается на экземпляр String.
Имя параметра: source'
Цитата:
в System.Globalization.CompareInfo.IsPrefix(String source, String prefix, CompareOptions options)
в Org.BouncyCastle.Security.PbeUtilities.CreateEngine(String algorithm)
в Org.BouncyCastle.Security.PbeUtilities.CreateEngine(AlgorithmIdentifier algID)
в Org.BouncyCastle.Pkcs.PrivateKeyInfoFactory.CreatePrivateKeyInfo(Char[] passPhrase, Boolean wrongPkcs12Zero, EncryptedPrivateKeyInfo encInfo)
в Org.BouncyCastle.Pkcs.Pkcs12Store.LoadPkcs8ShroudedKeyBag(EncryptedPrivateKeyInfo encPrivKeyInfo, Asn1Set bagAttributes, Char[] password, Boolean wrongPkcs12Zero)
в Org.BouncyCastle.Pkcs.Pkcs12Store.Load(Stream input, Char[] password)


Данная ошибка только с сертификатом от криптопро, пробовал несколько других pfx с открытым ключом RSA - проблем не возникло. Подскажите в какую сторону смотреть?
Offline Артём Макаров  
#29 Оставлено : 1 июня 2020 г. 10:27:38(UTC)
Артём Макаров

Статус: Сотрудник

Группы: Участники
Зарегистрирован: 20.02.2017(UTC)
Сообщений: 205

Сказал(а) «Спасибо»: 4 раз
Поблагодарили: 54 раз в 53 постах
Добрый день.

Не уверен, что BouncyCastle умеет работать с гостовыми pfx КриптоПро.

Попробуйте загрузить сертификат как объект X509Certificate2, после чего выполните действия аналогичные примеру подписи

Код:

// загрузка сертификата в объект  X509Certificate2 certificate

PdfReader reader = new PdfReader(document);
PdfStamper st = PdfStamper.CreateSignature(reader, new FileStream(document + "_signed.pdf", FileMode.Create, FileAccess.Write), '\0');                        
PdfSignatureAppearance sap = st.SignatureAppearance;

// Загружаем сертификат в объект iTextSharp
X509CertificateParser parser = new X509CertificateParser();
Org.BouncyCastle.X509.X509Certificate[] chain = new Org.BouncyCastle.X509.X509Certificate[] { 
    parser.ReadCertificate(certificate.RawData)
};

sap.Certificate = parser.ReadCertificate(certificate.RawData);

// остальной код подписи


Полный пример формирования pdf подписи можно найти в SDK (pdf/Sign.cs).
Техническую поддержку оказываем тут
Наша база знаний
Offline benchstyle  
#30 Оставлено : 1 июня 2020 г. 10:35:50(UTC)
benchstyle

Статус: Участник

Группы: Участники
Зарегистрирован: 26.04.2020(UTC)
Сообщений: 10
Откуда: Муром

Сказал(а) «Спасибо»: 1 раз
Автор: Артём Макаров Перейти к цитате
Добрый день.

Не уверен, что BouncyCastle умеет работать с гостовыми pfx КриптоПро.

Попробуйте загрузить сертификат как объект X509Certificate2, после чего выполните действия аналогичные примеру подписи

Код:

// загрузка сертификата в объект  X509Certificate2 certificate

PdfReader reader = new PdfReader(document);
PdfStamper st = PdfStamper.CreateSignature(reader, new FileStream(document + "_signed.pdf", FileMode.Create, FileAccess.Write), '\0');                        
PdfSignatureAppearance sap = st.SignatureAppearance;

// Загружаем сертификат в объект iTextSharp
X509CertificateParser parser = new X509CertificateParser();
Org.BouncyCastle.X509.X509Certificate[] chain = new Org.BouncyCastle.X509.X509Certificate[] { 
    parser.ReadCertificate(certificate.RawData)
};

sap.Certificate = parser.ReadCertificate(certificate.RawData);

// остальной код подписи


Полный пример формирования pdf подписи можно найти в SDK (pdf/Sign.cs).


Артем, пробовал получать сертификат из хранилища пользователя как объект X509Certificate2.
Тогда встает другая проблема, как получать из него приватный ключ для дальнейшей работы с: ICipherParameters pk в iText7
RSS Лента  Atom Лента
Пользователи, просматривающие эту тему
3 Страницы<123
Быстрый переход  
Вы не можете создавать новые темы в этом форуме.
Вы не можете отвечать в этом форуме.
Вы не можете удалять Ваши сообщения в этом форуме.
Вы не можете редактировать Ваши сообщения в этом форуме.
Вы не можете создавать опросы в этом форуме.
Вы не можете голосовать в этом форуме.