MakeSignature.SignDeferred & Проблема встраивания подписи (Itextsharp) - PullRequest
2 голосов
/ 12 июня 2019

У меня есть считыватель смарт-карт.Я хочу подписать PDF с этим.Я почти преуспел, но у меня появляется ошибка, когда я открываю pdf в программе чтения акробатов:

Подписано DENİZ KASAR

"Документ был изменен или поврежден с момента его подписания"

Здесь мои сертификаты, сырье и окончательный PDF.

1010 * toBeSignedSTR BF080D04029AB900082C6DC1E1E21E947C5B61F57BD91B974138657DBA7FFDB0 1014 * signedDataSTR 7FC9509A4A025B4B92A61464F94D5C3DA1EC66AF7C4D0E6C96436DCDDF46E415CDD220B817CFCAD06F47E2C7F3CF724EC018519D783D93B5A7478533C3C7D1992DE36E7FFDC586DBE9A30987098587354623B12A915A6CAE49585E0DE8C67FC4E06AD760EFF37E06C6C2CD81617B06AE60CFD3547C512A2D47D71F818D64F72405A681E6FAC3FC74346E313A5F7DA343FAF202108786CA6070A185BA711B41DA9D4AA13D6024BC697422D3298B78B5500A18BDC8DAFAD907DE42F997F2B244337904E5D63D40FF36D7266BC3D5169F9CBC63295EFC5B65951194FD6ED6AED5CCDD0818D3D7D86C29C14090BB31BFD8B273A546EDC19319A6757381D482A97EB8 1018 *

1 Ответ

0 голосов
/ 17 июня 2019

Ваш исходный код и пример подписи

Для начала расшифровка байтов подписи с помощью открытого ключа вашего сертификата приводит к чему-то, что явно не дополнено ни PKCS1-v1_5, ни EMSA-PSS.Таким образом, ваша смарт-карта либо не подписывает, используя закрытый ключ, связанный с этим сертификатом C=TR,SERIALNUMBER=90000000684,CN=DENİZ KASAR, либо возвращает результат, который не является массивом байтов простой подписи для подписи RSASSA-PKCS1-v1_5 или RSASSA-PSS для ввода хеш-кода.значение.

Возможно, на вашей карте несколько закрытых ключей для разных сертификатов, и вы указали неправильный адрес.Вероятно, есть другая проблема.


Кроме того, вы вызываете getAuthenticatedAttributeBytes с этими параметрами

byte[] signatureHash = signature.getAuthenticatedAttributeBytes(hash, null, null, CryptoStandard.CMS);

, затем сохраняете hash в локальной переменной _hash, но, наконец,Вызовите GetEncodedPKCS7 с этими параметрами

byte[] encodedSignature = _signature.GetEncodedPKCS7(_signatureHash, null, null, null, CryptoStandard.CMS);

Это выглядит неверно, параметры этих вызовов (кроме клиента TSA), как ожидается, будут совпадать, вы должны также использовать _hash здесь.

Ваш последний пример подписи

В комментарии вы подтвердили, что ваша смарт-карта имеет два сертификата.Очевидно, в вашем более новом коде вы также успешно обратились к приложению для подписи сертификата, которым вы хотите подписать, в качестве байтов подписи после того, как расшифровка RSA заканчивается 0xbc, который является индикатором для подписей RSASSA-PSS.

Это такжеОднако есть и недостаток: API подписи iText 5.x не был реализован с учетом RSASSA-PSS, и, в частности, класс PdfPKCS7 не может правильно создавать контейнеры CMS из сигнатур RSASSA-PSS.

Это не такЭто означает, однако, что вы не можете использовать iText для подписи с помощью своей карты, вам просто нужно реализовать больше в своем собственном коде, в частности, вы должны собрать весь контейнер для подписи.

Для этого вы используете это MakeSignature helper

/**
 * Sign the document using an external container, usually a PKCS7. The signature is fully composed
 * externally, iText will just put the container inside the document.
 * @param sap the PdfSignatureAppearance
 * @param externalSignatureContainer the interface providing the actual signing
 * @param estimatedSize the reserved size for the signature
 * @throws GeneralSecurityException
 * @throws IOException
 * @throws DocumentException 
 */
public static void SignExternalContainer(PdfSignatureAppearance sap, IExternalSignatureContainer externalSignatureContainer, int estimatedSize)

и просто нужно реализовать IExternalSignatureContainer для построения и возврата контейнера сигнатур CMS в его методе Sign, который подписывает данные из данного потока.

Youможет создать этот контейнер CMS, используя классы BouncyCastle или, возможно, даже классы Microsoft.К сожалению, тем не менее, я в основном занимаюсь практической подписью на Java, а не на .Net, поэтому я не могу с этим ничего поделать.

В случае подписей RSASSA-PKCS1-v1_5

Альтернативным подходом было бы проверить, можете ли вы указать своей смарт-карте генерировать подписи RSASSA-PKCS1-v1_5 вместо этого, поскольку это позволит вам использовать iText для генерации контейнера CMS.Я бы не рекомендовал это, поскольку RSASSA-PKCS1-v1_5 более открыт для атак, чем RSASSA-PSS.

В комментарии вы специально задали вопрос об этом случае.В этом случае я бы предложил вам значительно изменить код подписи.В настоящее время он использует сочетание старых более низкоуровневых и новых высокоуровневых API-интерфейсов для подписи iText.Вам следует использовать только новый API.

В этом случае код подписи будет сокращен до этого ключевого кода

using (PdfReader reader = new PdfReader(SRC))
using (FileStream os = new FileStream(DEST, FileMode.Create))
{
    PdfStamper stamper = PdfStamper.CreateSignature(reader, os, '\0');
    // Creating the appearance
    PdfSignatureAppearance appearance = stamper.SignatureAppearance;
    appearance.Reason = "MyRes";
    appearance.Location = "MyLoc";
    appearance.SetVisibleSignature(new Rectangle(36, 748, 250, 400), 1, "SIG");
    // Creating the signature
    CustomExternalSignature pks = new CustomExternalSignature();
    MakeSignature.SignDetached(appearance, pks, pks.GetChain(), null, null, null, 0, CryptoStandard.CMS);
}

в сочетании с классом помощника CustomExternalSignature, объединяющим код вашего устройства:

public class CustomExternalSignature : IExternalSignature
{
    public ICollection<X509Certificate> GetChain()
    {
        [essentially your GetChain method, but return the List as is, don't make it an array]]
    }

    public string GetEncryptionAlgorithm()
    {
        return "RSA";
    }

    public string GetHashAlgorithm()
    {
        return "SHA256";
    }

    public byte[] Sign(byte[] message)
    {
        [your code to call the smart card function to sign the message using RSASSA-PKCS1-v1_5]
        [you might or might not have to hash the message first, I don't know that smart card API you use]
    }
}
...