Trabalhando com assinaturas digitais

Uma assinatura digital é usada para autenticar um documento para estabelecer que o remetente do documento é quem diz ser e que o conteúdo do documento não foi adulterado.

Aspose.Words oferece suporte a documentos com assinaturas digitais e fornece acesso a eles, permitindo detectar e validar assinaturas digitais em um documento e assinar um documento PDF gerado com um certificado fornecido. Atualmente, as assinaturas digitais são suportadas em documentos DOC, OOXML e ODT. A assinatura dos documentos gerados é suportada em formato PDF.

Assinaturas digitais não são preservadas ao abrir e salvar

Um ponto importante a ser observado é que um documento carregado e salvo usando Aspose.Words perderá todas as assinaturas digitais assinadas no documento. Isto ocorre intencionalmente, pois uma assinatura digital garante que o conteúdo não foi modificado e, além disso, autentica a identidade de quem assinou o documento. Estes princípios seriam invalidados se as assinaturas originais fossem transportadas para o documento resultante.

Devido a isso, se você processar documentos carregados em um servidor, isso pode significar que você pode corromper um documento carregado em seu servidor dessa forma sem saber. Portanto, é melhor verificar a existência de assinaturas digitais num documento e tomar as medidas adequadas caso sejam encontradas, por exemplo, pode ser enviado um alerta ao cliente informando-o de que o documento que está a passar contém assinaturas digitais que serão perdidas se forem processado. Você pode baixar o arquivo de modelo deste exemplo em aqui.

# For complete examples and data files, please go to https://github.com/aspose-words/Aspose.Words-for-Python-via-.NET
info = aw.FileFormatUtil.detect_file_format(docs_base.my_dir + "Digitally signed.docx")
if info.has_digital_signature:
print("Document has digital signatures, they will be lost if you open/save this document with Aspose.words.")

O código acima usa o método FileFormatUtil.detect_file_format para detectar se um documento contém assinaturas digitais sem primeiro carregar o documento. Isso fornece uma maneira eficiente e segura de verificar se há assinaturas em um documento antes de processá-las. Quando executado, o método retorna um objeto FileFormatInfo que fornece a propriedade FileFormatInfo.has_digital_signature. Esta propriedade retorna true se o documento contiver uma ou mais assinaturas digitais. É importante observar que este método não valida as assinaturas, apenas determina se as assinaturas estão presentes. A validação de assinaturas digitais é abordada na próxima seção.

Assinaturas digitais em macros (projetos VBA)

As assinaturas digitais em macros não podem ser acessadas ou assinadas. Isso ocorre porque o Aspose.Words não lida diretamente com macros em um documento. No entanto, as assinaturas digitais nas macros são preservadas ao exportar o documento de volta para qualquer formato Word. Essas assinaturas podem ser preservadas no código VBA porque o conteúdo binário das macros não é alterado, mesmo que o próprio documento seja modificado.

Acesse e verifique assinaturas digitais

Um documento pode ter várias assinaturas digitais. Todas essas assinaturas podem ser acessadas por meio da coleção Document.digital_signatures. Cada objeto retornado é um DigitalSignature que representa uma única assinatura digital pertencente ao documento. Isso fornece membros que permitem verificar a validade da assinatura.

A propriedade mais importante a ser verificada com assinaturas digitais é a validade de cada assinatura no documento. Todas as assinaturas do documento podem ser validadas de uma só vez chamando a propriedade DigitalSignatureCollection.is_valid. Isso retornará true se todas as assinaturas do documento forem válidas ou se o documento não tiver assinaturas e false se pelo menos uma assinatura digital não for válida.

Cada assinatura também pode ser validada individualmente chamando DigitalSignature.is_valid. Uma assinatura pode retornar inválida por vários motivos, por exemplo, o documento foi alterado desde a assinatura ou o certificado expirou. Além disso, detalhes extras da assinatura também podem ser acessados. O exemplo de código abaixo mostra como validar cada assinatura em um documento e exibir informações básicas sobre a assinatura. Você pode baixar o arquivo de modelo deste exemplo em aqui.

# For complete examples and data files, please go to https://github.com/aspose-words/Aspose.Words-for-Python-via-.NET
doc = aw.Document(docs_base.my_dir + "Digitally signed.docx")
for signature in doc.digital_signatures :
print("*** Signature Found ***")
print("Is valid: " + str(signature.is_valid))
# This property is available in MS Word documents only.
print("Reason for signing: " + signature.comments)
print("Time of signing: " + str(signature.sign_time))
#print("Subject name: " + signature.certificate_holder.certificate.subject_name.name)
#print("Issuer name: " + signature.certificate_holder.certificate.issuer_name.name)
print()

Assinando documentos do Word

A classe DigitalSignatureUtil fornece métodos para assinar documentos. O método DigitalSignatureUtil.sign assina o documento de origem usando determinado CertificateHolder com assinatura digital e grava o documento assinado no fluxo de destino

O exemplo abaixo mostra como assinar um documento simples

# For complete examples and data files, please go to https://github.com/aspose-words/Aspose.Words-for-Python-via-.NET
certHolder = aw.digitalsignatures.CertificateHolder.create(docs_base.my_dir + "morzal.pfx", "aw")
aw.digitalsignatures.DigitalSignatureUtil.sign(docs_base.my_dir + "Digitally signed.docx", docs_base.artifacts_dir + "Document.signed.docx", certHolder)

O exemplo abaixo mostra como assinar um documento criptografado

# For complete examples and data files, please go to https://github.com/aspose-words/Aspose.Words-for-Python-via-.NET
signOptions = aw.digitalsignatures.SignOptions()
signOptions.decryption_password = "decryptionPassword"
certHolder = aw.digitalsignatures.CertificateHolder.create(docs_base.my_dir + "morzal.pfx", "aw")
aw.digitalsignatures.DigitalSignatureUtil.sign(docs_base.my_dir + "Digitally signed.docx", docs_base.artifacts_dir + "Document.encrypted_document.docx",
certHolder, signOptions)

Assinando documento do Word com linha de assinatura

Você pode assinar o documento de origem usando CertificateHolder e SignOptions com assinatura digital e gravar o documento assinado no arquivo de destino. Usando a classe SignOptions você pode especificar opções para assinatura de documentos. O exemplo abaixo mostra como criar uma nova linha de assinatura e assinar um documento

# For complete examples and data files, please go to https://github.com/aspose-words/Aspose.Words-for-Python-via-.NET
doc = aw.Document()
builder = aw.DocumentBuilder(doc)
signatureLine = builder.insert_signature_line(aw.SignatureLineOptions()).signature_line
doc.save(docs_base.artifacts_dir + "SignDocuments.signature_line.docx")
signOptions = aw.digitalsignatures.SignOptions()
signOptions.signature_line_id = signatureLine.id
with open(docs_base.images_dir + "Enhanced Windows MetaFile.emf", "rb") as image_file:
signOptions.signature_line_image = image_file.read()
certHolder = aw.digitalsignatures.CertificateHolder.create(docs_base.my_dir + "morzal.pfx", "aw")
aw.digitalsignatures.DigitalSignatureUtil.sign(docs_base.artifacts_dir + "SignDocuments.signature_line.docx",
docs_base.artifacts_dir + "SignDocuments.new_signature_line.docx", certHolder, signOptions)

O exemplo abaixo mostra como modificar a linha de assinatura existente e assinar o documento

# For complete examples and data files, please go to https://github.com/aspose-words/Aspose.Words-for-Python-via-.NET
doc = aw.Document(docs_base.my_dir + "Signature line.docx")
signatureLine = doc.first_section.body.get_child(aw.NodeType.SHAPE, 0, True).as_shape().signature_line
signOptions = aw.digitalsignatures.SignOptions()
signOptions.signature_line_id = signatureLine.id
imagefile = open(docs_base.images_dir + "Enhanced Windows MetaFile.emf", "rb")
with open(docs_base.images_dir + "Enhanced Windows MetaFile.emf", "rb") as image_file:
signOptions.signature_line_image = image_file.read()
certHolder = aw.digitalsignatures.CertificateHolder.create(docs_base.my_dir + "morzal.pfx", "aw")
aw.digitalsignatures.DigitalSignatureUtil.sign(docs_base.my_dir + "Digitally signed.docx",
docs_base.artifacts_dir + "SignDocuments.signing_existing_signature_line.docx", certHolder, signOptions)

Assinando documento do Word usando identificador de provedor de assinatura

O exemplo abaixo mostra como assinar um documento do Word usando o identificador do provedor de assinatura. O provedor de serviços criptográficos (CSP) é um módulo de software independente que realmente executa algoritmos de criptografia para autenticação, codificação e criptografia. O MS Office reserva o valor {00000000-0000-0000-0000-000000000000} para seu provedor de assinatura padrão.

# For complete examples and data files, please go to https://github.com/aspose-words/Aspose.Words-for-Python-via-.NET
doc = aw.Document(docs_base.my_dir + "Signature line.docx")
signatureLine = doc.first_section.body.get_child(aw.NodeType.SHAPE, 0, True).as_shape().signature_line
signOptions = aw.digitalsignatures.SignOptions()
signOptions.provider_id = signatureLine.provider_id
signOptions.signature_line_id = signatureLine.id
certHolder = aw.digitalsignatures.CertificateHolder.create(docs_base.my_dir + "morzal.pfx", "aw")
aw.digitalsignatures.DigitalSignatureUtil.sign(docs_base.my_dir + "Digitally signed.docx",
docs_base.artifacts_dir + "SignDocuments.set_signature_provider_id.docx", certHolder, signOptions)

Criar novo documento de assinatura de linha de assinatura usando o identificador de provedor

O exemplo abaixo mostra como criar uma linha de assinatura e assinar um documento do Word usando o identificador do provedor de assinatura.

# For complete examples and data files, please go to https://github.com/aspose-words/Aspose.Words-for-Python-via-.NET
doc = aw.Document()
builder = aw.DocumentBuilder(doc)
signatureLineOptions = aw.SignatureLineOptions()
signatureLineOptions.signer = "vderyushev"
signatureLineOptions.signer_title = "QA"
signatureLineOptions.email = "vderyushev@aspose.com"
signatureLineOptions.show_date = True
signatureLineOptions.default_instructions = False
signatureLineOptions.instructions = "Please sign here."
signatureLineOptions.allow_comments = True
signatureLine = builder.insert_signature_line(signatureLineOptions).signature_line
signatureLine.provider_id = uuid.UUID('{CF5A7BB4-8F3C-4756-9DF6-BEF7F13259A2}')
doc.save(docs_base.artifacts_dir + "SignDocuments.signature_line_provider_id.docx")
signOptions = aw.digitalsignatures.SignOptions()
signOptions.signature_line_id = signatureLine.id
signOptions.provider_id = signatureLine.provider_id
signOptions.comments = "Document was signed by vderyushev"
signOptions.sign_time = datetime.today()
certHolder = aw.digitalsignatures.CertificateHolder.create(docs_base.my_dir + "morzal.pfx", "aw")
aw.digitalsignatures.DigitalSignatureUtil.sign(docs_base.artifacts_dir + "SignDocuments.signature_line_provider_id.docx",
docs_base.artifacts_dir + "SignDocuments.create_new_signature_line_and_set_provider_id.docx", certHolder, signOptions)

Recuperar o valor da assinatura digital

Aspose.Words também oferece a capacidade de recuperar o valor da assinatura digital de um documento assinado digitalmente como uma matriz de bytes usando a propriedade SignatureValue.

O exemplo de código a seguir mostra como obter o valor da assinatura digital como uma matriz de bytes de um documento:

doc = aw.Document(MY_DIR + "Digitally signed.docx")

for digital_signature in doc.digital_signatures:
    signature_value = base64.b64encode(digital_signature.signature_value)
    print(f"Base64 signature value is: {signature_value}")