如何将pfx文件转换为jks然后使用它来通过使用wsdl生成的类来签署传出的soap请求

我正在寻找一个代码示例,该示例演示如何使用PFX证书通过SSL访问安全Web服务。 我有证书和密码,我开始使用下面提到的命令创建一个KeyStore实例。

keytool -importkeystore -destkeystore "C:\Program Files\Java\jdk1.8.0_131\jre\lib\security\dvs.keystore" -srckeystore "C:\Program Files\Java\jdk1.8.0_131\jre\lib\security\key.pfx" -srcstoretype pkcs12 -deststoretype JKS -srcstorepass ******* 

然后我使用wsimport -keep -verbose -extension https://sandpit.dvshub.com.au:19443/Bus/VerificationServiceBus.svc?wsdl命令生成Java文件。

之后我创建了一个主类,在其中我指定了几个参数,例如这些证书的位置。

  System.setProperty("javax.net.ssl.trustStore", trustStoreFile); System.setProperty("javax.net.ssl.trustStorePassword", trustStorePassword); System.setProperty("javax.net.ssl.keyStore", certificateFile); System.setProperty("javax.net.ssl.keyStorePassword", certificatePassword); System.setProperty("sun.security.ssl.allowUnsafeRenegotiation", "true"); System.setProperty("javax.net.ssl.keyStore", "C:\\Users\\Administrator\\Desktop\\dvs\\key.pfx"); System.setProperty("javax.net.ssl.keyStoreType", "PKCS12"); System.setProperty("javax.net.ssl.keyStorePassword", certificatePassword); 

然后我最终调用了wsimport使用它生成的服务创建的web方法。

 CreatedService service = ServiceFactory/Port/Creator.getCreatedService(); // Where 'CreatedService' and 'ServiceFactory/Port/Creator' were created by wsimport: this code entirely depends on the WSDL provided. service.[ws method](...); 

然后我创建了一个处理程序来跟踪标题内传递的内容,但我根本看不到添加任何签名。 我在这里错过了一些东西。 我只收到请求超时错误。

我在Soap UI中有一个工作示例,所以我知道服务正常运行。

任何有关这方面的帮助将非常感谢。 请指出正确的方向,因为我准备在这一点上尝试任何事情。

提前致谢。

[编辑] WSO2应用服务器是否可行: 参考

这是我选择当前方法参考的地方

所以我正在寻找的是一种签署我的soap请求的方法,我将详细介绍如何使用提供给我的wsdl生成Java类,如何设法从中生成Java密钥库pfx文件提供给我,然后设法签署使用它的soap请求。

WSDL到Java类:

因此,我将隐藏在ssl证书后面的wsdl的内容复制到文件中,然后使用下面pom中定义的插件生成Java类。 然后我将这些类从目标文件夹移动到src目录。

的pom.xml

   4.0.0 com.javacodegeeks.examples.jaxws.client JavaWsClient 0.0.1-SNAPSHOT    org.apache.maven.plugins maven-compiler-plugin  1.6 1.6    org.apache.cxf cxf-codegen-plugin 3.1.12   generate-sources generate-sources  ${project.build.directory}/generated/cxf   ${basedir}/src/main/resources/wsdl.xml     wsdl2java         org.apache.cxf cxf-rt-frontend-jaxws 3.1.12   org.apache.cxf cxf-rt-transports-http 3.1.12   org.apache.cxf cxf-rt-ws-security 3.1.12    org.apache.cxf cxf-rt-transports-http-jetty 3.1.12    org.apache.santuario xmlsec 2.0.8    

使用mvn generate-resources将为您在目标文件夹中创建Java类。

下一步是将我提供的pfx文件转换为JavaKeyStore’JKS’。 其步骤如下所述。 您必须下载weblogic才能获得转换所需的jar。

1.运行以下OpenSSL命令从.pfx文件中提取证书和密钥:openssl pkcs12 -in yourfilename.pfx -out tempcertfile.crt -nodes现在应该有一个名为tempcertfile.crt的文件。 使用文本编辑器(如写字板)打开此文件。 您将首先看到列出的私钥,然后是您的证书信息。

 -----BEGIN RSA PRIVATE KEY----- (Block of Encrypted Text) -----END RSA PRIVATE KEY----- 

2.将所有私钥(包括BEGIN和END标记)剪切并粘贴到新文本文件中,并将其另存为your_domain_name.key

3. tempcertfile.crt中剩余的证书将按以下顺序排列:服务器证书,根证书和中间证书。 但是,根据您的.pfx导出,文件中可能有2-4个证书。 只要您正确导出证书,此文件中的任何内容都是您应该拥有的证书。

4.确保已删除私钥(不仅仅是复制和粘贴),然后将文件另存为your_domain_name.pem。

5通过在keytool中将以下两行作为一个命令运行来创建身份证书密钥库:

 java utils.ImportPrivateKey -keystore new_identity_keystore.jks -storepass YOURPASSWORD -storetype JKS -keypass YOURPASSWORD -alias server -certfile tempcertfile.crt -keyfile your_domain_name.key -keyfilepass PFXPASSWORD 

请记住用密码替换YOURPASSWORD。 同时将PFXPASSWORD替换为您在创建.pfx文件时创建的密码。

参考

以下是我根据参考执行的命令。

 openssl pkcs12 -in "C:\Program Files\Java\jdk1.8.0_131\jre\lib\security\file.pfx" -out "C:\Program Files\Java\jdk1.8.0_131\jre\lib\security\tempcertfile.crt" -nodes openssl x509 -outform der -in "C:\Program Files\Java\jdk1.8.0_131\jre\lib\security\file.pem" -out "C:\Program Files\Java\jdk1.8.0_131\jre\lib\security\file.der" java -cp C:\Oracle\Middleware\Oracle_Home\wlserver\server\lib\weblogic.jar utils.ImportPrivateKey -keystore "C:\Program Files\Java\jdk1.8.0_131\jre\lib\security\file.jks" -storepass mypass-storetype JKS -keypass mypass-alias myalias -certfile "C:\Program Files\Java\jdk1.8.0_131\jre\lib\security\file.pem" -keyfile "C:\Program Files\Java\jdk1.8.0_131\jre\lib\security\file.key" -keyfilepass mypass 

下一步是使用jks并使用cfx签署我的传出请求。 这是Java类及其配置文件。

 /* * To change this license header, choose License Headers in Project Properties. * To change this template file, choose Tools | Templates * and open the template in the editor. */ package dvstest; import dvs.common._2014._06.contract.data.Gender; import dvs.common._2014._06.contract.data.RegistrationState; import dvs.common._2014._06.contract.data.manager.*; import dvs.common._2014._06.contract.service.manager.IVerification; import org.apache.cxf.endpoint.Client; import org.apache.cxf.endpoint.Endpoint; import org.apache.cxf.frontend.ClientProxy; import org.apache.cxf.jaxws.JaxWsProxyFactoryBean; import org.apache.cxf.transport.http.HTTPConduit; import org.apache.cxf.transports.http.configuration.HTTPClientPolicy; import org.apache.cxf.ws.addressing.WSAddressingFeature; import org.apache.cxf.ws.security.wss4j.WSS4JOutInterceptor; import org.apache.wss4j.dom.WSConstants; import org.apache.wss4j.dom.handler.WSHandlerConstants; import javax.xml.bind.JAXBElement; import javax.xml.datatype.DatatypeFactory; import javax.xml.datatype.XMLGregorianCalendar; import java.util.Date; import java.util.GregorianCalendar; import java.util.HashMap; import java.util.Map; import java.util.logging.Level; import java.util.logging.Logger; /** * @author Sadiq */ public class DVSTest { /** * @param args the command line arguments */ public static void main(String[] args) { try { // These params are used to print the soap request going in and out. System.setProperty("com.sun.xml.ws.transport.http.client.HttpTransportPipe.dump", "true"); System.setProperty("com.sun.xml.internal.ws.transport.http.client.HttpTransportPipe.dump", "true"); System.setProperty("com.sun.xml.ws.transport.http.HttpAdapter.dump", "true"); System.setProperty("com.sun.xml.internal.ws.transport.http.HttpAdapter.dump", "true"); //Path to java keystore which holds the ssl certificate, might come in handy later on. /*String trustStoreFile = "C:\\Program Files\\Java\\jdk1.8.0_131\\jre\\lib\\security\\cacerts"; String trustStorePassword = "changeit"; System.setProperty("javax.net.ssl.trustStore", trustStoreFile); System.setProperty("javax.net.ssl.trustStorePassword", trustStorePassword); System.setProperty("javax.net.ssl.trustStoreType", "JKS"); System.setProperty("sun.security.ssl.allowUnsafeRenegotiation", "true");*/ /* This is how we can extra namespaces if needed. Map nsMap = new HashMap(); nsMap.put("wsse", "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd"); nsMap.put("wsu", "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd"); nsMap.put("man", "http://DVS/Common/2014/06/Contract/Service/Manager"); nsMap.put("man1", "http://DVS/Common/2014/06/Contract/Data/Manager"); nsMap.put("ds", "http://www.w3.org/2000/09/xmldsig#"); nsMap.put("ec", "http://www.w3.org/2001/10/xml-exc-c14n#"); client.getRequestContext().put("soap.env.ns.map", nsMap); */ //Creating a factory and setting the service interface using which we can make soap requests. JaxWsProxyFactoryBean factory = new JaxWsProxyFactoryBean(); factory.setServiceClass(IVerification.class); //Path to endpoint //You can get this path by looking inside the wsdl factory.setAddress("https://urlhere/Https"); //Pointing the post request to be soap12 compliant factory.setBindingId("http://schemas.xmlsoap.org/wsdl/soap12/"); //Adding address feature to the outgoing request, this will add  part to soap request. factory.getFeatures().add(new WSAddressingFeature()); //Creating a port for the verification interface using the factory. IVerification port = (IVerification) factory.create(); //Creating client, this will be used to specify various outgoing props. Client client = ClientProxy.getClient(port); //Setting content type and creating a conduit. HTTPConduit http = (HTTPConduit) client.getConduit(); HTTPClientPolicy httpClientPolicy = new HTTPClientPolicy(); httpClientPolicy.setContentType("application/soap+xml"); http.setClient(httpClientPolicy); //Endpoint fetched using client Endpoint cxfEndpoint = client.getEndpoint(); //Setting cfx related props Map outProps = new HashMap(); outProps.put(WSHandlerConstants.ACTION, "Signature Timestamp"); outProps.put(WSHandlerConstants.USER, "myalias"); outProps.put(WSHandlerConstants.SIG_PROP_FILE, "client_sign.properties"); //Used to add the digest part to the soap post request outProps.put(WSHandlerConstants.SIG_KEY_ID, "DirectReference"); //Used to sign the  element. outProps.put(WSHandlerConstants.SIGNATURE_PARTS, "{Element}{http://www.w3.org/2005/08/addressing}To"); // Password type : plain text outProps.put(WSHandlerConstants.PASSWORD_TYPE, WSConstants.PW_TEXT); // for hashed password use: //properties.put(WSHandlerConstants.PASSWORD_TYPE, WSConstants.PW_DIGEST); // Callback used to retrieve password for given user. outProps.put(WSHandlerConstants.PW_CALLBACK_CLASS, ClientPasswordCallback.class.getName()); //Setting props to post request. WSS4JOutInterceptor wssOut = new WSS4JOutInterceptor(outProps); cxfEndpoint.getOutInterceptors().add(wssOut); System.out.println(passportRequest(port).getVerificationResultCode()); System.out.println(driverLicenseRequest(port).getVerificationResultCode()); } catch (Exception ex) { Logger.getLogger(DVSTest.class.getName()).log(Level.SEVERE, null, ex); } } /** * Sets properties to PassportRequest and makes a soap request using the IVerification object. * * @param port Needs a IVerification object created by the factory. * @return VerificationResponse as a response of soap request. * @throws Exception */ public static VerificationResponse passportRequest(IVerification port) throws Exception { //Creating a passport request PassportRequest request = new PassportRequest(); //Creating a DVSDate object and the creating a jaxb element to be assigned to the PassportRequest object. DVSDate date = new DVSDate(); date.setDay(1); date.setMonth(1); date.setYear(2017); ObjectFactory objectFactory = new ObjectFactory(); JAXBElement documentRequest = objectFactory.createDVSDate(date); request.setBirthDate(documentRequest); request.setDocumentTypeCode(DocumentType.PP); JAXBElement familyName = objectFactory.createCertificateRequestFamilyName2("D"); request.setFamilyName(familyName); JAXBElement givenName = objectFactory.createCertificateRequestGivenName2("T"); request.setGivenName(givenName); request.setOriginatingAgencyCode("1"); GregorianCalendar c = new GregorianCalendar(); c.setTime(new Date(System.currentTimeMillis())); XMLGregorianCalendar requestDate = DatatypeFactory.newInstance().newXMLGregorianCalendar(c); request.setRequestDateTime(requestDate); request.setVerificationRequestNumber("1"); request.setVersionNumber("1"); JAXBElement gender = objectFactory.createPassportRequestGender(Gender.M); request.setGender(gender); request.setTravelDocumentNumber("1"); return port.verifyDocument(request); } /** * Sets properties to DriverLicenseRequest and makes a soap request using the IVerification object. * * @param port Needs a IVerification object created by the factory. * @return VerificationResponse as a response of soap request. * @throws Exception */ public static VerificationResponse driverLicenseRequest(IVerification port) throws Exception { //Creating a passport request DriverLicenceRequest request = new DriverLicenceRequest(); //Creating a DVSDate object and the creating a jaxb element to be assigned to the PassportRequest object. DVSDate date = new DVSDate(); date.setDay(1); date.setMonth(1); date.setYear(2017); ObjectFactory objectFactory = new ObjectFactory(); JAXBElement documentRequest = objectFactory.createDVSDate(date); request.setBirthDate(documentRequest); request.setDocumentTypeCode(DocumentType.DL); JAXBElement familyName = objectFactory.createCertificateRequestFamilyName2("D"); request.setFamilyName(familyName); JAXBElement givenName = objectFactory.createCertificateRequestGivenName2("T"); request.setGivenName(givenName); request.setOriginatingAgencyCode("1"); GregorianCalendar c = new GregorianCalendar(); c.setTime(new Date(System.currentTimeMillis())); XMLGregorianCalendar requestDate = DatatypeFactory.newInstance().newXMLGregorianCalendar(c); request.setRequestDateTime(requestDate); request.setVerificationRequestNumber("1"); request.setVersionNumber("1"); request.setLicenceNumber("1"); JAXBElement middleName = objectFactory.createDriverLicenceRequestMiddleName("Joseph"); request.setMiddleName(middleName); dvs.common._2014._06.contract.data.ObjectFactory objectFactoryData = new dvs.common._2014._06.contract.data.ObjectFactory(); JAXBElement registrationState = objectFactoryData.createRegistrationState(RegistrationState.NSW); request.setStateOfIssue(registrationState.getValue()); JAXBElement gender = objectFactory.createPassportRequestGender(Gender.M); return port.verifyDocument(request); } } 

client_sign.properties文件:

 org.apache.ws.security.crypto.provider=org.apache.ws.security.components.crypto.Merlin org.apache.ws.security.crypto.merlin.keystore.type=jks org.apache.ws.security.crypto.merlin.keystore.password=mypass org.apache.ws.security.crypto.merlin.keystore.alias=myalias org.apache.ws.security.crypto.merlin.keystore.file=C:\\Program Files\\Java\\jdk1.8.0_131\\jre\\lib\\security\\file.jks 

最后但并非最不重要的密码回调处理程序。

 package dvstest; import java.io.IOException; import javax.security.auth.callback.Callback; import javax.security.auth.callback.CallbackHandler; import javax.security.auth.callback.UnsupportedCallbackException; import org.apache.wss4j.common.ext.WSPasswordCallback; public class ClientPasswordCallback implements CallbackHandler { @Override public void handle(Callback[] callbacks) throws IOException, UnsupportedCallbackException { WSPasswordCallback pc = (WSPasswordCallback) callbacks[0]; // set the password for our message. pc.setPassword("mypass"); } } 

我希望这有助于某人。 花了一些时间来收集所需的所有信息。

参考 文献2参考3