デジタル署名の操作

デジタル署名は、文書に署名し、署名者を認証して、文書が署名されてから変更されていないことを保証するための電子署名の技術的実装です。 公開鍵と秘密鍵の両方を生成するPKIプロトコルに従うため、各デジタル署名は署名者ごとに一意です。 文書にデジタル署名するとは、生成されたハッシュを暗号化するために数学的アルゴリズムが使用される署名者の秘密鍵を使用して署名を作成す

Aspose.Wordsは、既存のデジタル署名を検出、カウント、または検証し、文書に新しい署名を追加して、文書の改ざんを見つけることができます。 文書からすべてのデジタル署名を削除することもできます。 デジタル署名を操作するには、DigitalSignatureUtilクラスを使用します。

この記事では、デジタル文書の信頼性と整合性を検証するために上記のすべてを行う方法について説明します。

サポートされている形式

Aspose.Wordsを使用すると、DOC、OOXML、ODT文書のデジタル署名を操作し、生成された文書にPDFまたはXPS形式で署名することができます。

デジタル署名の制限

次の表は、Aspose.Wordsを使用してデジタル署名を操作する際に直面する可能性のあるいくつかの制限と、いくつかの代替オプションについて説明しています。

制限 代替オプション
それをロードして保存した後、文書上のデジタル署名の損失。 したがって、文書をサーバーに処理すると、予告なしにすべてのデジタル署名が失われる可能性があります。 文書にデジタル署名があるかどうかを確認し、見つかった場合は適切なアクションを実行します。 例えば、クライアントに、アップロードしているドキュメントに処理されると失われるデジタル署名が含まれていることを知らせるアラートを送信します。
Aspose.Wordsドキュメント内のマクロの操作をサポートします。 ただし、Aspose.Wordsはマクロのデジタル署名をまだサポートしていません。 ドキュメントを任意のWord形式にエクスポートし、Microsoft Wordを使用してマクロにデジタル署名を追加します。

デジタル署名の検出、カウント、および検証

Aspose.Wordsは、DetectFileFormatメソッドとHasDigitalSignatureプロパティを使用して、文書内のデジタル署名を検出できます。 そのようなチェックは署名の事実のみを検出し、その有効性は検出しないことに注意する価値があります。

文書は複数回署名することができ、これは異なるユーザーが行うことができます。 電子署名の有効性を確認するには、LoadSignaturesメソッドを使用して文書から電子署名をロードし、IsValidプロパティを使用する必要があります。 またAspose.Wordsでは、Countプロパティを使用して、文書内のすべてのデジタル署名のセットを数えることができます。

これらすべてが、文書を処理する前に文書の署名をチェックする効率的で安全な方法を提供します。

次のコード例は、デジタル署名の存在を検出して検証する方法を示しています:

// For complete examples and data files, please go to https://github.com/aspose-words/Aspose.Words-for-Java.git.
FileFormatInfo info = FileFormatUtil.detectFileFormat(getMyDir() + "Digitally signed.docx");
if (info.hasDigitalSignature())
{
System.out.println("Document {Path.GetFileName(MyDir + ");
}

デジタル署名 {#create-a-digital-signature}を作成する

デジタル署名を作成するには、idを確認する署名証明書をロードする必要があります。 デジタル署名された文書を送信すると、証明書と公開鍵も送信されます。

Aspose.Wordsは、国際的に認められているX.509PKI標準を使用して、公開鍵が証明書に含まれている署名者に属していることを確認するデジタル証明書であるX.509証明書を作成することができます。 これを行うには、CertificateHolderクラス内でCreateメソッドを使用します。

次のセクションでは、デジタル署名、署名行を追加する方法、および生成されたPDF文書に署名する方法について説明します。

文書に署名する

Aspose.Wordsを使用すると、SignメソッドとSignOptionsプロパティを使用して、DOC、DOCX、またはODT文書にデジタル署名できます。

証明書所有者と署名オプションを使用して文書に署名する方法を次のコード例に示します:

// For complete examples and data files, please go to https://github.com/aspose-words/Aspose.Words-for-Java.git.
CertificateHolder certHolder = CertificateHolder.create(getMyDir() + "morzal.pfx", "aw");
DigitalSignatureUtil.sign(getMyDir() + "Digitally signed.docx", getArtifactsDir() + "Document.Signed.docx",
certHolder);

署名行を追加する

署名行は、文書内のデジタル署名を視覚的に表現したものです。 Aspose.WordsDocumentBuilder.InsertSignatureLineメソッドを使用して署名行を挿入できます。 SignatureLineOptionsクラスを使用して、この表現のパラメータを設定することもできます。

たとえば、次の図は、有効な署名と無効な署名を表示する方法を示しています。

valid-digital-signature invalid-digital-signature

また、文書に署名行が含まれていてデジタル署名がない場合は、ユーザーに署名を追加するように依頼する機能があります。

次のコード例は、個人証明書と特定の署名行を使用してドキュメントに署名する方法を示しています:

// For complete examples and data files, please go to https://github.com/aspose-words/Aspose.Words-for-Java.git.
Document doc = new Document();
DocumentBuilder builder = new DocumentBuilder(doc);
SignatureLineOptions signatureLineOptions = new SignatureLineOptions();
{
signatureLineOptions.setSigner("yourname");
signatureLineOptions.setSignerTitle("Worker");
signatureLineOptions.setEmail("yourname@aspose.com");
signatureLineOptions.setShowDate(true);
signatureLineOptions.setDefaultInstructions(false);
signatureLineOptions.setInstructions("Please sign here.");
signatureLineOptions.setAllowComments(true);
}
SignatureLine signatureLine = builder.insertSignatureLine(signatureLineOptions).getSignatureLine();
signatureLine.setProviderId(UUID.fromString("CF5A7BB4-8F3C-4756-9DF6-BEF7F13259A2"));
doc.save(getArtifactsDir() + "SignDocuments.SignatureLineProviderId.docx");
SignOptions signOptions = new SignOptions();
{
signOptions.setSignatureLineId(signatureLine.getId());
signOptions.setProviderId(signatureLine.getProviderId());
signOptions.setComments("Document was signed by Aspose");
signOptions.setSignTime(new Date());
}
CertificateHolder certHolder = CertificateHolder.create(getMyDir() + "morzal.pfx", "aw");
DigitalSignatureUtil.sign(getArtifactsDir() + "SignDocuments.SignatureLineProviderId.docx",
getArtifactsDir() + "SignDocuments.CreateNewSignatureLineAndSetProviderId.docx", certHolder, signOptions);

生成されたPDF文書 {#sign-a-generated-pdf-document}に署名する

Aspose.Wordsでは、PdfDigitalSignatureDetailsプロパティを使用して、PDF文書のすべての詳細に署名して取得できます。

次のコード例は、生成されたPDFに署名する方法を示しています:

// For complete examples and data files, please go to https://github.com/aspose-words/Aspose.Words-for-Java.git.
Document doc = new Document();
DocumentBuilder builder = new DocumentBuilder(doc);
builder.writeln("Test Signed PDF.");
PdfSaveOptions saveOptions = new PdfSaveOptions();
{
saveOptions.setDigitalSignatureDetails(new PdfDigitalSignatureDetails(
CertificateHolder.create(getMyDir() + "morzal.pfx", "aw"), "reason", "location",
new Date()));
}
doc.save(getArtifactsDir() + "WorkingWithPdfSaveOptions.DigitallySignedPdfUsingCertificateHolder.pdf", saveOptions);

下の図は、生成されたPDFドキュメントがAdobe Acrobatで開かれ、デジタル署名が存在し有効であることを確認していることを示しています。

create-digital-signed-pdf-aspose-words-java

デジタル署名値の取得

Aspose.Wordsは、SignatureValueプロパティを使用して、デジタル署名されたドキュメントからデジタル署名値をバイト配列として取得する機能も提供します。

次のコード例は、ドキュメントからデジタル署名値をバイト配列として取得する方法を示しています:

// For complete examples and data files, please go to https://github.com/aspose-words/Aspose.Words-for-Java.git.
Document doc = new Document(getMyDir() + "Digitally signed.docx");
for (DigitalSignature digitalSignature : doc.getDigitalSignatures())
{
String signatureValue = Base64.getEncoder().encodeToString(digitalSignature.getSignatureValue());
Assert.assertEquals("K1cVLLg2kbJRAzT5WK+m++G8eEO+l7S+5ENdjMxxTXkFzGUfvwxREuJdSFj9AbD" +
"MhnGvDURv9KEhC25DDF1al8NRVR71TF3CjHVZXpYu7edQS5/yLw/k5CiFZzCp1+MmhOdYPcVO+Fm" +
"+9fKr2iNLeyYB+fgEeZHfTqTFM2WwAqo=", signatureValue);
}

デジタル署名の削除

Aspose.Wordsは、RemoveAllSignaturesメソッドを使用して、署名された文書からすべてのデジタル署名を削除できます。

次のコード例は、ドキュメントからデジタル署名を読み込んで削除する方法を示しています:

// For complete examples and data files, please go to https://github.com/aspose-words/Aspose.Words-for-Java.git.
// There are two ways of using the DigitalSignatureUtil class to remove digital signatures
// from a signed document by saving an unsigned copy of it somewhere else in the local file system.
// 1 - Determine the locations of both the signed document and the unsigned copy by filename strings:
DigitalSignatureUtil.removeAllSignatures(getMyDir() + "Digitally signed.docx",
getArtifactsDir() + "DigitalSignatureUtil.LoadAndRemove.FromString.docx");
// 2 - Determine the locations of both the signed document and the unsigned copy by file streams:
try (FileInputStream streamIn = new FileInputStream(getMyDir() + "Digitally signed.docx"))
{
try (FileOutputStream streamOut = new FileOutputStream(getArtifactsDir() + "DigitalSignatureUtil.LoadAndRemove.FromStream.docx"))
{
DigitalSignatureUtil.removeAllSignatures(streamIn, streamOut);
}
}
// Verify that both our output documents have no digital signatures.
Assert.assertEquals(IterableUtils.size(DigitalSignatureUtil.loadSignatures(getArtifactsDir() + "DigitalSignatureUtil.LoadAndRemove.FromString.docx")), 0);
Assert.assertEquals(IterableUtils.size(DigitalSignatureUtil.loadSignatures(getArtifactsDir() + "DigitalSignatureUtil.LoadAndRemove.FromStream.docx")), 0);