Эта страница может содержать автоматически переведенный текст.
Как подписывать PDF файлы с помощью USB-токенов и устройств HSM в C# и VB.NET
Доверенные центры сертификации больше не разрешают экспортировать закрытые ключи для сертификатов подписи документов. Вместо этого закрытые ключи должны храниться на защищенном оборудовании, таком как USB-токены, смарт-карты или облачные HSM.
Вы можете использовать библиотеку Docotic.Pdf для подписи документов PDF в .NET с помощью устройств HSM. В этой статье описывается интеграция с Azure Key Vault, AWS KMS и оборудованием, совместимым с PKCS#11.
9.7.18373 15,244 прошло Всего загрузок NuGet 5,976,723Библиотеку и бесплатный лицензионный ключ с ограниченным сроком действия можно получить на странице Скачать PDF библиотеку C# .NET.
Предварительные условия
Примеры кода в этой статье используют самоподписанные сертификаты для подписи PDF документов. По умолчанию просмотрщики PDF файлов не доверяют этим подписям. Самоподписанные сертификаты следует использовать только для тестирования, а не в производственных средах. Для создания доверенных подписей PDF файлов используйте сертификаты подписи документов, выпущенные сторонними центрами сертификации.
Получить правильный сертификат
Предпочитайте сертификаты от компаний, перечисленных в списке Adobe Approved Trust List (AATL). Adobe Acrobat доверяет сертификатам от таких компаний по умолчанию и не будет сообщать предупреждение «Действительность сертификата неизвестна».
Для создания документов, соответствующих требованиям ЕС (eIDAS), вам необходимо использовать квалифицированные сертификаты, выданные поставщиками, перечисленными в списках доверенных лиц Европейского союза (EUTL).
Узнать, как использовать ваш сертификат в .NET
При заказе сертификата для подписи документов вы обычно получаете доступ к устройству HSM. Это может быть физический USB-токен или облачное решение HSM.
Затем вам следует узнать, как подписывать данные с помощью этого HSM. Обычно это самая сложная часть, поскольку все криптопровайдеры разные. Вам следует следовать документации для вашего USB-токена или облачного API.
В идеале вам нужно найти соответствующий .NET SDK. Или, по крайней мере, найти нативный SDK и использовать его через interop в .NET.
Ваша цель — получить код C# или VB.NET, который сможет подписывать любые байты, используя ваш сертификат.
PDF API для внешней подписи
Как только вы сможете подписывать любые байты с помощью вашего устройства HSM, вы готовы подписывать документы PDF с помощью Docotic.Pdf. Для этого реализуйте интерфейс IPdfSigner и используйте его для подписи.
Реализовать интерфейс IPdfSigner
IPdfSigner
объявляет два члена. Свойство SignatureAlgorithm
возвращает алгоритм, используемый
для подписи. Обычно используются алгоритмы RSA или ECDSA.
Метод Sign
является ключевой частью внешнего потока подписи. Docotic.Pdf предоставляет дайджест
байтов документа PDF этому методу. Вы должны подписать этот дайджест с помощью вашего устройства
HSM и вернуть байты цифровой подписи. Обратите внимание, что вы не должны возвращать здесь объект
PKCS#7. Просто сгенерируйте и верните криптографическую подпись.
Docotic.Pdf вызывает метод Sign
дважды для каждой подписи. Первый вызов — для расчета места,
необходимого для подписи. Второй вызов — для фактической подписи документа.
Создать PdfSigningOptions для внешней подписи
Используйте конструктор PdfSigningOptions(IPdfSigner, X509Certificate2[])
для подписи PDF документов с помощью вашей реализации IPdfSigner
. Получите цепочку сертификатов и
укажите ее в качестве второго аргумента. Требуется как минимум один сертификат, и сертификат
подписи должен быть первым.
Последняя часть головоломки — свойство PdfSigningOptions.DigestAlgorithm
. Значение этого свойства
должно соответствовать IPdfSigner.SignatureAlgorithm
и реализации IPdfSigner.Sign
.
Давайте рассмотрим, как подписывать PDF файлы внешними подписями в распространенных сценариях.
Подписать PDF документы с использованием драйвера PKCS#11 на языке C#
Если ваш криптографический USB-токен или смарт-карта поставляются с драйвером PKCS#11, то вы можете
использовать библиотеки Pkcs11Interop.X509Store
или Pkcs11Interop в .NET. Pkcs11Interop
совместим со смарт-картами Atos CardOS, YubiKey PIV, SmartCard-HSM, SafeNet ProtectServer HSM и другими HSM.
Пример кода Подписывайте PDF-документы с помощью драйвера PKCS#11 показывает, как подписывать PDF документы с помощью USB-токена или смарт-карты. Вам нужно будет настроить эти строки:
string pkcsLibraryPath = @"C:\Program Files\SoftHSM2\lib\softhsm2-x64.dll";
ulong slotId = 1743347971;
string alias = "YOUR-ALIAS";
string certLabel = "YOUR-CERTIFICATE";
string pin = "YOUR-PIN";
var digestAlgorithm = PdfDigestAlgorithm.Sha512;
Наш пример конфигурации использует SoftHSM2 как эмулятор USB-токена. В реальных приложениях вам не нужен SoftHSM2. Вместо этого используйте драйвер, который идет с USB-токеном.
Подписать PDF документы с помощью Azure Key Vault
Microsoft Azure Key Vault надежно хранит сертификаты и ключи. Вам нужно будет сделать следующие приготовления:
- Создайте учетную запись Azure.
- Создайте пользователя Azure.
- Создайте Key Vault.
- Разрешите доступ к Key Vault выбранному пользователю Azure.
- Добавьте сертификат подписи документа в Key Vault. Вы можете импортировать сертификаты из интегрированных центров сертификации.
Затем используйте пакет NuGet Azure.Security.KeyVault.Keys
для подписи в .NET. Пример кода C# для
подписи с помощью ключа из Azure Key Vault:
var vaultUrl = new Uri("https://YOUR-VAULT.vault.azure.net/");
var credential = new DefaultAzureCredential();
var keyClient = new KeyClient(vaultUrl, credential);
KeyVaultKey key = keyClient.GetKey("YOUR-KEY");
var cryptoClient = new CryptographyClient(key.Id, credentials);
byte[] messageToSign = ..;
byte[] signature = cryptoClient.SignData(SignatureAlgorithm.RS512, messageToSign).Signature;
Связанная реализация IPdfSigner
может выглядеть так:
class AzureSigner : IPdfSigner
{
private readonly CryptographyClient m_client;
private readonly AzureSignatureAlgorithm m_signingAlgorithm;
public AzureSigner(CryptographyClient client, AzureSignatureAlgorithm signingAlgorithm)
{
m_client = client;
m_signingAlgorithm = signingAlgorithm;
}
public PdfSignatureAlgorithm SignatureAlgorithm
{
get
{
if (m_signingAlgorithm == AzureSignatureAlgorithm.RS256 ||
m_signingAlgorithm == AzureSignatureAlgorithm.RS384 ||
m_signingAlgorithm == AzureSignatureAlgorithm.RS512)
return PdfSignatureAlgorithm.Rsa;
throw new NotSupportedException($"Unsupported {nameof(SignatureAlgorithm)} value: {m_signingAlgorithm}");
}
}
public PdfDigestAlgorithm DigestAlgorithm
{
get
{
if (m_signingAlgorithm == AzureSignatureAlgorithm.RS256)
return PdfDigestAlgorithm.Sha256;
if (m_signingAlgorithm == AzureSignatureAlgorithm.RS384)
return PdfDigestAlgorithm.Sha384;
if (m_signingAlgorithm == AzureSignatureAlgorithm.RS512)
return PdfDigestAlgorithm.Sha512;
throw new NotSupportedException($"Unsupported {nameof(SignatureAlgorithm)} value: {m_signingAlgorithm}");
}
}
public byte[] Sign(byte[] message)
{
return m_client.SignData(m_signingAlgorithm, message).Signature;
}
}
Наконец, используйте этот класс AzureSigner
для подписи PDF документов:
CryptographyClient cryptoClient = ..;
using X509Certificate2 cert = ..
var signer = new AzureSigner(cryptoClient, SignatureAlgorithm.RS512);
using var pdf = new PdfDocument();
PdfPage page = pdf.Pages[0];
PdfSignatureField field = page.AddSignatureField(50, 50, 200, 200);
var options = new PdfSigningOptions(signer, new[] { cert })
{
DigestAlgorithm = signer.DigestAlgorithm,
Field = field,
};
pdf.SignAndSave(options, ..);
Изучите полный пример кода Подписывайте PDF-документы с помощью Azure Key Vault. на GitHub.
Подписать PDF документы с помощью AWS KMS
AWS Key Management Service (KMS) — еще одно безопасное хранилище для криптографических ключей. Подготовка выполняется так же, как и в Azure Key Vault:
- Создайте учетную запись AWS.
- Создайте пользователя IAM.
- Добавьте ключ подписи.
- Разрешите доступ к ключам для выбранного пользователя IAM.
Для AWS вам понадобится использовать пакет NuGet AWSSDK.KeyManagementService
в .NET. Пример кода
для подписи PDF довольно близок к сценарию Azure:
using var pdf = new PdfDocument();
PdfPage page = pdf.Pages[0];
PdfSignatureField field = page.AddSignatureField(50, 50, 200, 200);
var signingAlgorithm = SigningAlgorithmSpec.RSASSA_PSS_SHA_512;
var signer = new AwsSigner("arn:aws:kms:YOUR-id", signingAlgorithm)
var options = new PdfSigningOptions(signer, new[] { cert })
{
DigestAlgorithm = signer.DigestAlgorithm,
Field = field,
};
pdf.SignAndSave(options, ..);
class AwsSigner : IPdfSigner
{
private readonly string m_keyId;
private readonly SigningAlgorithmSpec m_signingAlgorithm;
public AwsSigner(string keyId, SigningAlgorithmSpec signingAlgorithm)
{
m_keyId = keyId;
m_signingAlgorithm = signingAlgorithm;
}
public PdfSignatureAlgorithm SignatureAlgorithm
{
get
{
if (m_signingAlgorithm == SigningAlgorithmSpec.RSASSA_PKCS1_V1_5_SHA_256 ||
m_signingAlgorithm == SigningAlgorithmSpec.RSASSA_PKCS1_V1_5_SHA_384 ||
m_signingAlgorithm == SigningAlgorithmSpec.RSASSA_PKCS1_V1_5_SHA_512)
return PdfSignatureAlgorithm.Rsa;
throw new NotSupportedException($"Unsupported {nameof(SigningAlgorithmSpec)} value: {m_signingAlgorithm}");
}
}
public PdfDigestAlgorithm DigestAlgorithm
{
get
{
string alg = m_signingAlgorithm.Value;
if (alg.EndsWith("256"))
return PdfDigestAlgorithm.Sha256;
if (alg.EndsWith("384"))
return PdfDigestAlgorithm.Sha384;
if (alg.EndsWith("512"))
return PdfDigestAlgorithm.Sha512;
throw new NotSupportedException($"Unsupported {nameof(SigningAlgorithmSpec)} value: {m_signingAlgorithm}");
}
}
public byte[] Sign(byte[] message)
{
using var kmsClient = new AmazonKeyManagementServiceClient();
using var stream = new MemoryStream(message);
var signRequest = new SignRequest()
{
SigningAlgorithm = m_signingAlgorithm,
KeyId = m_keyId,
MessageType = MessageType.RAW,
Message = stream,
};
SignResponse signResponse = kmsClient.SignAsync(signRequest).GetAwaiter().GetResult();
return signResponse.Signature.ToArray();
}
}
Полный пример кода Подписывайте PDF-документы с помощью AWS KMS также доступен на GitHub.
Заключение
Используйте библиотеку Docotic.Pdf для подписи документов PDF с помощью USB-токенов,
смарт-карт или облачных HSM. Для этого реализуйте интерфейс IPdfSigner
в коде C# или VB.NET.
Загрузите и попробуйте примеры кода для цифровых подписей в PDF с GitHub. Ознакомьтесь со связанными статьями для получения дополнительной информации:
Часто задаваемые вопросы
Как подписать PDF с помощью USB-токена или смарт-карты?
Используйте библиотеки Docotic.Pdf и Pkcs11Interop .NET для подписи PDF файлов с помощью токена или смарт-карты. Дополнительные сведения см. в разделе Подписать PDF документы с использованием драйвера PKCS#11 на языке C#.
Как использовать SoftHSM с моим USB-токеном или смарт-картой?
SoftHSM имитирует настоящее устройство HSM. Вам не нужен SoftHSM, если у вас есть USB-токен или смарт-карта. Вместо этого используйте драйвер PKCS#11, предоставленный вместе с вашим устройством HSM.
Как подписать PDF-документ внешней подписью?
Check the Sign PDF documents using Azure Key Vault and Sign PDF documents using AWS KMS sections. External PDF signing with other cloud-based HSMs follows a similar process.
Проверьте разделы Подписать PDF документы с помощью Azure Key Vault и Подписать PDF документы с помощью AWS KMS. Внешняя подпись PDF с помощью других облачных HSM выполняется аналогичным образом.
Как использовать Azure Key Vault в .NET?
Используйте пакет NuGet Azure.Security.KeyVault.Keys
. Попробуйте пример кода
Подписывайте PDF-документы с помощью Azure Key Vault. с GitHub.