SignAzureKeyVault.vb
C# VB
'''' This code is part of Document Solutions for PDF .NET demos.'' Copyright (c) MESCIUS inc. All rights reserved.''Imports SystemImports System.IOImports System.DrawingImports System.Security.Cryptography.X509CertificatesImports Org.BouncyCastle.Crypto.DigestsImports Azure.CoreImports Azure.IdentityImports Azure.Security.KeyVault.CertificatesImports Azure.Security.KeyVault.Keys.CryptographyImports GrapeCity.Documents.PdfImports GrapeCity.Documents.Pdf.Security
'' This sample shows how to sign an existing PDF file that contains'' an empty signature field with a certificate that is stored'' in an Azure Key Vault.'''' The sample includes a ready to use utility class AzureSignatureGenerator'' that implements the GrapeCity.Documents.Pdf.IPkcs7SignatureGenerator interface,'' and can be used to sign PDFs with certificates stored in Azure Key Vault.'''' Please note that when run directly off the DsPdf demo site,'' this sample will NOT sign the PDF, as it passes dummy Azure credentials'' to the AzureSignatureGenerator's ctor. You will need to download the sample'' and provide your own credentials for the sample code to actually sign a PDF.Public Class SignAzureKeyVault Function CreatePDF(ByVal stream As Stream) As Integer Dim doc = New GcPdfDocument() Using s = File.OpenRead(Path.Combine("Resources", "PDFs", "SignAzureKeyVault.pdf")) doc.Load(s)
Try '' This WILL NOT WORK due to dummy Azure credentials. '' Supply valid credentials to actually sign the PDF. Using sg = New AzureSignatureGenerator( "keyVaultName", "tenantId", "clientId", "clientSecret", "certificateName")
Dim sp = New SignatureProperties() With { .SignatureBuilder = New Pkcs7SignatureBuilder() With { .SignatureGenerator = sg, .CertificateChain = New X509Certificate2() {sg.Certificate} }, .SignatureField = doc.AcroForm.Fields(0) } doc.Sign(sp, stream) End Using Catch e As Exception Dim page = doc.Pages(0) Dim r = doc.AcroForm.Fields(0).Widgets(0).Rect Util.AddNote( "Signing failed because dummy Azure credentials were used." & vbLf & "Use valid Azure Key Vault credentials to sign the PDF.", page, New RectangleF(r.Left, r.Bottom + 24, page.Size.Width - r.Left * 2, 0)) doc.Save(stream) End Try End Using
'' Done. Return doc.Pages.Count End FunctionEnd Class
''' <summary>''' Implements IPkcs7SignatureGenerator''' and allows generating a digital signature using''' a certificate stored in Azure Key Vault.''' </summary>Public Class AzureSignatureGenerator Implements IPkcs7SignatureGenerator Implements IDisposable
Private _certificateClient As CertificateClient Private _certificate As X509Certificate2 Private _cryptographyClient As CryptographyClient
''' <summary> ''' Initializes a new instance of the AzureSignatureGenerator class. ''' </summary> Public Sub New( ByVal keyVaultName As String, ByVal tenantId As String, ByVal clientId As String, ByVal clientSecret As String, ByVal certificateName As String) Dim keyVaultUri = New Uri($"https://{keyVaultName}.vault.azure.net/") Dim credential As TokenCredential = New ClientSecretCredential(tenantId, clientId, clientSecret) _certificateClient = New CertificateClient(keyVaultUri, credential) Dim c = _certificateClient.GetCertificate(certificateName) _certificate = New X509Certificate2(c.Value.Cer) _cryptographyClient = New CryptographyClient(c.Value.KeyId, credential) End Sub
''' <summary> ''' Gets the ID of the hash algorithm. ''' </summary> Public ReadOnly Property HashAlgorithm As OID Implements IPkcs7SignatureGenerator.HashAlgorithm Get Return OID.HashAlgorithms.SHA256 End Get End Property
''' <summary> ''' Gets the ID of the encryption algorithm. ''' </summary> Public ReadOnly Property DigestEncryptionAlgorithm As OID Implements IPkcs7SignatureGenerator.DigestEncryptionAlgorithm Get Return OID.EncryptionAlgorithms.RSA End Get End Property
''' <summary> ''' Gets the certificate. ''' </summary> Public ReadOnly Property Certificate As X509Certificate2 Get Return _certificate End Get End Property
''' <summary> ''' Signs data. ''' </summary> Public Function SignData(ByVal input As Byte()) As Byte() Implements IPkcs7SignatureGenerator.SignData Dim hashDigest = New Sha256Digest() Dim hash = New Byte(hashDigest.GetDigestSize() - 1) {} hashDigest.Reset() hashDigest.BlockUpdate(input, 0, input.Length) hashDigest.DoFinal(hash, 0) Dim result As Byte() = _cryptographyClient.Sign(SignatureAlgorithm.RS256, hash).Signature Return result End Function
''' <summary> ''' Releases resources used by this object. ''' </summary> Public Sub Dispose() Implements IDisposable.Dispose _certificateClient = Nothing If _certificate IsNot Nothing Then _certificate.Dispose() _certificate = Nothing End If _cryptographyClient = Nothing End SubEnd Class