gpt4 book ai didi

java - 在 Java 中使用 WSS4j 对 SOAP 消息进行签名

转载 作者:行者123 更新时间:2023-11-30 06:16:32 27 4
gpt4 key购买 nike

我正在编写一个 Java 客户端应用程序,它需要签署 SOAP 消息(其中包含 2 个部分)并将其发送到远程服务器,然后再获取响应。我成功地在 SoapUI 中进行了调用(请参阅下面的请求和屏幕截图)。

我已准备好大部分代码,但我不断从服务器收到一条错误消息:

SECU3504: Digital signature verification failure.
Signature failed core validation

Signature validation status: true
ref[#id-32e3db92-b6fd-42a5-b032-a0dc2a15ae82] validity status: false
ref[#id-2b67ce75-e25f-4f66-b265-80a0e31911ec] validity status: false

这是我的 Java 代码:

// Load KeyStore from .PFX certificate
KeyStore store = KeyStore.getInstance("PKCS12");
store.load(new FileInputStream(certificateFileName), certificatePassword.toCharArray());

// Build XML Document from String
String data = "..."; // Same request as in SoapUI
DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance();
DocumentBuilder dBuilder = dbFactory.newDocumentBuilder();
doc = dBuilder.parse(new ByteArrayInputStream(data.getBytes()));

// Load certificate
String alias = store.aliases().nextElement(); // There's only one
PrivateKeyEntry keyEntry = (PrivateKeyEntry)store.getEntry(alias, new KeyStore.PasswordProtection(password.toCharArray()));
X509Certificate cert = (X509Certificate) keyEntry.getCertificate();

// Add <wsse:Security> tag.
WSSecHeader secHeader = new WSSecHeader();
secHeader.setMustUnderstand(false);
secHeader.insertSecurityHeader(doc);

// It is not added to the right place, so move it under the right header
Node n = doc.getFirstChild().getFirstChild().getFirstChild();
Element elemEnvelope = (Element)doc.getElementsByTagName("soapenv:Envelope").item(0);
Element elemNewHeader = (Element)doc.getElementsByTagName("Header").item(0);
Element elemSoapHeader = (Element)doc.getElementsByTagName("soapenv:Header").item(0);
Element elemBody = (Element)doc.getElementsByTagName("soapenv:Body").item(0);
Element elemHeader = (Element)doc.getElementsByTagName("ns1:CAISOWSHeader").item(0);
elemSoapHeader.insertBefore(n, elemHeader);
elemEnvelope.removeChild(elemNewHeader);

// Setup signing algorithm
WSSecSignature builder = new WSSecSignature();
builder.setX509Certificate(cert);
builder.setUserInfo(alias, password);
builder.setKeyIdentifierType(WSConstants.BST_DIRECT_REFERENCE);
builder.setSignatureAlgorithm(WSConstants.RSA_SHA1);
builder.setSigCanonicalization(WSConstants.C14N_EXCL_OMIT_COMMENTS);
builder.setDigestAlgo(WSConstants.SHA1);
builder.setUseSingleCertificate(true);

// Set message parts to sign
List<WSEncryptionPart> parts = new ArrayList<WSEncryptionPart>();
WSEncryptionPart bodyPart1 = new WSEncryptionPart("Body", WSConstants.URI_SOAP11_ENV, "Content");
WSEncryptionPart bodyPart2 = new WSEncryptionPart("CAISOWSHeader", "http://www.caiso.com/soa/2006-09-30/CAISOWSHeader.xsd", "Content");
bodyPart1.setElement(elemBody);
bodyPart2.setElement(elemHeader);
parts.add(bodyPart1);
parts.add(bodyPart2);
builder.getParts().addAll(parts);

// Set keystore and sign the document
Properties properties = new Properties();
properties.setProperty("org.apache.ws.security.crypto.provider", "org.apache.wss4j.common.crypto.Merlin");

Merlin crypto = (Merlin)CryptoFactory.getInstance(properties);
crypto.setKeyStore(store);

doc = builder.build(doc, crypto, secHeader);
String docStr = this.toString(doc); // This method generates a string of the Document.

// Send SOAP message
CloseableHttpClient httpclient = HttpClients.custom().setSSLSocketFactory(sslsf).build();
HttpPost httppost = new HttpPost(this.url);
HttpEntity entity = new ByteArrayEntity(docStr .getBytes("UTF-8"));
httppost.setEntity(entity); // Signed Body
httppost.addHeader("SOAPAction", "http://www.caiso.com/soa/retrieveConvergenceBidAwards_v2");

HttpResponse response = httpclient.execute(httppost);
String respStr = EntityUtils.toString(response.getEntity());

我成功地使用以下安全设置在 SoapUI 中进行了调用:enter image description here

我在SoapUI中输入的请求如下(Dates/MessageId/Nonce是当场生成的,但为了可读性,我将它们硬编码在这里):

<?xml version="1.0" encoding="UTF-8"?>
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:stan="http://www.caiso.com/soa/2006-06-13/StandardAttachmentInfor.xsd" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<soapenv:Header>
<ns1:CAISOWSHeader xmlns:ns1="http://www.caiso.com/soa/2006-09-30/CAISOWSHeader.xsd" xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd" soapenv:actor="" soapenv:mustUnderstand="0">
<ns1:CAISOUsernameToken>
<ns1:Username>CN=XXXX, OU=people, O=XXXX, C=US</ns1:Username>
<Nonce xmlns:ns2="http://schemas.xmlsoap.org/ws/2002/07/secext" EncodingType="http://docs.oasisopen.org/wss/2004/01/oasis-200401wss-soap-message-security-1.0#Base64Binary">MGNkNmU5ODMtZjcyZC00YTAyLWE5NWMtM2Q5Y2RjMTEyNDA1</Nonce>
<Created xmlns:ns3="http://schemas.xmlsoap.org/ws/2002/07/utility">2018-03-02T21:13:45.932Z</Created>
</ns1:CAISOUsernameToken>
<CAISOMessageInfo>
<MessageID>06c3379d-f10e-45f2-84eb-9262acce277e</MessageID>
<Timestamp>
<Created xmlns:ns4="http://schemas.xmlsoap.org/ws/2002/07/utility">2018-03-02T21:13:45.932Z</Created>
<Expires xmlns:ns5="http://schemas.xmlsoap.org/ws/2002/07/utility">2018-03-02T23:13:45.932Z</Expires>
</Timestamp>
</CAISOMessageInfo>
</ns1:CAISOWSHeader>
<attachmentHash xmlns:ns7="http://www.caiso.com/mrtu/soa/schemas/2005/09/attachmenthash" actor="http://schemas.xmlsoap.org/soap/actor/next" mustUnderstand="0">
<hashValue />
</attachmentHash>
<standardAttachmentInfor xmlns:ns1="http://www.caiso.com/soa/2006-06-13/StandardAttachmentInfor.xsd">
<Attachment>
<id>1</id>
<compressFlag>yes</compressFlag>
<compressMethod>gzip</compressMethod>
</Attachment>
</standardAttachmentInfor>
</soapenv:Header>
<soapenv:Body>
<retrieveConvergenceBidAwards_v2>
<RequestConvergenceBidAwards>
<MessagePayload>
<RequestConvergenceBidAwardRecord>
<dateTimeEnd>2018-02-02T08:00:00Z</dateTimeEnd>
<dateTimeStart>2018-02-01T08:00:00Z</dateTimeStart>
<SchedulingCoordinatorList>
<schedulingCoordinator>XXXX</schedulingCoordinator>
</SchedulingCoordinatorList>
</RequestConvergenceBidAwardRecord>
</MessagePayload>
</RequestConvergenceBidAwards>
</retrieveConvergenceBidAwards_v2>
</soapenv:Body>
</soapenv:Envelope>

我不知道问题出在哪里。是在签名过程中、从文档到字符串的转换过程中还是在我执行 HTTP 请求的过程中?

非常感谢您的帮助:)

最佳答案

我知道这是一个老问题,但我一直在努力解决这个问题,我终于找到了一种生成签名的方法,就像 Soap UI 所做的那样,这是我的代码:

public String handleMessage(SOAPMessage message) {
String ret;
try {
Document doc = message.getSOAPBody().getOwnerDocument();
Crypto crypto = CryptoFactory.getInstance(properties); //File

WSSecSignature sign = new WSSecSignature();
sign.setUserInfo(properties.getProperty("org.apache.ws.security.crypto.merlin.keystore.alias"), properties.getProperty("privatekeypassword"));
sign.setKeyIdentifierType(WSConstants.BST_DIRECT_REFERENCE); // Binary Security Token - SecurityTokenReference
sign.setUseSingleCertificate(true);
sign.setDigestAlgo(DigestMethod.SHA256);

WSSecHeader secHeader = new WSSecHeader();
secHeader.insertSecurityHeader(doc);
Document signedDoc = sign.build(doc, crypto, secHeader);

ret = org.apache.ws.security.util.XMLUtils.PrettyDocumentToString(signedDoc);

} catch (SOAPException e) {
e.printStackTrace();
return null;
} catch (WSSecurityException e) {
e.printStackTrace();
throw new RuntimeException("Error: " + e.getMessage());
}
return ret;
}

此代码取自:https://sourceforge.net/p/signsoaprequest/code/HEAD/tree/SignSOAPRequest/trunk/src/main/java/br/gov/dataprev/soaptools/sign/

关于java - 在 Java 中使用 WSS4j 对 SOAP 消息进行签名,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49077876/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com