如何将 pfx 文件转换为 jks,然后使用它通过使用从 wsdl 生成的 类 来签署传出的 soap 请求
How to convert a pfx file into jks and then use it to sign an outgoing soap request by using the classes generated from a wsdl
我正在寻找一个代码示例,它展示了如何使用 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 个文件。
之后我创建了一个主程序 class,我在其中指定了几个参数,例如这些证书的位置。
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](...);
然后我创建了一个处理程序来跟踪在 header 中传递的内容,但我根本看不到任何签名被添加到它。我在这里错过了什么吗?我只收到请求超时错误。
我在 Soap UI 中有一个它的工作示例,所以我知道该服务 运行 是正确的。
如能提供任何帮助,我们将不胜感激。请为我指明正确的方向,因为此时我已准备好尝试任何事情。
提前致谢。
[编辑]
WSO2 应用程序服务器是要走的路吗:Reference
这是我采用当前方法的地方Reference
所以我一直在寻找一种方法来签署我的 soap 请求,我将详细介绍如何使用 wsdl 生成 Java classes向我提供了我如何设法从提供给我的 pfx 文件生成一个 Java 密钥库,然后设法使用它签署 soap 请求。
WSDL 到 Java classes:
所以我将隐藏在 ssl 证书后面的 wsdl 的内容复制到一个文件中,然后使用下面的 pom 中定义的插件生成 Java classes。然后我将这些 classes 从目标文件夹移动到 src 目录。
pom.xml
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.javacodegeeks.examples.jaxws.client</groupId>
<artifactId>JavaWsClient</artifactId>
<version>0.0.1-SNAPSHOT</version>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>1.6</source>
<target>1.6</target>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.cxf</groupId>
<artifactId>cxf-codegen-plugin</artifactId>
<version>3.1.12</version>
<executions>
<execution>
<id>generate-sources</id>
<phase>generate-sources</phase>
<configuration>
<sourceRoot>${project.build.directory}/generated/cxf</sourceRoot>
<wsdlOptions>
<wsdlOption>
<wsdl>${basedir}/src/main/resources/wsdl.xml</wsdl>
</wsdlOption>
</wsdlOptions>
</configuration>
<goals>
<goal>wsdl2java</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
<dependencies>
<dependency>
<groupId>org.apache.cxf</groupId>
<artifactId>cxf-rt-frontend-jaxws</artifactId>
<version>3.1.12</version>
</dependency>
<dependency>
<groupId>org.apache.cxf</groupId>
<artifactId>cxf-rt-transports-http</artifactId>
<version>3.1.12</version>
</dependency>
<dependency>
<groupId>org.apache.cxf</groupId>
<artifactId>cxf-rt-ws-security</artifactId>
<version>3.1.12</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.apache.cxf/cxf-rt-transports-http-jetty -->
<dependency>
<groupId>org.apache.cxf</groupId>
<artifactId>cxf-rt-transports-http-jetty</artifactId>
<version>3.1.12</version>
</dependency>
<!--
<dependency>
<groupId>org.springframework.ws</groupId>
<artifactId>spring-ws-security</artifactId>
<exclusions>
<exclusion>
<groupId>org.apache.santuario</groupId>
<artifactId>xmlsec</artifactId>
</exclusion>
</exclusions>
</dependency>-->
<dependency>
<groupId>org.apache.santuario</groupId>
<artifactId>xmlsec</artifactId>
<version>2.0.8</version>
</dependency>
</dependencies>
</project>
使用 mvn generate-resources
会在目标文件夹中为您创建 Java classes。
下一步是将提供给我的 pfx 文件转换为 JavaKeyStore 'JKS'。下面提到的步骤。您将必须下载 weblogic 以获得转换所需的 jar。
1.Run 以下 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.Cut 并将所有私钥(包括 BEGIN 和 END 标记)粘贴到一个新的文本文件中,并将其另存为 your_domain_name.key
3.The 个留在您的 tempcertfile.crt 中的证书将按以下顺序排列:服务器证书、根证书和中间证书。但是,根据您的 .pfx 导出,文件中可能有 2-4 个证书。只要你正确导出了证书,这个文件里的就是你应该有的证书。
4.Make 确保私钥已删除(不仅仅是复制和粘贴),然后将文件另存为 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 class 及其配置文件。
/*
* 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<String, String> 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 <To><MessageId><ReplyTo> 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<String, Object> outProps = new HashMap<String, Object>();
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 <To> 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<DVSDate> documentRequest = objectFactory.createDVSDate(date);
request.setBirthDate(documentRequest);
request.setDocumentTypeCode(DocumentType.PP);
JAXBElement<String> familyName = objectFactory.createCertificateRequestFamilyName2("D");
request.setFamilyName(familyName);
JAXBElement<String> 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> 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<DVSDate> documentRequest = objectFactory.createDVSDate(date);
request.setBirthDate(documentRequest);
request.setDocumentTypeCode(DocumentType.DL);
JAXBElement<String> familyName = objectFactory.createCertificateRequestFamilyName2("D");
request.setFamilyName(familyName);
JAXBElement<String> 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<String> 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> registrationState = objectFactoryData.createRegistrationState(RegistrationState.NSW);
request.setStateOfIssue(registrationState.getValue());
JAXBElement<Gender> 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");
}
}
我希望这对某人有所帮助。我花了一些时间来收集所有需要的信息。
我正在寻找一个代码示例,它展示了如何使用 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 个文件。
之后我创建了一个主程序 class,我在其中指定了几个参数,例如这些证书的位置。
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](...);
然后我创建了一个处理程序来跟踪在 header 中传递的内容,但我根本看不到任何签名被添加到它。我在这里错过了什么吗?我只收到请求超时错误。
我在 Soap UI 中有一个它的工作示例,所以我知道该服务 运行 是正确的。
如能提供任何帮助,我们将不胜感激。请为我指明正确的方向,因为此时我已准备好尝试任何事情。
提前致谢。
[编辑] WSO2 应用程序服务器是要走的路吗:Reference
这是我采用当前方法的地方Reference
所以我一直在寻找一种方法来签署我的 soap 请求,我将详细介绍如何使用 wsdl 生成 Java classes向我提供了我如何设法从提供给我的 pfx 文件生成一个 Java 密钥库,然后设法使用它签署 soap 请求。
WSDL 到 Java classes:
所以我将隐藏在 ssl 证书后面的 wsdl 的内容复制到一个文件中,然后使用下面的 pom 中定义的插件生成 Java classes。然后我将这些 classes 从目标文件夹移动到 src 目录。
pom.xml
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.javacodegeeks.examples.jaxws.client</groupId>
<artifactId>JavaWsClient</artifactId>
<version>0.0.1-SNAPSHOT</version>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>1.6</source>
<target>1.6</target>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.cxf</groupId>
<artifactId>cxf-codegen-plugin</artifactId>
<version>3.1.12</version>
<executions>
<execution>
<id>generate-sources</id>
<phase>generate-sources</phase>
<configuration>
<sourceRoot>${project.build.directory}/generated/cxf</sourceRoot>
<wsdlOptions>
<wsdlOption>
<wsdl>${basedir}/src/main/resources/wsdl.xml</wsdl>
</wsdlOption>
</wsdlOptions>
</configuration>
<goals>
<goal>wsdl2java</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
<dependencies>
<dependency>
<groupId>org.apache.cxf</groupId>
<artifactId>cxf-rt-frontend-jaxws</artifactId>
<version>3.1.12</version>
</dependency>
<dependency>
<groupId>org.apache.cxf</groupId>
<artifactId>cxf-rt-transports-http</artifactId>
<version>3.1.12</version>
</dependency>
<dependency>
<groupId>org.apache.cxf</groupId>
<artifactId>cxf-rt-ws-security</artifactId>
<version>3.1.12</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.apache.cxf/cxf-rt-transports-http-jetty -->
<dependency>
<groupId>org.apache.cxf</groupId>
<artifactId>cxf-rt-transports-http-jetty</artifactId>
<version>3.1.12</version>
</dependency>
<!--
<dependency>
<groupId>org.springframework.ws</groupId>
<artifactId>spring-ws-security</artifactId>
<exclusions>
<exclusion>
<groupId>org.apache.santuario</groupId>
<artifactId>xmlsec</artifactId>
</exclusion>
</exclusions>
</dependency>-->
<dependency>
<groupId>org.apache.santuario</groupId>
<artifactId>xmlsec</artifactId>
<version>2.0.8</version>
</dependency>
</dependencies>
</project>
使用 mvn generate-resources
会在目标文件夹中为您创建 Java classes。
下一步是将提供给我的 pfx 文件转换为 JavaKeyStore 'JKS'。下面提到的步骤。您将必须下载 weblogic 以获得转换所需的 jar。
1.Run 以下 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.Cut 并将所有私钥(包括 BEGIN 和 END 标记)粘贴到一个新的文本文件中,并将其另存为 your_domain_name.key
3.The 个留在您的 tempcertfile.crt 中的证书将按以下顺序排列:服务器证书、根证书和中间证书。但是,根据您的 .pfx 导出,文件中可能有 2-4 个证书。只要你正确导出了证书,这个文件里的就是你应该有的证书。
4.Make 确保私钥已删除(不仅仅是复制和粘贴),然后将文件另存为 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 class 及其配置文件。
/*
* 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<String, String> 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 <To><MessageId><ReplyTo> 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<String, Object> outProps = new HashMap<String, Object>();
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 <To> 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<DVSDate> documentRequest = objectFactory.createDVSDate(date);
request.setBirthDate(documentRequest);
request.setDocumentTypeCode(DocumentType.PP);
JAXBElement<String> familyName = objectFactory.createCertificateRequestFamilyName2("D");
request.setFamilyName(familyName);
JAXBElement<String> 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> 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<DVSDate> documentRequest = objectFactory.createDVSDate(date);
request.setBirthDate(documentRequest);
request.setDocumentTypeCode(DocumentType.DL);
JAXBElement<String> familyName = objectFactory.createCertificateRequestFamilyName2("D");
request.setFamilyName(familyName);
JAXBElement<String> 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<String> 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> registrationState = objectFactoryData.createRegistrationState(RegistrationState.NSW);
request.setStateOfIssue(registrationState.getValue());
JAXBElement<Gender> 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");
}
}
我希望这对某人有所帮助。我花了一些时间来收集所有需要的信息。