Cette page peut contenir du texte traduit automatiquement.

Comment signer des PDF avec des jetons USB et des périphériques HSM en C# et VB.NET

Les autorités de certification de confiance n'autorisent plus le téléchargement de clés privées pour les certificats de signature de documents. Ces clés doivent être stockées sur du matériel sécurisé, tel que des jetons USB, des cartes à puce ou des HSM cloud.

Vous pouvez utiliser la bibliothèque Docotic.Pdf pour signer des documents PDF dans .NET à l'aide de périphériques HSM. Cet article décrit les intégrations avec Azure Key Vault, AWS KMS et le matériel compatible PKCS#11.

Bibliothèque Docotic.Pdf 9.7.18373 Tests de régression 15,244 réussis Téléchargements totaux de NuGet 5,976,723

Vous pouvez obtenir la bibliothèque et une clé de licence gratuite à durée limitée sur la page Télécharger la bibliothèque PDF C# .NET.

Signature PDF externe

Prérequis

Les exemples de code de cet article utilisent des certificats auto-signés pour signer les documents PDF. Par défaut, les lecteurs PDF ne font pas confiance à ces signatures. Les certificats auto-signés doivent être utilisés uniquement à des fins de test, et non en production. Pour générer des signatures PDF fiables, utilisez des certificats de signature de documents émis par des autorités de certification tierces.

Choisissez le bon certificat

Privilégiez les certificats provenant d'entreprises figurant sur la Liste de confiance Adobe Approuvée (AATL). Adobe Acrobat approuve par défaut les certificats de ces entreprises et n'affiche pas l'avertissement « Validité du certificat inconnue ».

Pour créer des documents conformes à la réglementation eIDAS de l'UE, vous devez utiliser des certificats qualifiés émis par des fournisseurs figurant sur les listes de confiance de l'Union européenne (EUTL).

Apprenez à utiliser votre certificat dans .NET

Lorsque vous commandez un certificat de signature de document, vous avez généralement accès à un HSM. Il peut s'agir d'un jeton USB physique ou d'une solution HSM cloud.

Vous devriez ensuite apprendre à signer des données avec ce HSM. C'est généralement la partie la plus délicate, car tous les fournisseurs de cryptographie sont différents. Consultez la documentation de votre jeton USB ou de votre API cloud.

Idéalement, vous devez trouver un SDK .NET correspondant. Ou au moins un SDK natif et l'utiliser via l'interopérabilité dans .NET.

Votre objectif est d'obtenir du code C# ou VB.NET capable de signer n'importe quel octet à l'aide de votre certificat.

PDF API pour la signature externe

Une fois que vous pouvez signer des octets avec votre périphérique HSM, vous pouvez signer des documents PDF avec Docotic.Pdf. Pour ce faire, implémentez l'interface IPdfSigner et utilisez-la pour la signature.

Implémentation de l'interface IPdfSigner

IPdfSigner déclare deux membres. La propriété SignatureAlgorithm renvoie l'algorithme utilisé pour la signature. Généralement, les algorithmes RSA ou ECDSA sont utilisés.

La méthode Sign est l'élément clé du flux de signature externe. Docotic.Pdf fournit à cette méthode le condensé des octets d'un document PDF. Vous devez signer ce condensé avec votre périphérique HSM et renvoyer les octets d'une signature numérique. Notez que vous ne devez pas renvoyer d'objet PKCS#7 ici. Générez et renvoyez simplement la signature cryptographique.

Docotic.Pdf appelle la méthode Sign deux fois pour chaque signature. Le premier appel sert à calculer l'espace requis pour la signature. Le second appel sert à signer le document.

Créer des options de signature externe PdfSigningOptions

Utilisez le constructeur PdfSigningOptions(IPdfSigner, X509Certificate2[]) pour signer des documents PDF avec votre implémentation IPdfSigner. Obtenez une chaîne de certificats et indiquez-la comme second argument. Au moins un certificat est requis, et le certificat de signature doit être placé en premier.

La dernière pièce du puzzle est la propriété PdfSigningOptions.DigestAlgorithm. Sa valeur doit correspondre à celle de IPdfSigner.SignatureAlgorithm et à l'implémentation de IPdfSigner.Sign.

Voyons comment signer des PDF avec des signatures externes dans des scénarios courants.

Signer des documents PDF avec le pilote PKCS#11 en C#

Si votre jeton USB ou votre carte à puce cryptographique est fourni avec un pilote PKCS#11, vous pouvez utiliser les bibliothèques Pkcs11Interop.X509Store ou Pkcs11Interop dans .NET. Pkcs11Interop est compatible avec les cartes à puce Atos CardOS, YubiKey PIV, SmartCard-HSM, SafeNet ProtectServer HSM et d'autres HSM.

L'exemple de code Signer des documents PDF à l'aide des pilotes PKCS#11 montre comment signer des documents PDF avec un jeton USB ou une carte à puce. Vous devrez personnaliser ces lignes :

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;

Notre exemple de configuration utilise SoftHSM2 comme émulateur de jeton USB. Dans les applications réelles, SoftHSM2 n'est pas nécessaire. Utilisez plutôt le pilote fourni avec le jeton USB.

Signer des documents PDF avec Azure Key Vault

Microsoft Azure Key Vault stocke les certificats et les clés de manière sécurisée. Vous devrez effectuer les préparatifs suivants :

  1. Créer un compte Azure.
  2. Créer un utilisateur Azure.
  3. Créer un coffre de clés.
  4. Autoriser l’accès au coffre de clés pour l’utilisateur Azure sélectionné.
  5. Ajouter un certificat de signature de document au coffre de clés. Vous pouvez importer des certificats depuis les autorités de certification intégrées.

Utilisez ensuite le package NuGet Azure.Security.KeyVault.Keys pour la signature dans .NET. Exemple de code C# pour la signature avec une clé 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;

Une implémentation associée de IPdfSigner pourrait ressembler à ceci :

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;
    }
}

Enfin, utilisez la classe AzureSigner pour signer des documents 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, ..);

Découvrez l'exemple de code complet Signer des documents PDF à l'aide d'Azure Key Vault sur GitHub.

Signer des documents PDF avec AWS KMS

AWS Key Management Service (KMS) est un autre stockage sécurisé pour les clés cryptographiques. La préparation suit les mêmes étapes qu'Azure Key Vault :

  1. Créer un compte AWS.
  2. Créer un utilisateur IAM.
  3. Ajouter une clé de signature.
  4. Autoriser l'accès aux clés pour l'utilisateur IAM sélectionné.

Pour AWS, vous devrez utiliser le package NuGet AWSSDK.KeyManagementService dans .NET. L'exemple de code pour la signature PDF est très proche du scénario 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();
    }
}

L'exemple de code complet Signer des documents PDF à l'aide d'AWS KMS est également disponible sur GitHub.

Conclusion

Utilisez la bibliothèque Docotic.Pdf pour signer des documents PDF à l'aide de clés USB, de cartes à puce ou de HSM cloud. Pour ce faire, implémentez l'interface IPdfSigner en C# ou VB.NET.

Téléchargez et essayez exemples de code pour les signatures numériques dans les PDF depuis GitHub. Consultez les articles connexes pour plus d'informations :

Questions fréquemment posées

Comment signer un PDF avec un jeton USB ou une carte à puce ?

Utilisez les bibliothèques .NET Docotic.Pdf et Pkcs11Interop pour signer des PDF avec un jeton ou une carte à puce. Consultez la section Signer des documents PDF avec le pilote PKCS#11 en C# pour plus de détails.

Comment utiliser SoftHSM avec mon jeton USB ou ma carte à puce ?

SoftHSM simule un véritable HSM. Vous n'avez pas besoin de SoftHSM si vous disposez d'un jeton USB ou d'une carte à puce. Utilisez plutôt le pilote PKCS#11 fourni avec votre HSM.

Comment signer un document PDF avec une signature externe ?

Consultez les sections Signer des documents PDF avec Azure Key Vault et Signer des documents PDF avec AWS KMS. La signature externe de PDF avec d'autres HSM cloud suit un processus similaire.

Comment utiliser Azure Key Vault dans .NET ?

Utilisez le package NuGet Azure.Security.KeyVault.Keys. Essayez l'exemple de code Signer des documents PDF à l'aide d'Azure Key Vault sur GitHub.