我使用 java 创建了数字签名
XMLSignatureFactory xmlSignatureFactory = XMLSignatureFactory.getInstance("DOM");
当整个过程完成输出xml包括
签名
检查这个问题时,它发生在换行符。我使用替换方法将其删除。但是当它检查时它给出错误Verifying the digest value for the 1. Reference failed
我尝试使用以下代码创建签名
private String generateEbXml() throws Exception {
// Create a DOM XMLSignatureFactory that will be used to generate the enveloped signature.
XMLSignatureFactory xmlSignatureFactory = XMLSignatureFactory.getInstance("DOM");
List<Reference> references = new ArrayList<>();
DigestMethod digestMethod = xmlSignatureFactory.newDigestMethod(DigestMethod.SHA1, null);
List<Transform> transforms = new LinkedList<>();
Transform envelopedTransform = xmlSignatureFactory.newTransform(CanonicalizationMethod.ENVELOPED,
(TransformParameterSpec) null);
transforms.add(envelopedTransform);
String xpathExpr = "not(ancestor-or-self::eb:TraceHeaderList or ancestor-or-self::eb:Via)";
XPathFilterParameterSpec xpathSpec = new XPathFilterParameterSpec(xpathExpr);
Transform xpathTransform = xmlSignatureFactory.newTransform(CanonicalizationMethod.XPATH, xpathSpec);
transforms.add(xpathTransform);
Transform inclusiveTransform = xmlSignatureFactory.newTransform(CanonicalizationMethod.INCLUSIVE,
(TransformParameterSpec) null);
transforms.add(inclusiveTransform);
Reference wholeDocumentReference = xmlSignatureFactory
.newReference("", digestMethod, transforms, null, null);
String content = new String(Files.readAllBytes(Paths.get(resourceFileLocation.concat("ase2.xml"))));
MessageDigest sha1 = MessageDigest.getInstance("SHA-1");
byte[] hash = sha1.digest(content.getBytes());
Reference aseXmlreference = xmlSignatureFactory
.newReference("cid:aseXML", digestMethod, null, null, null, hash);
references.add(wholeDocumentReference);
references.add(aseXmlreference);
// Create the SignedInfo
SignedInfo signedInfo = xmlSignatureFactory
.newSignedInfo(xmlSignatureFactory
.newCanonicalizationMethod(CanonicalizationMethod.INCLUSIVE,
(C14NMethodParameterSpec) null),
xmlSignatureFactory
.newSignatureMethod(SignatureMethod.RSA_SHA1, null), references);
// Load the KeyStore and get the signing key and certificate.
KeyStore keyStore = KeyStore.getInstance("PKCS12");
//keyStore.load(new FileInputStream("keyStore.p12"), "123456".toCharArray());
keyStore.load(keyStoreFile.getInputStream(), keyStorePassword.toCharArray());
KeyStore.PrivateKeyEntry keyEntry =
(KeyStore.PrivateKeyEntry) keyStore.getEntry
(keyStoreAlias, new KeyStore.PasswordProtection(keyStorePassword.toCharArray()));
X509Certificate x509Certificate = (X509Certificate) keyEntry.getCertificate();
// Create the KeyInfo containing the X509Data.
KeyInfoFactory keyInfoFactory = xmlSignatureFactory.getKeyInfoFactory();
List x509Content = new ArrayList();
x509Content.add(x509Certificate.getSubjectX500Principal().getName());
x509Content.add(x509Certificate);
X509Data x509Data = keyInfoFactory.newX509Data(x509Content);
List<XMLStructure> keyInfoList = new ArrayList<>();
PublicKey publicKey = keyEntry.getCertificate().getPublicKey();
KeyValue keyValue = keyInfoFactory.newKeyValue(publicKey);
keyInfoList.add(keyValue);
keyInfoList.add(x509Data);
KeyInfo keyInfo = keyInfoFactory.newKeyInfo(keyInfoList);
// Instantiate the document to be signed.
DocumentBuilderFactory documentBuilderFactory = DocumentBuilderFactory.newInstance();
// process XML securely, avoid attacks like XML External Entities (XXE)
documentBuilderFactory.setFeature(XMLConstants.FEATURE_SECURE_PROCESSING, true);
documentBuilderFactory.setNamespaceAware(true);
Resource resource = new FileSystemResource(resourceFileLocation.concat("ebxml_without_sign_new.xml"));
Document document = documentBuilderFactory.newDocumentBuilder().parse(resource.getFile());
// Create a DOMSignContext and specify the RSA PrivateKey and
// location of the resulting XMLSignature's header element.
DOMSignContext domSignContext = new DOMSignContext(keyEntry.getPrivateKey(), document.getDocumentElement().getFirstChild());
// Create the XMLSignature, but don't sign it yet.
XMLSignature xmlSignature = xmlSignatureFactory.newXMLSignature(signedInfo, keyInfo, null, "WmEbXML-Signature-54cl6h00gi08isbf003ient2", null);
domSignContext.setURIDereferencer(new EmptyURIDereferencer(document));
// Marshal, generate, and sign the enveloped signature.
xmlSignature.sign(domSignContext);
DOMImplementationLS domImplementationLS = (DOMImplementationLS) document.getImplementation();
LSSerializer lsSerializer = domImplementationLS.createLSSerializer();
LSOutput lsOutput = domImplementationLS.createLSOutput();
lsOutput.setEncoding("UTF-8");
Writer stringWriter = new StringWriter();
lsOutput.setCharacterStream(stringWriter);
lsSerializer.write(document, lsOutput);
String ebxmlContent = stringWriter.toString();
return ebxmlContent;
}
我试过下面的代码删除上面提到的
Field f = XMLUtils.class.getDeclaredField("ignoreLineBreaks");
f.setAccessible(true);
f.set(null, Boolean.TRUE);
但没有任何帮助。
输出如下的xml
<Signature
xmlns="http://www.w3.org/2000/09/xmldsig#" Id="WmEbXML-Signature-54cl6h00gi08isbf003ient2">
<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"/>
<Transform Algorithm="http://www.w3.org/TR/1999/REC-xpath-19991116">
<XPath>not(ancestor-or-self::eb:TraceHeaderList or ancestor-or-self::eb:Via)</XPath>
</Transform>
<Transform Algorithm="http://www.w3.org/TR/2001/REC-xml-c14n-20010315"/>
</Transforms>
<DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1"/>
<DigestValue>2jmj7l5rSw0yVb/vlWAYkK/YBwk=</DigestValue>
</Reference>
<Reference URI="cid:aseXML">
<DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1"/>
<DigestValue>+VwuE6JsSHeCXWC+DPxgjVeJW3s=</DigestValue>
</Reference>
</SignedInfo>
<SignatureValue>aC8ktJUPln/upPXzh1bKOwixJR7MzCPR/fti/Y51hHBGXTH+9YYbfjDYPDoujUwBMPFYiYvW8mwy
SK8hw033Jo2FsG5MzTnLkDWL/iLA48RBADeP0RLh5a4w2bm/6afxBejKPyZsMQI6xZVjYfYhHN66
o873Ut66NA67QYrO3bQ3Pmf6OQZYrghDfYdDcR+UMkBclzUnl7hLe2zk2FUg8ciUghe+mAQTrodr
qfZkGRUuZuk4ApoYuHfTuCVVPuFumnK0cxGpZ+t8F+veuRi8fDmDuj00xtekos0RvveHkXDJV86f
5e3qbF5dFoCT2wAPrI176yZmM2Tj3kU1zxqnDQ==</SignatureValue>
<KeyInfo>
<KeyValue>
<RSAKeyValue>
<Modulus>tEwpS7E66OGOtjRmxF/n2WhRtSG4fX1plZWOMC6muIQKRmNeZ4R1rIhWN9/ApIvnU2s3ydV6EuYx
Xwgg6Dj+rFqLyD4ad5kpe4iValJw6+iUgNsdPXeX4nyzSyjrYwqXBWcJ1PySuVjN4fGI20M/9UBN
6p35N/7SQhkrx9Hrj+y/sIZj33SDLrqw79HeoTbah1aL8V4Ah02tYQi20qRAsyM1dz3czuzCdvA2
flQFlWJsX0NEFFyDfbOEQk6ZbeWYdbSHxYvEjWy0A0EQ2bfBog0A/ulVCMY8VFHVohcVi6+jwmHq
6rFezTKnDeCaY9fL9/1n07CjEOzDvYJp5FlfSw==</Modulus>
<Exponent>AQAB</Exponent>
</RSAKeyValue>
</KeyValue>
<X509Data>
<X509SubjectName>XXX</X509SubjectName>
<X509Certificate>MIIFAzCCA+ugAwIBAgIQD8BrY2+s1N8STrkTMhU63zANBgkqhkiG9w0BAQsFADBcMQswCQYDVQQG
EwJBVTEyMDAGA1UEChMpQXVzdHJhbGlhbiBFbmVyZ3kgTWFya2V0IE9wZXJhdG9yIExpbWl0ZWQx
GTAXBgNVBAMTEEFFTU8tSUNBLVRFU1QgRzEwHhcNMjMwMjE3MDAwMDAwWhcNMjYwMjE1MjM1OTU5
WjBbMQswCQYDVQQGEwJBVTERMA8GA1UECBMIVmljdG9yaWExEjAQBgNVBAcTCU1lbGJvdXJuZTEN
MAsGA1UEChMEQUVNTzEWMBQGA1UEAxMNU1VNTzItUHJlUHJvZDCCASIwDQYJKoZIhvcNAQEBBQAD
ggEPADCCAQoCggEBALRMKUuxOujhjrY0ZsRf59loUbUhuH19aZWVjjAupriECkZjXmeEdayIVjff
wKSL51NrN8nVehLmMV8IIOg4/qxai8g+GneZKXuIlWpScOvolIDbHT13l+J8s0so62MKlwVnCdT8
krlYzeHxiNtDP/VATeqd+Tf+0kIZK8fR64/sv7CGY990gy66sO/R3qE22odWi/FeAIdNrWEIttKk
QLMjNXc93M7swnbwNn5UBZVibF9DRBRcg32zhEJOmW3lmHW0h8WLxI1stANBENm3waINAP7pVQjG
PFRR1aIXFYuvo8Jh6uqxXs0ypw3gmmPXy/f9Z9OwoxDsw72CaeRZX0sCAwEAAaOCAcAwggG8MB8G
A1UdIwQYMBaAFLObeJREzHBITOulhDEDmNo2+ssEMB0GA1UdDgQWBBTYcw2iSBrmnKmkVG6hk2Jv
CVaOUzAYBgNVHREEETAPgg1TVU1PMi1QcmVQcm9kMA4GA1UdDwEB/wQEAwIFoDAdBgNVHSUEFjAU
BggrBgEFBQcDAQYIKwYBBQUHAwIwbQYDVR0fBGYwZDAwoC6gLIYqaHR0cDovL2NybDMuZGlnaWNl
cnQuY29tL0FFTU9JQ0FURVNURzEuY3JsMDCgLqAshipodHRwOi8vY3JsNC5kaWdpY2VydC5jb20v
QUVNT0lDQVRFU1RHMS5jcmwwQQYDVR0gBDowODA2BglghkgBhv1sAQEwKTAnBggrBgEFBQcCARYb
aHR0cDovL3d3dy5kaWdpY2VydC5jb20vQ1BTMHEGCCsGAQUFBwEBBGUwYzAkBggrBgEFBQcwAYYY
aHR0cDovL29jc3AuZGlnaWNlcnQuY29tMDsGCCsGAQUFBzAChi9odHRwOi8vY2FjZXJ0cy5kaWdp
Y2VydC5jb20vQUVNTy1JQ0EtVEVTVEcxLmNydDAMBgNVHRMBAf8EAjAAMA0GCSqGSIb3DQEBCwUA
A4IBAQCrrec8+7laWuMzxvmws/80dtdVKmwTTF/qXFy3k3ONDNqcfQteXjKxH83VFxi9rgKSt07H
G2HWzUnOzK4WSJ4Lwr/Af01Ycxy5zblSzfl/9A0yjgyX9rxFnRYtLYr8EqMXt18N1jdd+YH9L0P8
j+SKfdzm5C1tLTlWV2fKppaE2xjmYw3Bj4g8xG+bhaNR/sFXzp2NApovBjdsfh2BjBw1gXDdSKjh
8OE2/zEW7RcilwjDw8+8vJAEs1XQnc9zU1OiheWSdAjPXhxTtlGmcwKBqo8Gi75rTd2wxk747oIi
SKBjCVsLgdKu12RZGDmvH4vr3a/9P6VkyrHVuM5DGaFC</X509Certificate>
</X509Data>
</KeyInfo>
</Signature>