javaxml数字签名问题
我需要对XML文档进行数字签名。给出的要求是输入是一个XML文件和一个私钥。签名应使用SHA256/RSA-2048,签名应为信封式。我已经想出了下面的方法来做到这一点。在测试中,使用KeyPairGenerator类生成密钥对,RSA作为算法,密钥大小设置为2048。传递的输入流是FileInputStream对象,输出流是FileOutputStream对象。这个方法似乎很有效javaxml数字签名问题,java,encryption,key,digital-signature,xml-signature,Java,Encryption,Key,Digital Signature,Xml Signature,我需要对XML文档进行数字签名。给出的要求是输入是一个XML文件和一个私钥。签名应使用SHA256/RSA-2048,签名应为信封式。我已经想出了下面的方法来做到这一点。在测试中,使用KeyPairGenerator类生成密钥对,RSA作为算法,密钥大小设置为2048。传递的输入流是FileInputStream对象,输出流是FileOutputStream对象。这个方法似乎很有效 public void sign(InputStream inputStream, OutputStream ou
public void sign(InputStream inputStream, OutputStream outputStream, KeyPair kp) throws Exception {
XMLSignatureFactory fac = XMLSignatureFactory.getInstance("DOM");
Reference ref = fac.newReference("#object", fac.newDigestMethod(DigestMethod.SHA256, null));
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
dbf.setNamespaceAware(true);
org.w3c.dom.Document doc = dbf.newDocumentBuilder().parse(inputStream);
XMLStructure content = new DOMStructure(doc.getDocumentElement());
XMLObject obj = fac.newXMLObject(Collections.singletonList(content), "object", null, null);
SignatureMethod signatureMethod = fac.newSignatureMethod("http://www.w3.org/2001/04/xmldsig-more#rsa-sha256", null);
CanonicalizationMethod canonicalizationMethod = fac.newCanonicalizationMethod(CanonicalizationMethod.INCLUSIVE, (C14NMethodParameterSpec)null);
SignedInfo si = fac.newSignedInfo(canonicalizationMethod, signatureMethod, Collections.singletonList(ref));
KeyInfoFactory kif = fac.getKeyInfoFactory();
KeyValue kv = kif.newKeyValue(kp.getPublic());
KeyInfo ki = kif.newKeyInfo(Collections.singletonList(kv));
XMLSignature signature = fac.newXMLSignature(si, ki, Collections.singletonList(obj), null, null);
DOMSignContext dsc = new DOMSignContext(kp.getPrivate(), doc);
signature.sign(dsc);
TransformerFactory tf = TransformerFactory.newInstance();
Transformer trans = tf.newTransformer();
trans.transform(new DOMSource(doc), new StreamResult(outputStream));
}
我有一些问题:
Transform tr = fac.newTransform(CanonicalizationMethod.INCLUSIVE, (TransformParameterSpec) null);
fac.newReference("#object", fac.newDigestMethod(DigestMethod.SHA256, null), Collections.singletonList(tr), null, null);
这段代码将在引用将被散列的#对象的引用中添加一个带有规范化算法的转换
3) 您将在对象元素中拥有与添加到其中的内容完全相同的内容。在计算摘要值之前,将对此内容应用规范化(或任何其他转换)
4) KeyValue是可选的,是签名验证器的提示。通常签名将在X509Certificate中包含证书,而不是键值
希望这有帮助。
Moez我真的不明白你对(2)的回答。调用newReference()方法有什么问题吗?如果我更改此行中的规范化算法:CanonicalizationMethod CanonicalizationMethod=signatureFactory.newCanonicalizationMethod(CanonicalizationMethod.EXCLUSIVE_,带_注释,(C14NMethodParameterSpec)null);我注意到DigestValue仍将保持不变,但SignatureValue将更改。为什么会这样?规范化方法指定了一个规范化算法,该算法将用于在计算签名值之前规范化SignedInfo。对XML blob的摘要值没有影响。我在答案中添加了为XML blob添加规范化算法的方法。当我们进行加密时,我们可以指定模式和填充。例如,RSA/ECB/PKCS1P。对于数字签名,我使用RSA。那么,是否已经内置了默认模式和填充?我们可以指定模式和填充吗?填充和其他参数是URI中隐含的。URI指RFC 3447中描述的RSASSA-PKCS1-v1_5算法(请参阅)。