我如何签名xml文件的哈希并将签名集成到原始文件中 [英] How can i sign hash of xml file and integrate signature in original file

查看:110
本文介绍了我如何签名xml文件的哈希并将签名集成到原始文件中的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

是否可以对xml文件的哈希进行签名,然后将该签名的哈希集成到原始文件中。

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

对于PDF签名,我使用iText,并且效果很好。

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

更新1:对原始XML文件进行签名

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));
}
}

我要做的是计算原始XML文件的哈希,将其发送给另一个服务器(B)进行签名,该服务器将对哈希进行签名并返回已签名的哈希,然后将其集成到服务器A中的原始文件中。

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.

推荐答案

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

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));




KeyValue与公钥等效。代码很简单:

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));




注意:每个元素必须使用XML签名结果才能规范签名和算法。

在创建了有效的XML数字签名后,它看起来像这样:

Upon a valid XML digital signature created, it looks like this:



<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签名应满足以下要求:

A pristine XML signature shall meet below requirements :


  • 签名元素未被操纵

  • 摘要方法|价值|算法应在规范化,加密和解密阶段之间匹配

将其放入上下文中,直接解码密钥字节并在App服务器上发送哈希的方法相当失败安全签名收据的目的。有一些选项可用于支持DS验证,减轻风险(更改文档结构)并通过Java API防止签名被拒绝:

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:


  • 启用安全的签名过程,该过程可能会限制XSLT转换文件|

  • 汇总安全属性以实施限制。例如增加了用于验证的XML签名密钥长度。
    在NoSQL /文档存储领域(例如MarkLogic),有一些复杂的安全功能可用来探索和保护PII数据:元素安全性,SSL签名证书,文档编辑。

除非原始文档,公共密钥和签名都同时遭到破坏,否则Java crypto API将检测到篡改。可以轻松地对核心签名(标题|值|键值)或参考元素进行编组,然后进行验证。

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.



我的要旨应用程序是:生成密钥对,使用私钥和XML签名节点创建XML DOM符号上下文 DOM签名工厂,使用摘要算法引用封装/转换后的文档,然后规范化上述引用,最后创建RSA keyvalue / keyinfo并签署XML。逻辑是Oracle Java XMLSignatureFactory 的具体实现。 KeyInfoFactory 符合 W3C XML所需的算法。

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.



  • 因为尽管我鼓励创造性思维,但(我不想双关语)我并不热衷于签名并扔 hash 。 (可以想象它具有一定的美感:移动通信中的密码短消息……等)。我看不到如何散列重量级的XML。

  • 第二,在开发并插入X509转换和算法时,获取Keyvalue / keyinfo至关重要。我问是否已检索到正确的键值/信息。

  • 第三,您是通过什么上下文指定 DOM 签名实例并创建的引用?

  • 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?


这篇关于我如何签名xml文件的哈希并将签名集成到原始文件中的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆