Проблема:
Проверка подписи XML не удалась, и возникла ошибка, указывающая, что значения дайджеста не соответствуют вычисленным значениям. Оба значения DigestValue и SignatureValue закодированы в формате Base64, и я позаботился о том, чтобы процесс подписи соответствовал стандартным методам канонизации XML (C14N).
Вот соответствующая часть моего кода подписи:
Код: Выделить всё
public class SignXmlService {
private KeyStoreService keystoreService;
public SignXmlService(KeyStoreService keystoreService) {
this.keystoreService = keystoreService;
}
public String signXMLString(Document document)
throws GeneralSecurityException, MarshalException, XMLSignatureException, TransformerException {
PrivateKey privateKey = keystoreService.getPrivateKey();
X509Certificate x509Certificate = (X509Certificate) keystoreService.getCertificate();
System.setProperty("org.apache.xml.security.ignoreLineBreaks", "true");
System.setProperty("com.sun.org.apache.xml.internal.security.ignoreLineBreaks", "true");
String keyInfoId = "_" + UUID.randomUUID().toString();
String signatureId = "_" + UUID.randomUUID().toString();
DOMSignContext dsc = new DOMSignContext(privateKey, document.getDocumentElement());
dsc.setDefaultNamespacePrefix("ds");
XMLSignatureFactory fac = XMLSignatureFactory.getInstance("DOM");
// Canonicalization and Transform methods
Transform envelopedTransform = fac.newTransform(Transform.ENVELOPED, (TransformParameterSpec) null);
Transform c14NEXCTransform = fac.newTransform(CanonicalizationMethod.EXCLUSIVE, (TransformParameterSpec) null);
List transforms = Arrays.asList(envelopedTransform, c14NEXCTransform);
Reference ref = fac.newReference("", fac.newDigestMethod(DigestMethod.SHA256, null), transforms, null, null);
Reference keyInfoRef = fac.newReference(
"#" + keyInfoId,
fac.newDigestMethod(DigestMethod.SHA256, null),
Collections.singletonList(fac.newTransform(CanonicalizationMethod.EXCLUSIVE, (TransformParameterSpec) null)),
null, null);
List refIds = Arrays.asList(ref, keyInfoRef);
SignedInfo si = fac.newSignedInfo(
fac.newCanonicalizationMethod(CanonicalizationMethod.EXCLUSIVE, (C14NMethodParameterSpec) null),
fac.newSignatureMethod(SignatureMethod.RSA_SHA256, null),
refIds);
KeyInfoFactory kif = fac.getKeyInfoFactory();
X509Data x509Data = kif.newX509Data(Arrays.asList(x509Certificate));
KeyInfo ki = kif.newKeyInfo(Collections.singletonList(x509Data), keyInfoId);
XMLSignature signature = fac.newXMLSignature(si, ki, null, signatureId, null);
signature.sign(dsc);
ByteArrayOutputStream output = new ByteArrayOutputStream();
Transformer transformer = TransformerFactory.newInstance().newTransformer();
transformer.setOutputProperty(OutputKeys.ENCODING, UTF_8.name());
transformer.setOutputProperty(OutputKeys.OMIT_XML_DECLARATION, "no");
transformer.transform(new DOMSource(document), new StreamResult(output));
return new String(output.toByteArray());
}
}
Код: Выделить всё
dUo
string
string
2024-09-07
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
< /code>
Шаги, предпринятые для отладки: < /p>
[list]
[*] Я использую SHA-256 для вычисления дигеста и RSA для подписания. < / li>
Я установил системные свойства для обработки разрывов строк/возврата каретки ( ), поскольку подпись XML может содержать проблемы с возвратом каретки. Вот конкретный отрывок, который решает эту проблему.
[/list]
System.setProperty("org.apache.xml.security.ignoreLineBreaks", "true");
System.setProperty("com.sun.org.apache.xml.internal.security.ignoreLineBreaks", "true");
- Канонизация осуществляется с помощью CanonicalizationMethod.EXCLUSIVE.
- Я проверил, что закрытый ключ и сертификат, используемый для подписи, верен.
- Ожидается, что значения DigestValue и SignatureValue будут закодированы в Base64, и я подтвердил, что это обрабатывается службой keyStoreService, которая получает содержимое частного файла в кодировке pem. ключ и сертификат
Буду очень признателен за любую помощь или информацию о том, почему происходит несоответствие дайджеста и как его устранить!< /п>
Подробнее здесь: https://stackoverflow.com/questions/789 ... rrect-this