我正在用jks签名SOAP,以从客户端获取证书和私钥并将消息发送到服务器。我在BODY做签名。到目前为止,我还没有问题。现在,当使用公钥验证服务器上的签名时,出现以下错误:
[linux-o58d]02Oct2019_10:02:43(Wed)CEST admin.sh:java.security.spec.InvalidKeySpecException: java.security.InvalidKeyException: IOException: ObjectIdentifier() -- data isn't an object ID (tag = -96)
[linux-o58d]02Oct2019_10:02:43(Wed)CEST admin.sh:at sun.security.rsa.RSAKeyFactory.engineGeneratePublic(RSAKeyFactory.java:205)
[linux-o58d]02Oct2019_10:02:43(Wed)CEST admin.sh:at java.security.KeyFactory.generatePublic(KeyFactory.java:334)
[linux-o58d]02Oct2019_10:02:43(Wed)CEST admin.sh:at com.avvillas.was.webServicesCoordinador.webServicesUtilities.KryptoUtil.getStoredPublicKey(KryptoUtil.java:160)
[linux-o58d]02Oct2019_10:02:43(Wed)CEST admin.sh:at com.avvillas.was.webServicesCoordinador.webServicesUtilities.ServerSOAPHandler.handleInboundMessage(ServerSOAPHandler.java:58)
[linux-o58d]02Oct2019_10:02:43(Wed)CEST admin.sh:at com.avvillas.was.webServicesCoordinador.webServicesUtilities.ServerSOAPHandler.handleMessage(ServerSOAPHandler.java:42)
[linux-o58d]02Oct2019_10:02:43(Wed)CEST admin.sh:at com.avvillas.was.webServicesCoordinador.webServicesUtilities.ServerSOAPHandler.handleMessage(ServerSOAPHandler.java:30)
[linux-o58d]02Oct2019_10:02:43(Wed)CEST admin.sh:at com.sun.xml.internal.ws.handler.HandlerProcessor.callHandleMessage(HandlerProcessor.java:282)
[linux-o58d]02Oct2019_10:02:43(Wed)CEST admin.sh:at com.sun.xml.internal.ws.handler.HandlerProcessor.callHandlersRequest(HandlerProcessor.java:125)
[linux-o58d]02Oct2019_10:02:43(Wed)CEST admin.sh:at com.sun.xml.internal.ws.handler.ServerSOAPHandlerTube.callHandlersOnRequest(ServerSOAPHandlerTube.java:123)
[linux-o58d]02Oct2019_10:02:43(Wed)CEST admin.sh:at com.sun.xml.internal.ws.handler.HandlerTube.processRequest(HandlerTube.java:112)
[linux-o58d]02Oct2019_10:02:43(Wed)CEST admin.sh:at com.sun.xml.internal.ws.api.pipe.Fiber.__doRun(Fiber.java:1121)
[linux-o58d]02Oct2019_10:02:43(Wed)CEST admin.sh:at com.sun.xml.internal.ws.api.pipe.Fiber._doRun(Fiber.java:1035)
[linux-o58d]02Oct2019_10:02:43(Wed)CEST admin.sh:at com.sun.xml.internal.ws.api.pipe.Fiber.doRun(Fiber.java:1004)
[linux-o58d]02Oct2019_10:02:43(Wed)CEST admin.sh:at com.sun.xml.internal.ws.api.pipe.Fiber.runSync(Fiber.java:862)
[linux-o58d]02Oct2019_10:02:43(Wed)CEST admin.sh:at com.sun.xml.internal.ws.server.WSEndpointImpl$2.process(WSEndpointImpl.java:404)
[linux-o58d]02Oct2019_10:02:43(Wed)CEST admin.sh:at com.sun.xml.internal.ws.transport.http.HttpAdapter$HttpToolkit.handle(HttpAdapter.java:706)
[linux-o58d]02Oct2019_10:02:43(Wed)CEST admin.sh:at com.sun.xml.internal.ws.transport.http.HttpAdapter.handle(HttpAdapter.java:260)
[linux-o58d]02Oct2019_10:02:43(Wed)CEST admin.sh:at com.sun.xml.internal.ws.transport.http.server.WSHttpHandler.handleExchange(WSHttpHandler.java:98)
[linux-o58d]02Oct2019_10:02:43(Wed)CEST admin.sh:at com.sun.xml.internal.ws.transport.http.server.WSHttpHandler.handle(WSHttpHandler.java:82)
[linux-o58d]02Oct2019_10:02:43(Wed)CEST admin.sh:at com.sun.net.httpserver.Filter$Chain.doFilter(Filter.java:79)
[linux-o58d]02Oct2019_10:02:43(Wed)CEST admin.sh:at sun.net.httpserver.AuthFilter.doFilter(AuthFilter.java:83)
[linux-o58d]02Oct2019_10:02:43(Wed)CEST admin.sh:at com.sun.net.httpserver.Filter$Chain.doFilter(Filter.java:82)
[linux-o58d]02Oct2019_10:02:43(Wed)CEST admin.sh:at sun.net.httpserver.ServerImpl$Exchange$LinkHandler.handle(ServerImpl.java:675)
[linux-o58d]02Oct2019_10:02:43(Wed)CEST admin.sh:at com.sun.net.httpserver.Filter$Chain.doFilter(Filter.java:79)
[linux-o58d]02Oct2019_10:02:43(Wed)CEST admin.sh:at sun.net.httpserver.ServerImpl$Exchange.run(ServerImpl.java:645)
[linux-o58d]02Oct2019_10:02:43(Wed)CEST admin.sh:at sun.net.httpserver.ServerImpl$DefaultExecutor.execute(ServerImpl.java:158)
[linux-o58d]02Oct2019_10:02:43(Wed)CEST admin.sh:at sun.net.httpserver.ServerImpl$Dispatcher.handle(ServerImpl.java:431)
[linux-o58d]02Oct2019_10:02:43(Wed)CEST admin.sh:at sun.net.httpserver.ServerImpl$Dispatcher.run(ServerImpl.java:396)
[linux-o58d]02Oct2019_10:02:43(Wed)CEST admin.sh:at java.lang.Thread.run(Thread.java:748)
[linux-o58d]02Oct2019_10:02:43(Wed)CEST admin.sh:Caused by: java.security.InvalidKeyException: IOException: ObjectIdentifier() -- data isn't an object ID (tag = -96)
[linux-o58d]02Oct2019_10:02:43(Wed)CEST admin.sh:at sun.security.x509.X509Key.decode(X509Key.java:397)
[linux-o58d]02Oct2019_10:02:43(Wed)CEST admin.sh:at sun.security.x509.X509Key.decode(X509Key.java:402)
[linux-o58d]02Oct2019_10:02:43(Wed)CEST admin.sh:at sun.security.rsa.RSAPublicKeyImpl.<init>(RSAPublicKeyImpl.java:86)
[linux-o58d]02Oct2019_10:02:43(Wed)CEST admin.sh:at sun.security.rsa.RSAKeyFactory.generatePublic(RSAKeyFactory.java:298)
[linux-o58d]02Oct2019_10:02:43(Wed)CEST admin.sh:at sun.security.rsa.RSAKeyFactory.engineGeneratePublic(RSAKeyFactory.java:201)
[linux-o58d]02Oct2019_10:02:43(Wed)CEST admin.sh:... 28 more
我从jks生成了公钥,但仍在KryptoUtil类中。
/**
* Method used to get the generated Public Key
*
* @param filePath of the PublicKey file
* @return PublicKey
*/
public PublicKey getStoredPublicKey(String filePath) {
PublicKey publicKey = null;
byte[] keydata = getKeyData(filePath);
KeyFactory keyFactory = null;
try {
keyFactory = KeyFactory.getInstance("RSA");
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
}
X509EncodedKeySpec encodedPublicKey = new X509EncodedKeySpec(keydata);
try {
publicKey = keyFactory.generatePublic(encodedPublicKey);
} catch (NullPointerException npe) {
npe.printStackTrace();
} catch (InvalidKeySpecException e) {
e.printStackTrace();
}
return publicKey;
}
}
这里,错误是:
X509EncodedKeySpec encodedPublicKey = new X509EncodedKeySpec(keydata);
publicKey = keyFactory.generatePublic(encodedPublicKey);
SOAP签名客户端:
@Override
public boolean handleMessage(SOAPMessageContext smc) {
Boolean outboundProperty = (Boolean) smc.get(MessageContext.MESSAGE_OUTBOUND_PROPERTY);
SOAPMessage message = smc.getMessage();
if (outboundProperty) {
try {
SOAPPart soapPart = message.getSOAPPart();
SOAPEnvelope soapEnvelope = soapPart.getEnvelope();
Source source = soapPart.getContent();
Node root = null;
Document doc22 = null;
KEYSTORE_FILE += utils.getParamAutorizacionWS().get("KEYSTORE_SIGN");
KEYSTORE_INSTANCE = utils.getParamAutorizacionWS().get("KEYSTORE_INSTANCE_SIGN");
KEYSTORE_PWD = utils.getParamAutorizacionWS().get("KEYSTORE_PWD_SIGN");
KEYSTORE_ALIAS = utils.getParamAutorizacionWS().get("KEYSTORE_ALIAS_SIGN");
if (source instanceof DOMSource) {
root = ((DOMSource) source).getNode();
} else if (source instanceof SAXSource) {
InputSource inSource = ((SAXSource) source).getInputSource();
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
dbf.setNamespaceAware(true);
DocumentBuilder db = null;
db = dbf.newDocumentBuilder();
doc22 = db.parse(inSource);
root = (Node) doc22.getDocumentElement();
}
XMLSignatureFactory fac = XMLSignatureFactory.getInstance("DOM");
Reference ref = fac.newReference("", fac.newDigestMethod(DigestMethod.SHA1, null),
Collections.singletonList(fac.newTransform(Transform.ENVELOPED, (TransformParameterSpec) null)),
null, null);
SignedInfo si = fac.newSignedInfo(fac.newCanonicalizationMethod(CanonicalizationMethod.INCLUSIVE,
(C14NMethodParameterSpec) null),
fac.newSignatureMethod(SignatureMethod.RSA_SHA1, null),
Collections.singletonList(ref));
// Load the KeyStore and get the signing key and certificate.
KeyStore ks = KeyStore.getInstance(KEYSTORE_INSTANCE);
ks.load(new FileInputStream(KEYSTORE_FILE),
KEYSTORE_PWD.toCharArray());
KeyStore.PrivateKeyEntry keyEntry = (KeyStore.PrivateKeyEntry) ks
.getEntry(
KEYSTORE_ALIAS,
new KeyStore.PasswordProtection(KEYSTORE_PWD
.toCharArray()));
X509Certificate cert = (X509Certificate) keyEntry.getCertificate();
// Create the KeyInfo containing the X509Data.
KeyInfoFactory kif2 = fac.getKeyInfoFactory();
List x509Content = new ArrayList();
x509Content.add(cert.getSubjectX500Principal().getName());
x509Content.add(cert);
X509Data xd = kif2.newX509Data(x509Content);
KeyInfo ki = kif2.newKeyInfo(Collections.singletonList(xd));
Element body = (Element) root.getFirstChild().getChildNodes().item(1);
DOMSignContext dsc = new DOMSignContext(keyEntry.getPrivateKey(), body);
XMLSignature signature = fac.newXMLSignature(si, ki);
signature.sign(dsc);
message.saveChanges();
message.writeTo(System.out);
} catch (Exception ex) {
ex.printStackTrace();
}
}
return true;
}
SOAP验证签名
private void handleInboundMessage(SOAPMessageContext context) {
try {
SOAPMessage msg = context.getMessage();
SOAPPart sp = msg.getSOAPPart();
SOAPEnvelope document = sp.getEnvelope();
boolean validFlag = false;
Document doc = document.getOwnerDocument();
NodeList nl = doc.getElementsByTagNameNS(XMLSignature.XMLNS, "Signature");
if (nl.getLength() == 0) {
throw new Exception("No XML Digital Signature Found, document is discarded");
}
PublicKey publicKey = new KryptoUtil().getStoredPublicKey(PUBLIC_KEY);
DOMValidateContext valContext = new DOMValidateContext(publicKey, nl.item(0));
XMLSignatureFactory fac = XMLSignatureFactory.getInstance("DOM");
XMLSignature signature = fac.unmarshalXMLSignature(valContext);
validFlag = signature.validate(valContext);
context.put("SIGNATURE", validFlag);
} catch (Exception e) {
System.out.println("Error reading SOAP message context: " + e);
e.printStackTrace();
}
}
发生了什么事?
感谢。
似乎您正在将JSF参考实现Mojarra和Apache JSF实现MyFaces混合在一起。我在您的堆栈跟踪中看到了两个类。 (org.apache.myfaces
与com.sun.faces
)。我猜WebLogic提供了Mojarra实现,因此您不应将JSF相关的JAR添加到Web应用程序中。
如果您的构建工具是Maven,请删除myfaces-impl工件并用<scope>provided</scope>
标记myfaces-api或将其替换为
<dependency>
<groupId>javax.faces</groupId>
<artifactId>javax.faces-api</artifactId>
<version>YOUR_WEB_LOGICS_JSF_API_VERSION_HERE</version>
<scope>provided</scope>
</dependency>