如何签署XML文件的哈希值并将签名集成到原始文件中。

huangapple go评论74阅读模式
英文:

How can i sign hash of xml file and integrate signature in original file

问题

以下是您要翻译的内容:

"Is there a way to sign the hash of an xml file and then integrate this signed hash into the original file.

For the PDF signature I use iText and it works very well.

UPDATE 1 : Sign Original XML FILE

public class SignXML {

static String fileToSign = "B:/tmp/client/032936.xml";
static String signedFile = "B:/tmp/client/Signed-032936.xml";
static String certificate = "C:/lp7command/tools/certificate.p12";
static String password = "123456";

public static void main(String[] args) throws Exception{
    XMLSignatureFactory fac = XMLSignatureFactory.getInstance("DOM");       
    Transform exc14nTranform = fac.newTransform("http://www.w3.org/TR/2001/REC-xml-c14n-20010315", 
        (TransformParameterSpec) null);
    Transform envTransform = fac.newTransform(Transform.ENVELOPED, (TransformParameterSpec) null);

    List<Transform> transformList = new ArrayList();
    transformList.add(exc14nTranform);
    transformList.add(envTransform);

    Reference ref = fac.newReference("#evidence", fac.newDigestMethod(DigestMethod.SHA1, null), transformList,null, null);

    SignedInfo si = fac.newSignedInfo(fac.newCanonicalizationMethod(CanonicalizationMethod.INCLUSIVE,
        (C14NMethodParameterSpec) null),fac.newSignatureMethod(SignatureMethod.RSA_SHA1, null), Collections.singletonList(ref));

    KeyStore ks = KeyStore.getInstance("PKCS12");
    ks.load(new FileInputStream(certificate), password.toCharArray());
    KeyStore.PrivateKeyEntry keyEntry = (KeyStore.PrivateKeyEntry) ks.getEntry ("mykey", 
        new KeyStore.PasswordProtection(password.toCharArray()));     
    X509Certificate cert = (X509Certificate) keyEntry.getCertificate();

    KeyInfoFactory kif = fac.getKeyInfoFactory();
    List x509Content = new ArrayList();

    X509IssuerSerial issuer = kif.newX509IssuerSerial(cert.getIssuerDN().toString(), cert.getSerialNumber());
    //System.out.println(cert.getSubjectAlternativeNames().toString());
    x509Content.add(cert.getSubjectX500Principal().getName());
    x509Content.add(issuer);
    x509Content.add(cert);

    X509Data xd = kif.newX509Data(x509Content);
    KeyInfo ki = kif.newKeyInfo(Collections.singletonList(xd));

    DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
    dbf.setNamespaceAware(true);
    Document doc = dbf.newDocumentBuilder().parse(new FileInputStream(fileToSign));
    XMLStructure content = new DOMStructure(doc.getDocumentElement());
    
    XMLObject obj = fac.newXMLObject(Collections.singletonList(content), "evidence", null, null);

    DOMSignContext dsc = new DOMSignContext(keyEntry.getPrivateKey(), doc);
    XMLSignature signature = fac.newXMLSignature(si, ki, Collections.singletonList(obj), null, null);
    
    signature.sign(dsc);

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

}

what I want to do is calculate the hash of the original XML file and send it for signature to another server (B) which will sign the hash and return signed hash which I will then integrate into the original file which is in server A."

英文:

Is there a way to sign the hash of an xml file and then integrate this signed hash into the original file.

For the PDF signature I use iText and it works very well.

UPDATE 1 : Sign Original XML FILE

public class SignXML {

static String fileToSign = "B:/tmp/client/032936.xml";
static String signedFile = "B:/tmp/client/Signed-032936.xml";
static String certificate = "C:/lp7command/tools/certificate.p12";
static String password = "123456";

public static void main(String[] args) throws Exception{
	XMLSignatureFactory fac = XMLSignatureFactory.getInstance("DOM");       
	Transform exc14nTranform = fac.newTransform("http://www.w3.org/TR/2001/REC-xml-c14n-20010315", 
			(TransformParameterSpec) null);
	    Transform envTransform = fac.newTransform(Transform.ENVELOPED, (TransformParameterSpec) null);

	    List<Transform> transformList = new ArrayList();
	    transformList.add(exc14nTranform);
	    transformList.add(envTransform);

	    Reference ref = fac.newReference("#evidence", fac.newDigestMethod(DigestMethod.SHA1, null), transformList,null, null);

	    SignedInfo si = fac.newSignedInfo(fac.newCanonicalizationMethod(CanonicalizationMethod.INCLUSIVE,
	    		(C14NMethodParameterSpec) null),fac.newSignatureMethod(SignatureMethod.RSA_SHA1, null), Collections.singletonList(ref));

	    KeyStore ks = KeyStore.getInstance("PKCS12");
	    ks.load(new FileInputStream(certificate), password.toCharArray());
	    KeyStore.PrivateKeyEntry keyEntry = (KeyStore.PrivateKeyEntry) ks.getEntry ("mykey", 
	    		new KeyStore.PasswordProtection(password.toCharArray()));     
	    X509Certificate cert = (X509Certificate) keyEntry.getCertificate();

	    KeyInfoFactory kif = fac.getKeyInfoFactory();
	    List x509Content = new ArrayList();

	    X509IssuerSerial issuer = kif.newX509IssuerSerial(cert.getIssuerDN().toString(), cert.getSerialNumber());
	    //System.out.println(cert.getSubjectAlternativeNames().toString());
	    x509Content.add(cert.getSubjectX500Principal().getName());
	    x509Content.add(issuer);
	    x509Content.add(cert);

	    X509Data xd = kif.newX509Data(x509Content);
	    KeyInfo ki = kif.newKeyInfo(Collections.singletonList(xd));

	    DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
	    dbf.setNamespaceAware(true);
	    Document doc = dbf.newDocumentBuilder().parse(new FileInputStream(fileToSign));
	    XMLStructure content = new DOMStructure(doc.getDocumentElement());
	    
	    XMLObject obj = fac.newXMLObject(Collections.singletonList(content), "evidence", null, null);

	    DOMSignContext dsc = new DOMSignContext(keyEntry.getPrivateKey(), doc);
	    XMLSignature signature = fac.newXMLSignature(si, ki, Collections.singletonList(obj), null, null);
	    
	    signature.sign(dsc);

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

what I want to do is calculate the hash of the original XML file and send it for signature to another server (B) which will sign the hash and return signed hash which I will then integrate into the original file which is in server A.

答案1

得分: 1

Yes there is a way to do that. Have a look at, for example, https://www.w3.org/TR/xmldsig-core/ for (one) standard way to do that. Depending on your technology, there are several libraries that can support you with that. You mentioned iText, so for Java, it is integrated into the JRE for a while now. See https://docs.oracle.com/en/java/javase/13/docs/api/java.xml.crypto/javax/xml/crypto/dsig/package-summary.html as a starting point.

You are looking for an enveloped XML-Signature, where the Signature is not included in hash calculation, so that it can be included in the original document.

UPDATE 1: So you are looking to include a remote signing service into XML documents. That is also possible, I did that on a previous job, though it's a bit more complicated.

In general, you have to plug in where the signature is created, get the hash, send it to the server, get the signature value, and include it into the respective XML node.

Then and there we provided our own Java Crypto Provider, (https://docs.oracle.com/javase/8/docs/technotes/guides/security/crypto/HowToImplAProvider.html) which would override the Private Key Object to perform the remote signing magic. In retrospect, I would rather recommend looking into Apache Santuario http://santuario.apache.org/, which might be a bit more flexible when extending, or the EU-DSS library https://ec.europa.eu/cefdigital/DSS/webapp-demo/doc/dss-documentation.html#_other_implementations.

英文:

Yes there is a way to do that. Have a look at for example https://www.w3.org/TR/xmldsig-core/ at (one) standard way to that. Depending on your technology there are several libraries that support you with that. You mentioned iText, so for Java it is integrated in the JRE for a while now. See https://docs.oracle.com/en/java/javase/13/docs/api/java.xml.crypto/javax/xml/crypto/dsig/package-summary.html as a starting point.

You are looking for an enveloped XML-Signature, where the Signature is not included in hash calculation, so that it can be included in the original document.

UPDATE 1: So you are looking for including a remote signing service into xml documents. That is also possible, did that on a previous job, though a bit more complicated.

In general you have to plug in where the signature is created, get the hash, send it to server get the signature value and include it into the respective XML node.

Then and there we provided our own Java Crypto Provider, (https://docs.oracle.com/javase/8/docs/technotes/guides/security/crypto/HowToImplAProvider.html) which would override the Private Key Object to do the remote signing magic. In retrospect I would rather recommend looking into Apache Santuario http://santuario.apache.org/, which might be a bit more flexible, when extending or the EU-DSS library https://ec.europa.eu/cefdigital/DSS/webapp-demo/doc/dss-documentation.html#_other_implementations.

答案2

得分: 1

以下是您要翻译的内容:

"The short answer is you can check my repo: https://github.com/chenhuang511/xml-dsig-sign-hash/blob/main/src/main/java/vn/softdreams/xml/signhash/HashOperator.java

The long answer is you have to create the signed XML manually, step by step with Java built-in XML library:

Firstly, you prepare the content of the XML Signature tag, as it can be done in the way you sign the whole file directly. The key point is the SignatureValue tag is empty at this step, we can fulfill it later. You must define manually the hash algorithm, the XML transform algorithm inside the content of SignedInfo tag:

//signedInfo node
Element signedInfo = doc.createElement("SignedInfo");
//signedInfo-canonicalizationMethod node
Element canonicalizationMethod = doc.createElement("CanonicalizationMethod");
canonicalizationMethod.setAttribute("Algorithm", usingNS ? "http://www.w3.org/2001/10/xml-exc-c14n#" : "http://www.w3.org/TR/2001/REC-xml-c14n-20010315");
signedInfo.appendChild(canonicalizationMethod);
//signedInfo-SignatureMethod node
Element signatureMethod = doc.createElement("SignatureMethod");
signatureMethod.setAttribute("Algorithm", hashAlgo.getSignatureMethod());
signedInfo.appendChild(signatureMethod);

//SignedInfo-Reference node
Element reference = doc.createElement("Reference");
reference.setAttribute("URI", "#" + signingTagId);
signedInfo.appendChild(reference);
Element transforms = doc.createElement("Transforms");
Element transform1 = doc.createElement("Transform");
transform1.setAttribute("Algorithm", "http://www.w3.org/2000/09/xmldsig#enveloped-signature");
transforms.appendChild(transform1);
if (usingNS) {
Element transform2 = doc.createElement("Transform");
transform2.setAttribute("Algorithm", "http://www.w3.org/2001/10/xml-exc-c14n#");
transforms.appendChild(transform2);
}

reference.appendChild(transforms);

Element digestMethod = doc.createElement("DigestMethod");
digestMethod.setAttribute("Algorithm", hashAlgo.getHashMethod());
reference.appendChild(digestMethod);

Element digestValue = doc.createElement("DigestValue");
digestValue.setTextContent(getDigestForRemote());
reference.appendChild(digestValue);
signedInfo.appendChild(reference);
sigElement.appendChild(signedInfo);

//signatureValue node (empty right now)
Element signatureValue = doc.createElement("SignatureValue");
sigElement.appendChild(signatureValue);

The DigestValue can be calculated by getting the whole node value you want to sign. This node often presents in the document with the given signing node id.

private String getDigestForRemote() throws Exception {
Node nodeToBeHash = inputDoc.getElementsByTagName(signingTagName).item(0);

//transform
Canonicalizer c14n = usingNS ?
        Canonicalizer.getInstance(Canonicalizer.ALGO_ID_C14N_EXCL_OMIT_COMMENTS) : Canonicalizer.getInstance(Canonicalizer.ALGO_ID_C14N_OMIT_COMMENTS);
byte[] transformed = c14n.canonicalizeSubtree(nodeToBeHash);

//hash
return Base64.getEncoder().encodeToString(DigestCreator.digest(transformed, hashAlgo));

}

Next step, when the SignedInfo is done, the hash for signing is calculated by transform and create the digest of SignedInfo content. Remember you have to use algorithms you defined in 1st step for canonicalization and hash operation.

Node signedInfo = signature.getElementsByTagName("SignedInfo").item(0);
Element signedInfoEle = (Element) doc.importNode((Element) signedInfo, true);
signedInfoEle.setAttribute("xmlns", "http://www.w3.org/2000/09/xmldsig#");
doc.appendChild(signedInfoEle);

//transform
Canonicalizer c14n = Canonicalizer.getInstance(Canonicalizer.ALGO_ID_C14N_OMIT_COMMENTS);
byte[] transformed = c14n.canonicalizeSubtree(doc);
//hash
byte[] hash = DigestCreator.digest(transformed, hashAlgo);

Another key point is when you compute the signature from the hash in Java, you may need to add Digest Info into the hash if you want the final XML document can be validated correctly.

public byte[] signHashWithInfo(byte[] hash, PrivateKey privateKey, DigestAlgorithm algo) throws Exception {
Provider provider = new BouncyCastleProvider();
Security.addProvider(provider);

    ASN1ObjectIdentifier oidObject = new ASN1ObjectIdentifier(algo.getOid());

    AlgorithmIdentifier identifier = new AlgorithmIdentifier(oidObject, null);
    DigestInfo di = new DigestInfo(identifier, hash);

    Cipher cipher = Cipher.getInstance("RSA/ECB/PKCS1Padding", provider);
    cipher.init(Cipher.ENCRYPT_MODE, privateKey);
    return cipher.doFinal(di.getEncoded());
}

"

英文:

The short answer is you can check my repo: https://github.com/chenhuang511/xml-dsig-sign-hash/blob/main/src/main/java/vn/softdreams/xml/signhash/HashOperator.java

The long answer is you have to create the signed XML manually, step by step with Java built-in XML library:

Firstly, you prepare the content of the XML Signature tag, as it can be done in the way you sign the whole file directly. The key point is the SignatureValue tag is empty at this step, we can fulfill it later. You must define manually the hash algorithm, the XML transform algorithm inside the content of SignedInfo tag:

        //signedInfo node
    Element signedInfo = doc.createElement("SignedInfo");
    //signedInfo-canonicalizationMethod node
    Element canonicalizationMethod = doc.createElement("CanonicalizationMethod");
    canonicalizationMethod.setAttribute("Algorithm", usingNS ? "http://www.w3.org/2001/10/xml-exc-c14n#" : "http://www.w3.org/TR/2001/REC-xml-c14n-20010315");
    signedInfo.appendChild(canonicalizationMethod);
    //signedInfo-SignatureMethod node
    Element signatureMethod = doc.createElement("SignatureMethod");
    signatureMethod.setAttribute("Algorithm", hashAlgo.getSignatureMethod());
    signedInfo.appendChild(signatureMethod);

    //SignedInfo-Reference node
    Element reference = doc.createElement("Reference");
    reference.setAttribute("URI", "#" + signingTagId);
    signedInfo.appendChild(reference);
    Element transforms = doc.createElement("Transforms");
    Element transform1 = doc.createElement("Transform");
    transform1.setAttribute("Algorithm", "http://www.w3.org/2000/09/xmldsig#enveloped-signature");
    transforms.appendChild(transform1);
    if (usingNS) {
        Element transform2 = doc.createElement("Transform");
        transform2.setAttribute("Algorithm", "http://www.w3.org/2001/10/xml-exc-c14n#");
        transforms.appendChild(transform2);
    }

    reference.appendChild(transforms);

    Element digestMethod = doc.createElement("DigestMethod");
    digestMethod.setAttribute("Algorithm", hashAlgo.getHashMethod());
    reference.appendChild(digestMethod);
    
    Element digestValue = doc.createElement("DigestValue");
    digestValue.setTextContent(getDigestForRemote());
    reference.appendChild(digestValue);
    signedInfo.appendChild(reference);
    sigElement.appendChild(signedInfo);

    //signatureValue node (empty right now)
    Element signatureValue = doc.createElement("SignatureValue");
    sigElement.appendChild(signatureValue);

The DigestValue can be calculated by getting the whole node value you want to sign. This node often presents in the document with the given signing node id.

private String getDigestForRemote() throws Exception {
    Node nodeToBeHash = inputDoc.getElementsByTagName(signingTagName).item(0);

    //transform
    Canonicalizer c14n = usingNS ?
            Canonicalizer.getInstance(Canonicalizer.ALGO_ID_C14N_EXCL_OMIT_COMMENTS) : Canonicalizer.getInstance(Canonicalizer.ALGO_ID_C14N_OMIT_COMMENTS);
    byte[] transformed = c14n.canonicalizeSubtree(nodeToBeHash);

    //hash
    return Base64.getEncoder().encodeToString(DigestCreator.digest(transformed, hashAlgo));
}

Next step, when the SignedInfo is done, the hash for signing is calculated by transform and create the digest of SignedInfo content. Remember you have to use algorithms you defined in 1st step for canonicalization and hash operation.

Node signedInfo = signature.getElementsByTagName("SignedInfo").item(0);
    Element signedInfoEle = (Element) doc.importNode((Element) signedInfo, true);
    signedInfoEle.setAttribute("xmlns", "http://www.w3.org/2000/09/xmldsig#");
    doc.appendChild(signedInfoEle);

    //transform
    Canonicalizer c14n = Canonicalizer.getInstance(Canonicalizer.ALGO_ID_C14N_OMIT_COMMENTS);
    byte[] transformed = c14n.canonicalizeSubtree(doc);
    //hash
    byte[] hash = DigestCreator.digest(transformed, hashAlgo);

Another key point is when you compute the signature from the hash in Java, you may need to add Digest Info into the hash if you want the final XML document can be validated correctly.

public byte[] signHashWithInfo(byte[] hash, PrivateKey privateKey, DigestAlgorithm algo) throws Exception {
        Provider provider = new BouncyCastleProvider();
        Security.addProvider(provider);

        ASN1ObjectIdentifier oidObject = new ASN1ObjectIdentifier(algo.getOid());

        AlgorithmIdentifier identifier = new AlgorithmIdentifier(oidObject, null);
        DigestInfo di = new DigestInfo(identifier, hash);

        Cipher cipher = Cipher.getInstance("RSA/ECB/PKCS1Padding", provider);
        cipher.init(Cipher.ENCRYPT_MODE, privateKey);
        return cipher.doFinal(di.getEncoded());
    }

答案3

得分: 0

XML数字签名是标准的Java API,与传统的摘要|加密|解密哈希值的方法不同。要点是首先要规范化|引用(URI)|嵌入签名算法,然后接收者验证引用签名

> 从您的代码中成功创建了KeyValue吗?

List x509Content = new ArrayList();

X509IssuerSerial issuer = kif.newX509IssuerSerial(cert.getIssuerDN().toString(), cert.getSerialNumber());
//System.out.println(cert.getSubjectAlternativeNames().toString());
x509Content.add(cert.getSubjectX500Principal().getName());
x509Content.add(issuer);
x509Content.add(cert);

X509Data xd = kif.newX509Data(x509Content);
KeyInfo ki = kif.newKeyInfo(Collections.singletonList(xd));

>> KeyValue等效于公钥。代码如下所示:

KeyInfoFactory kif = fac.getKeyInfoFactory();
KeyValue kv = kif.newKeyValue(kp.getPublic());

// 将值包装在KeyInfo中
KeyInfo ki = kif.newKeyInfo(List.of(kv));

>> 注意:XML签名结果的每个元素都需要规范化签名和算法。
>>
>> 有效的XML数字签名如下所示:

<national-treasure>
.......
    </Banff-highlights>
    <Banff-revenue>CAD$6 billion per annum</Banff-revenue>
<Signature xmlns="http://www.w3.org/2000/09/xmldsig#">
    <SignedInfo>
        <CanonicalizationMethod Algorithm="http://www.w3.org/TR/2001/REC-xml-c14n-20010315#WithComments"/>
        <SignatureMethod Algorithm="http://www.w3.org/2001/04/xmldsig-more#rsa-sha256"/>
        <Reference URI="">
            <Transforms>
                <Transform Algorithm="http://www.w3.org/2000/09/xmldsig#enveloped-signature"/>
            </Transforms>
            <DigestMethod Algorithm="http://www.w3.org/2001/04/xmlenc#sha256"/>
            <DigestValue>3tiwE7fdQxZ.....lU99kmkHAg/Bi6fESM=</DigestValue>
        </Reference>
    </SignedInfo>
    <SignatureValue>AZMlxFBjoZxmy8.....YOO3qINqG/wHoJPg==</SignatureValue>
    <KeyInfo>
        <KeyValue>
            <RSAKeyValue>
                <Modulus>sLQ+W9fT18Okqf.....tQ==</Modulus>
                <Exponent>AQAB</Exponent>
            </RSAKeyValue>
        </KeyValue>
    </KeyInfo>
</Signature>
</national-treasure>

> 一个完整的XML签名应满足以下要求:
> > - 签名的元素未被篡改
> > - 规范化、加密和解密阶段的摘要方法、值和算法应匹配
> >
> > 在这个背景下,直接解码密钥字节并将哈希发送到应用服务器,会大大削弱安全签名接收的目的。通过Java API,有多种选项来强化数字签名验证,减轻风险(更改文档结构),并防止签名否认:
>> - 启用安全签名过程,可以限制应用服务器中的XSLT转换文档和交叉引用URI。
>> - 聚合安全属性以强制执行限制。例如,增加XML签名密钥长度以进行验证。
>> 在NoSQL/文档存储领域,如MarkLogic,有许多复杂的安全功能可供探索,以保护个人身份信息数据:元素安全性、SSL签名证书、文档消除等。

>
> 除非原始文档、公钥和签名同时遭到破坏,否则Java加密API将检测到篡改。核心签名(标头|值|密钥值)或引用元素可以轻松解组然后验证。

> 我的应用程序要点是:生成密钥对,使用私钥和XML签名节点创建XML DOM签名上下文;使用摘要算法引用已包装/转换的文档的DOM签名工厂,然后规范化上述引用,最后创建RSA keyvalue/keyinfo并对XML进行签名。这个逻辑是Oracle Java XMLSignatureFactory | KeyInfoFactory的具体实现,符合W3C XML所需的算法。
>> - 尽管我鼓励创造性思考,(无恶意)我不太愿意签名并将哈希丢掉(可能在移动通信中有一定的美感:加密短信等)。我不明白如何对重量级XML进行哈希。
>> - 第二,当您开发并插入X509转换和算法时,正确的keyvalue/keyinfo是否已经检索到?
>> - 第三,您是通过什么上下文指定的DOM签名实例并创建引用?

英文:

XML digital signature is the standard Java API which is different from the classic method of digesting | encrypting | decrypting hash value. The gist is first to canonicalize | reference(URI) | embed the signature algorithm and then receiver verifies both reference and signature.

> Is the KeyValue successfully created from the Array in your codes?

        List x509Content = new ArrayList();

        X509IssuerSerial issuer = kif.newX509IssuerSerial(cert.getIssuerDN().toString(), cert.getSerialNumber());
        //System.out.println(cert.getSubjectAlternativeNames().toString());
        x509Content.add(cert.getSubjectX500Principal().getName());
        x509Content.add(issuer);
        x509Content.add(cert);

        X509Data xd = kif.newX509Data(x509Content);
        KeyInfo ki = kif.newKeyInfo(Collections.singletonList(xd));

>> The KeyValue is the equivalent of a Public Key. The code is as simple as:

	        KeyInfoFactory kif = fac.getKeyInfoFactory();
	        KeyValue kv = kif.newKeyValue(kp.getPublic());

	        // wrap the value in the KeyInfo
 	        KeyInfo ki = kif.newKeyInfo(List.of(kv));

>> NOTE: Each element of the XML signature result is required to canonicalise the signature and algorithm.
>>
>> Upon a valid XML digital signature created, it looks like this:

&lt;national-treasure&gt;
.......
    &lt;/Banff-highlights&gt;
      &lt;Banff-revenue&gt;CAD$6 billion per annum
    &lt;/Banff-revenue&gt;
&lt;Signature xmlns=&quot;http://www.w3.org/2000/09/xmldsig#&quot;&gt;
    &lt;SignedInfo&gt;
        &lt;CanonicalizationMethod Algorithm=&quot;http://www.w3.org/TR/2001/REC-xml-c14n-20010315#WithComments&quot;/&gt;
        &lt;SignatureMethod Algorithm=&quot;http://www.w3.org/2001/04/xmldsig-more#rsa-sha256&quot;/&gt;
        &lt;Reference URI=&quot;&quot;&gt;
            &lt;Transforms&gt;
                &lt;Transform Algorithm=&quot;http://www.w3.org/2000/09/xmldsig#enveloped-signature&quot;/&gt;
            &lt;/Transforms&gt;
            &lt;DigestMethod Algorithm=&quot;http://www.w3.org/2001/04/xmlenc#sha256&quot;/&gt;
            &lt;DigestValue&gt;3tiwE7fdQxZ.....lU99kmkHAg/Bi6fESM=&lt;/DigestValue&gt;
        &lt;/Reference&gt;
    &lt;/SignedInfo&gt;
    &lt;SignatureValue&gt;AZMlxFBjoZxmy8.....YOO3qINqG/wHoJPg==
    &lt;/SignatureValue&gt;
    &lt;KeyInfo&gt;
        &lt;KeyValue&gt;
            &lt;RSAKeyValue&gt;
                &lt;Modulus&gt;sLQ+W9fT18Okqf.....tQ==
                &lt;/Modulus&gt;
                &lt;Exponent&gt;AQAB&lt;/Exponent&gt;
            &lt;/RSAKeyValue&gt;
        &lt;/KeyValue&gt;
    &lt;/KeyInfo&gt;
&lt;/Signature&gt;
&lt;/national-treasure&gt;

> A pristine XML signature shall meet below requirements :
> > - Signed element has not been manipulated
> > - Digest method | value | algorithm shall match among canonicalized, encrypt and decrypt stages
> >
> > Put that into context, the method of direct decoding key bytes and sending hash over the App servers quite defeats the purpose of secure signature receipt. There are options to buttress DS validation, mitigate risks(alter document construct), and prevent signature repudiation through Java API:
>> - Enable secure Signature process which can restrict XSLT transforms document | cross reference URI in App server.
>> - Aggregate security property to enforce restrictions. e.g. increased XML signature key length for validation.
>> In the realm of NoSQL/document store, like MarkLogic, there are sophisticated security features to explore and to protect PII data: element security, SSL signed certificates, document redaction.
>
> Unless the original document, public key and signature are ALL compromised the same time, Java crypto API shall detect the tampering. Core signature (header |value | key value) or reference element can be effortlessly unmarshalled then validated.

> The gist of my application is: Generate the keypair, create XML DOM sign context with the private key and XML signed node; DOM signature factory, referencing the enveloped/transformed document with the digested algorithm, then canonicalized the aforesaid reference, finally create the RSA keyvalue/keyinfo and sign the XML. The logic is the concrete implementation of Oracle Java XMLSignatureFactory | KeyInfoFactory which conforms to W3C XML required algorithms.
> > - For although I encourage creative thinking, (No pun intended) I am not keen to sign and toss the hash. ( conceivably it has certain beauty: Cipher short message in mobile communication…etc ). I don’t see how you can hash a heavy-weight XML.
> > - 2ndly, it is critical to get the Keyvalue/keyinfo when you develop and plug in X509 transform and algorithm. I ask if the correct keyvalue/info has been retrieved.
> > - 3rdly, by what context did you specify the DOM signature instance and create the reference?

huangapple
  • 本文由 发表于 2020年8月3日 19:49:28
  • 转载请务必保留本文链接:https://go.coder-hub.com/63228884.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定