2013-04-30 18 views
5

Tôi đang cố gắng ký một tệp xml bằng cách sử dụng chữ ký bao bọc và các lớp javax.xml.crypto.dsig. *. Kết quả là tôi nhận được tệp có nội dung Chữ ký chính xác nhưng không có không gian tên được xác định. Làm thế nào tôi có thể thêm xmlns: ds = "http://www.w3.org/2000/09/xmldsig#" không gian tên và tiền tố ds tương ứng? Tôi không thấy bất kỳ nơi nào tôi có thể xác định nó.Cách thêm không gian tên trong khi ký tệp XML bằng cách sử dụng javax.xml.crypto.dsig. *?

Ví dụ mã:

XMLSignatureFactory xmlSignatureFactory = XMLSignatureFactory.getInstance("DOM"); 

    (...) 

    XMLSignature signature = xmlSignatureFactory.newXMLSignature(signedInfo, keyInfo); 

    // Marshal, generate, and sign the enveloped signature. 
    signature.sign(domSignContext); 

cho ví dụ XML:

<?xml version="1.0" encoding="UTF-8"?> 
<test xmlns="http://different.namespace.com"> 
    <someBody/> 
    <Signature xmlns="http://www.w3.org/2000/09/xmldsig#"> 
     <SignedInfo> 
      <CanonicalizationMethod Algorithm="http://www.w3.org/TR/2001/REC-xml-c14n-20010315"/> 
      <SignatureMethod Algorithm="http://www.w3.org/2000/09/xmldsig#rsa-sha1"/>  
      <Reference URI=""> 
       <Transforms> 
        <Transform Algorithm="http://www.w3.org/2000/09/xmldsig#enveloped-signature"/> 
       </Transforms> 
       <DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1"/> 
       <DigestValue>base64_digest</DigestValue> 
      </Reference> 
     </SignedInfo> 
     <SignatureValue>some_base64</SignatureValue> 
     <KeyInfo> 
      <X509Data> 
       <X509SubjectName>subject_data</X509SubjectName> 
       <X509Certificate>some_more_base64</X509Certificate> 
      </X509Data> 
      <KeyValue> 
       <RSAKeyValue> 
        <Modulus>another_base64</Modulus> 
        <Exponent>base64_as_well</Exponent> 
       </RSAKeyValue> 
      </KeyValue> 
     </KeyInfo> 
    </Signature> 
</test> 

nhưng tôi muốn:

<?xml version="1.0" encoding="UTF-8"?> 
<test xmlns="http://different.namespace.com" xmlns:ds="http://www.w3.org/2000/09/xmldsig#"> 
    <someBody/> 
    <ds:Signature xmlns="http://www.w3.org/2000/09/xmldsig#"> 
     <ds:SignedInfo> 
      <ds:CanonicalizationMethod Algorithm="http://www.w3.org/TR/2001/REC-xml-c14n-20010315"/> 
      <ds:SignatureMethod Algorithm="http://www.w3.org/2000/09/xmldsig#rsa-sha1"/>  
      <ds:Reference URI=""> 
       <ds:Transforms> 
        <ds:Transform Algorithm="http://www.w3.org/2000/09/xmldsig#enveloped-signature"/> 
       </ds:Transforms> 
       <ds:DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1"/> 
       <ds:DigestValue>base64_digest</ds:DigestValue> 
      </ds:Reference> 
     </ds:SignedInfo> 
     <ds:SignatureValue>some_base64</ds:SignatureValue> 
     <ds:KeyInfo> 
      <ds:X509Data> 
       <ds:X509SubjectName>subject_data</ds:X509SubjectName> 
       <ds:X509Certificate>some_more_base64</ds:X509Certificate> 
      </ds:X509Data> 
      <ds:KeyValue> 
       <ds:RSAKeyValue> 
        <ds:Modulus>another_base64</ds:Modulus> 
        <ds:Exponent>base64_as_well</ds:Exponent> 
       </ds:RSAKeyValue> 
      </ds:KeyValue> 
     </ds:KeyInfo> 
    </ds:Signature> 
</test> 
+0

Kết quả là XML đúng. Tại sao bạn muốn có tiền tố đó trên ? Có, nó được coi là tiền tố "nổi tiếng", nhưng điều này không ảnh hưởng đến tính chính xác của XML kết quả. – user568826

Trả lời

3

Dưới đây là các mẫu mã từ Oracle để tạo chữ ký bao bọc. Và tôi đoán những gì bạn đang tìm kiếm là dsc.setDefaultNamespacePrefix ("dsig"); như trong ví dụ dưới đây.

XMLSignatureFactory fac = XMLSignatureFactory.getInstance("DOM"); 

    Reference ref = fac.newReference 
    ("", fac.newDigestMethod(DigestMethod.SHA1, null), 
      Collections.singletonList 
      (fac.newTransform 
        (Transform.ENVELOPED, (TransformParameterSpec) null)), 
        null, null); 

    // Create the SignedInfo 
    SignedInfo si = fac.newSignedInfo 
    (fac.newCanonicalizationMethod 
      (CanonicalizationMethod.INCLUSIVE_WITH_COMMENTS, 
        (C14NMethodParameterSpec) null), 
        fac.newSignatureMethod(SignatureMethod.DSA_SHA1, null), 
        Collections.singletonList(ref)); 

    // Create a DSA KeyPair 
    KeyPairGenerator kpg = KeyPairGenerator.getInstance("DSA"); 
    kpg.initialize(512); 
    KeyPair kp = kpg.generateKeyPair(); 

    // Create a KeyValue containing the DSA PublicKey that was generated 
    KeyInfoFactory kif = fac.getKeyInfoFactory(); 
    KeyValue kv = kif.newKeyValue(kp.getPublic()); 

    // Create a KeyInfo and add the KeyValue to it 
    KeyInfo ki = kif.newKeyInfo(Collections.singletonList(kv)); 

    // Instantiate the document to be signed 
    DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance(); 
    dbf.setNamespaceAware(true); 
    Document doc = dbf.newDocumentBuilder().parse(new FileInputStream(sourceFile)); 

    // Create a DOMSignContext and specify the DSA PrivateKey and 
    // location of the resulting XMLSignature's parent element 
    DOMSignContext dsc = new DOMSignContext(kp.getPrivate(), doc.getDocumentElement()); 
    dsc.setDefaultNamespacePrefix("dsig"); 

    // Create the XMLSignature (but don't sign it yet) 
    XMLSignature signature = fac.newXMLSignature(si, ki); 

    // Marshal, generate (and sign) the enveloped signature 
    signature.sign(dsc); 

    // output the resulting document 
    OutputStream os; 
    os = new FileOutputStream(DestinationFile); 

    TransformerFactory tf = TransformerFactory.newInstance(); 
    Transformer trans = tf.newTransformer(); 
    trans.transform(new DOMSource(doc), new StreamResult(os)); 
-1

Chuỗi algoritmo = XMLSignature.ALGO_ID_SIGNATURE_RSA; XMLSignature sig = new XMLSignature(doc, algoritmo);

-1

Nếu bạn muốn có XML ký của bạn ở dưới dạng

<ds:Signature ...> ... </ds:Signature> 

Sau đó, vui lòng sử dụng java 6 phiên bản 31 và bạn sẽ cần các ký XML.