XML数字安全 - Hmac_SHA1

时间:2015-07-29 15:32:56

标签: digital-signature digest

我需要为以下输入

创建一个摘要值
<u:Timestamp u:Id="_0" xmlns:u="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd">
    <u:Created>2015-07-28T13:35:54Z</u:Created>
    <u:Expires>2015-07-28T13:40:49Z</u:Expires>
</u:Timestamp>

所以我将上述值作为doc obj传递给下面的代码

public static void main(String[] args) throws Exception {

    // Create a DOM XMLSignatureFactory that will be used to generate the
    // enveloped signature
    XMLSignatureFactory fac = XMLSignatureFactory.getInstance("DOM");
    SecretKey signingKey = new SecretKeySpec("welcome1".getBytes(), "HMAC");
    // Create a Reference to the enveloped document (in this case we are
    // signing the whole document, so a URI of "" signifies that) and
    // also specify the SHA1 digest algorithm and the ENVELOPED Transform.

    Reference ref = fac.newReference
        ("#_0", fac.newDigestMethod(DigestMethod.SHA1, null),
         Collections.singletonList
          (fac.newTransform
            ("http://www.w3.org/2001/10/xml-exc-c14n#", (TransformParameterSpec) null)),
         null, null);

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


    // Instantiate the document to be signed
    DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
    dbf.setNamespaceAware(true);
    Document doc =
        dbf.newDocumentBuilder().parse(new FileInputStream("C:/Users/Signed_Encryp/timestamp.txt"));

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

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

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

    // output the resulting document
    OutputStream os;
    if (args.length > 1) {
       os = new FileOutputStream(args[1]);
    } else {
       os = System.out;
    }

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

将结果作为

返回给我
<u:Timestamp xmlns:u="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd" u:Id="_0">
    <u:Created>2015-07-28T13:35:54Z</u:Created>
    <u:Expires>2015-07-28T13:40:49Z</u:Expires>
    <ds:Signature xmlns:ds="http://www.w3.org/2000/09/xmldsig#">
        <ds:SignedInfo>
            <ds:CanonicalizationMethod Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#"/>
            <ds:SignatureMethod Algorithm="http://www.w3.org/2000/09/xmldsig#hmac-sha1"/>
            <ds:Reference URI="#_0">
                <ds:Transforms>
                    <ds:Transform Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#"/>
                </ds:Transforms>
                <ds:DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1"/>
                <ds:DigestValue>1X/3X+yCdJc0x3n8guQnlCFvX+s=</ds:DigestValue>
            </ds:Reference>
        </ds:SignedInfo>
        <ds:SignatureValue>R4ZrHvlvyGvvQYpojZWPgUgRRSw=</ds:SignatureValue>
    </ds:Signature>
</u:Timestamp>

这里不确定使用传递的输入创建摘要值,还是在timestamp标记内创建签名,是否有任何选项可用于在timestamp标记之后创建签名标记。

请帮忙

1 个答案:

答案 0 :(得分:0)

要检查签名是否在数据上,只需更改数据并使用相同的密钥。如果HMAC值发生变化,则散列明显超过数据。更改后,它应返回旧值。请注意,这对于HMAC-SHA1来说是正确的,它可能是所有基元(例如RSA-PSS)的情况。

或者,如果您达到目的,您可以自己执行规范化并手动计算签名。或尝试其他实施。

如果u:Timestamp是根元素,那么就不能在它旁边添加任何内容,因为XML只有一个根元素。您已经表明签名位于doc.getDocumentElement()。但是,您可以创建分离的签名。现在你知道它是如何调用的,你应该能够搜索它。