Генерация подписи XML Java не проходит проверку, как это исправить?JAVA

Программисты JAVA общаются здесь
Anonymous
Генерация подписи XML Java не проходит проверку, как это исправить?

Сообщение Anonymous »

Я работаю над процессом подписи XML на Java, используя пакет javax.xml.crypto.dsig. Моя цель — подписать XML-документ. Хотя подпись успешно сгенерирована, когда я пытаюсь ее проверить, я постоянно сталкиваюсь с проблемой, когда DigestValue и SignatureValue не соответствуют вычисленным значениям во время проверки.
Проблема:
Проверка подписи 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());
}
}
Вот пример XML-сообщения, созданного с использованием приведенного выше кода:

Код: Выделить всё




dUo
string
string
2024-09-07












dES9uM794KhwUlwTGHzG+UPxxM2uD4VGZlAcBa+rgYw=






rv9DaN3WexhCYTjPgMOGBZjlmjEEgIWnXhVRY7HI1ME=


z0XO1yBC0gdMCWg5o9Dwy/QdGsrsOX01xWw0Qc9NVGZT8NW15TbcIVMXzbO8SHOy61igRPiS/07JgAFcLj/h4BINpJmTu1oMpytF+UtVxXxg6ht9D1oVxr1PqwHR9M6T7E47fTedhJ0Uygul9l+488dRXDpAo21Bm06jjNuNQCe9Xj/CXjVSvdp20xfo66nqjogsWsNObecmMngWhR8m1VqZwZ9Fl1dP3N83eShlpiyvKqA/5GrCGSF//qaGU+HDzpYcpbCxlsUg2WGw7FJl/o76IQqUURbx8fGN1hDyy30WywYXMgvFgASC7Hz7mIonCIMzD+1k4R7yNtEUWOTFpA==


MIIFwzCCA6ugAwIBAgIUZ+/0NR80a5BgKrnqi0EI8GSaC0EwDQYJKoZIhvcNAQELBQAwfzELMAkGA1UEBhMCS0UxEDAOBgNVBAgMB05haXJvYmkxDTALBgNVBAoMBElQU0wxEzARBgNVBAsMClRlY2hub2xvZ3kxGjAYBgNVBAMMEUlQU0wgSW50ZXJtZWRpYXRlMR4wHAYJKoZIhvcNAQkBFg9pbmZvQGlwc2wuY28ua2UwHhcNMjQw0DI3MDkyMjEzWhcNMjUwOTI5MDkyMjQzWjBqMQswCQYDVQQGEwJLRTEQMA4GA1UEBxMHTmFpcm9iaTENMAsGA1UEChMESVBTTDERMA8GA1UECxMIUGF5bWVudHMxJzAlBgNVBAMTHjAyMDEtc2VhbC5zdGFnZS5wZXNhbGluay5jby5rZTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAItd33GEXtuk5iuyBgUGlhcsEvx0OfshkpgA2NWm5U+s8zLx3PZm7tWhkH99ztBmO/x++OOTc2E9/vlyso+Uke3G7xgywDIBxuvULx+Isgj+AzdBBCtVdAaDb7o0OuuyOqqT4wM6qrbL/qGBdMJzk2LjGeB/PgyVU/dgGXBEdoftX16Af/FvEZveZZ1NOqwJxjRhiEN6i4STR9p+DmJnO3/RqLzYa3v75czvV3bqBlWh8RjJYVUm5hFRoGsSgb1DKhtMeiRISdGhLthIyWNtKEXBummPBi7RN6qUGWNbNh3u6+uuAY5LIksbMu2gGbbsOPPTOxlJ+CcNBvHxwlRmNVMCAwEAAaOCAUowggFGMA4GA1UdDwEB/wQEAwIGwDAMBgNVHRMBAf8EAjAAMB0GA1UdDgQWBBTdWH3JZ4oXKk7pcwmVjmvGxFXGJTAfBgNVHSMEGDAWgBSKj0mwWY9FuNR035FMI5x0FQgWIDBNBggrBgEFBQcBAQRBMD8wPQYIKwYBBQUHMAKGMWh0dHA6Ly9jZXJ0LnN0YWdlLnBlc2FsaW5rLmNvLmtlL3YxL3NpZ25hdHVyZS5jcnQwQgYDVR0fBDswOTA3oDWgM4YxaHR0cDovL2NlcnQuc3RhZ2UucGVzYWxpbmsuY28ua2UvdjEvc2lnbmF0dXJlLmNybDBTBgNVHREETDBKoA0GA1UEYaAGDAQwMjAxgh4wMjAxLXNlYWwuc3RhZ2UucGVzYWxpbmsuY28ua2WCGTAyMDEuc3RhZ2UucGVzYWxpbmsuY28ua2UwDQYJKoZIhvcNAQELBQADggIBAF+OPL8UJaibXhLT8635QlzDEQiRCysHXxTKgXUBdE/flsVHylNx8QnPHmoXJHLYn7EnyVA07yIuEa2Uo8hsnnyUQDaykHVm5z9xwJn8QvHHLKtWyfDvDbU9/tpNNA5+zbIG61dl3p/Ji3PgMSnEMI0nzILQa9uFFaF8x+TcYWdi1W5lICz9Wx5/qDSfz1yv8ClJqrpW4HoKbKhY9EdAGLiBbcvJCtxiea5udrZRIJFoQNesbWdM4dhy9U4EGcZPoApQZaTRPJBm36FthCAMmi+dLSEK1lfwPQ2yhwUnkfhLdZHpTgqQ6NCkmb/egQw4CCGGu3oL0rRzC5FZicXPNxr7c2eETleH+fUNk2P+eXCP1xUz40SGzWxhAGnSMohHdZw8YYr3ySSdjCePnO33ueApVB+sda5Lh1/WfhNYcAjDlFechQSpolmnu5P9LNCgOaGHmFHCQELcHMLCW9F6QJ6A84Jov1Td1xj8xBdsfpLbSK7Pyf922CrpDzf47w6BxcNfqxQXIEDUgznS7sJVcxAFRKoYHfEQxYxgYJj1yPjpTGH/pRrdIZhlb+MpGBXEOqO2lcUhjPNVhm90ABmfn76+pvfAsOzxZID5dZqzPE5h3MayVyiVY1DDiczIU1oK7rPU78vrOomSeyCDltXTFkfD9hf0iLQUidcifmLiNCF8




< /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. ключ и сертификат
Несмотря на эти шаги, проверка дайджеста завершается неудачей, и я получаю сообщение об ошибке, указывающее, что значения дайджеста, вычисленные во время проверки, не соответствуют значениям дайджеста в подписанном XML. Я также пытался нормализовать XML перед подписанием, но по-прежнему сталкиваюсь с той же ошибкой.
Буду очень признателен за любую помощь или информацию о том, почему происходит несоответствие дайджеста и как его устранить!< /п>

Подробнее здесь: https://stackoverflow.com/questions/789 ... rrect-this

Вернуться в «JAVA»