如何将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

查看:136
本文介绍了如何将pfx文件转换为jks,然后通过使用wsdl生成的类将其用于签署传出的soap请求的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I am looking for a code example which shows how to access a secure web service over SSL using a PFX certificate. I have the certificate and its password and I started by creating a KeyStore instance using the command mentioned below.

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文件。

I then used wsimport -keep -verbose -extension https://sandpit.dvshub.com.au:19443/Bus/VerificationServiceBus.svc?wsdl command to generate Java files.

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

After which I created a main class in which I specified several parameters such as the location of these certificates.

        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方法。

Then I eventually called the web method that was created by wsimport using the service it generated.

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](...);

然后我创建了一个处理程序来跟踪标头中传递的内容,但是我看不到签名被添加到它。我在这想念什么吗?我只是收到请求超时错误。

I then created a handler to keep track of what is being passed inside the header but I cannot see any signature being added to it at all. Am I missing something over here. I am only getting request timed out errors.

我在Soap UI中有一个有效的示例,因此我知道该服务运行正常。

I have a working example of it in Soap UI so I know that the service is running properly.

任何对此的帮助将不胜感激。请指向正确的方向,因为我现在准备尝试任何事情。

Any help with this would be very much appreciated. Please point me in the right direction as I am ready to try anything at this point.

预先感谢。


是WSO2应用程序服务器要走的路:参考

这是我采用当前方法的地方参考

This is where I picked up my current approach Reference

推荐答案

所以我一直在寻找一种签名我的soap请求的方法,我将详细介绍如何使用提供给我的wsdl生成Java类,如何生成Java。

So what I was looking for was a way to sign my soap request, I am going to go into details as to how I managed to generate Java classes using the wsdl that was provided to me, how I managed to generate a Java keystore from the pfx file that was provided to me and then managed to sign the soap request going out using it.

WSDL到Java类:

WSDL to Java classes:

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

So I copied the content of of the wsdl that was hiding behind an ssl certificate to a file and then used the plugin defined in the pom below to generate Java classes. I then moved these classes from the target folder to the src directory.

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

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

Next step was to convert the pfx file I was provided with into a JavaKeyStore 'JKS'. Steps for which are mentioned down below. You will have to download weblogic to get the jars necessary for the conversion.

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

1.Run the following OpenSSL command to extract your certificates and key from the .pfx file: openssl pkcs12 -in yourfilename.pfx -out tempcertfile.crt -nodes You should now have a file called tempcertfile.crt. Open this file with a text editor (such as WordPad). You will see the private key listed first, followed by your certificate information.

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

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

2.Cut and paste all of the private key, including the BEGIN and END tags to a new text file and save it as your_domain_name.key

3。tempcertfile.crt中剩余的证书将按照以下顺序排列:服务器证书,根证书和中间证书。但是,根据您的.pfx导出,文件中可能有2-4个证书。只要您正确地导出了证书,该文件中所包含的就是您应该拥有的证书。

3.The certificates remaining in your tempcertfile.crt will be in the following order: Server Certificate, Root Certificate, and Intermediate Certificate. However, depending on your .pfx export there could be 2–4 certificates inside the file. As long as you exported the certificates correctly, whatever you have in this file are the certificates that you are supposed to have.

4。确保已删除私钥(

4.Make sure the private key was removed (not just copied and pasted), then save the file as your_domain_name.pem.

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

5Create a identity certificate keystore by running the following two lines as one command in 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

记住要替换您的密码和您的密码。还将PFXPASSWORD替换为创建.pfx文件时创建的密码。

Remember to replace YOURPASSWORD with your password. Also replace PFXPASSWORD with the password that you created when you created your .pfx file.

参考

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

Here are the commands that I executed based on the reference.

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类及其配置文件。

Next step was to use the jks and sign my outgoing request using cfx. Here is the Java class along with the configuration file for it.

/*
 * 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文件:

client_sign.properties file:

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

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

Last but not the least the password callback handler.

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");
    }

}

我希望这对某人有帮助。花了我一段时间来收集所有必需的信息。

I hope this helps somebody. Took me a while to gather all the info that was required.

参考2
Reference3

这篇关于如何将pfx文件转换为jks,然后通过使用wsdl生成的类将其用于签署传出的soap请求的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆