首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> Java 程式設計 >> Java 相關知識

Java 使用 DSA 金鑰對生成 XML 簽名

     編輯:Java 相關知識

基於 JSR 105 (javax.xml.crypto.dsig) 實現 XML 數字簽名

Java 內置支持 XML 數字簽名標準。下面展示如何生成 DSA 金鑰對,並對 XML 數據(通過 Reference URI 引用)進行規範化、摘要、簽名,輸出包含 KeyInfo 的 Signature 元素。

完整代碼範例

import java.security.*;
import javax.xml.crypto.dsig.*;
import javax.xml.crypto.dsig.keyinfo.*;
import javax.xml.crypto.dsig.spec.C14NMethodParameterSpec;
import java.util.Collections;

public class XmlDsigExample {
    public static void main(String[] args) throws Exception {
        // 1. 生成 DSA 金鑰對 (1024 位)
        KeyPairGenerator kpg = KeyPairGenerator.getInstance("DSA");
        kpg.initialize(1024, new SecureRandom());
        KeyPair dsaKeyPair = kpg.generateKeyPair();

        // 2. 獲取 XMLSignatureFactory (默認實現)
        XMLSignatureFactory sigFactory = XMLSignatureFactory.getInstance("DOM");

        // 3. 創建 Reference:指定被簽名數據 (此處為同一文檔中 Id="Body" 的元素)
        // DigestMethod: SHA-1
        Reference ref = sigFactory.newReference(
            "#Body",
            sigFactory.newDigestMethod(DigestMethod.SHA1, null)
        );

        // 4. 創建 SignedInfo:規範化方法、簽名算法、引用列表
        // Canonicalization: 包含註釋的排他規範化
        SignedInfo signedInfo = sigFactory.newSignedInfo(
            sigFactory.newCanonicalizationMethod(
                CanonicalizationMethod.INCLUSIVE_WITH_COMMENTS,
                (C14NMethodParameterSpec) null
            ),
            sigFactory.newSignatureMethod(SignatureMethod.DSA_SHA1, null),
            Collections.singletonList(ref)
        );

        // 5. 創建 KeyInfo:包含公鑰值
        KeyInfoFactory kif = sigFactory.getKeyInfoFactory();
        KeyValue kv = kif.newKeyValue(dsaKeyPair.getPublic());
        KeyInfo keyInfo = kif.newKeyInfo(Collections.singletonList(kv));

        // 6. 創建 XMLSignature 對象
        XMLSignature xmlSig = sigFactory.newXMLSignature(signedInfo, keyInfo);

        // 7. 簽名:需提供 XML 文檔上下文 (DOMSignContext)
        // 假設 document 是已解析的 org.w3c.dom.Document
        // DOMSignContext signContext = new DOMSignContext(dsaKeyPair.getPrivate(), document.getDocumentElement());
        // xmlSig.sign(signContext);
        // 完成後 document 將包含  元素

        System.out.println("XMLSignature 對象創建成功,調用 sign() 即可生成簽名。");
    }
}

關鍵步驟解析

  1. 金鑰生成:DSA 適合簽名,非加密。生產環境建議 2048 位及以上,並妥善保管私鑰(Keystore/HSM)。
  2. Reference URI:#Body 表示同文檔中 Id="Body" 的元素。也可簽名外部資源 (https://...) 或整個文檔 ("")。
  3. 規範化:確保簽名驗證時字節流一致。INCLUSIVE_WITH_COMMENTS 保留註釋。
  4. 簽名算法:DSA_SHA1 對應 https://www.w3.org/2000/09/xmldsig#dsa-sha1。現代建議使用 RSA-SHA256 或 ECDSA-SHA256。
  5. DOMSignContext:簽名時需指定私鑰和簽名元素的插入位置(父節點)。

驗證簽名


// 驗證端代碼片段
DOMValidateContext valContext = new DOMValidateContext(keyValue.getPublicKey(), signatureElement);
boolean valid = xmlSig.validate(valContext);

注意事項

  • 需將生成的 xmlSig 通過 sign() 寫入 DOM 文檔。
  • 命名空間處理:確保被簽名元素及其子孫節點的命名空間聲明正確規範化。
  • 性能:大文檔簽名耗時,考慮異步處理或流式簽名。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved