Tuesday 23 February 2016

applying RESTful Webservice - security using Asymmetric (public/private key) - Spring & CXF

continuation to this link  we need to do below configuration setup:

Generate jks file:

1) keytool -genkeypair -alias tomcat -keyalg RSA -keysize 1024 -keypass changeit -keystore tomcat.jks

2) To view public key :
keytool -list -rfc -keystore C:\Users\rkumarga\tomcat.jks -alias tomcat -storepass changeit

3) in tomcat.properties file, use these values:

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=changeit
org.apache.ws.security.crypto.merlin.keystore.alias=tomcat
org.apache.ws.security.crypto.merlin.keystore.file=C:/Users/kuku/tomcat.jks

Open postman tool and use the below url and click on Send, we get response in encrypted format:

http://localhost:8080/MyWS/rest/myRestServices/myCodes?_type=xml



This response from server has been encrypted using public key. to see the decrypted data of the response, follow the below steps:

Use the below code to get the private key from tomcat.jks file:

import org.apache.commons.codec.binary.Base64;

import java.io.FileInputStream;
import java.security.Key;
import java.security.KeyStore;

public class DumpPrivateKey {
    static public void main(String[] args) throws Exception {

        final String keystoreName = "C:/Users/kuku/tomcat.jks";
        final String keystorePassword = "changeit";
        final String alias = "tomcat";

        KeyStore ks = KeyStore.getInstance("jks");
        ks.load(new FileInputStream(keystoreName), keystorePassword.toCharArray());
        Key key = ks.getKey(alias, keystorePassword.toCharArray());

        String b64 = new String(Base64.encodeBase64(key.getEncoded(), true));
        System.out.println("-----BEGIN PRIVATE KEY-----");
        System.out.println(b64);
        System.out.println("-----END PRIVATE KEY-----");
    }
}

output of the above code:

-----BEGIN PRIVATE KEY-----
MIICdwIBADANBgkqhkiG9w0BAQEFAASCAmEwggJdAgEAAoGBAKVkFxAPT+WrykynfxMJVnAKM3i2
IGGQQhTFiyjgI6QnVKjUsb6rOUtACuVacSVKxwDLHfLV6JxOQX5ulZz9sNcFqOJ/Hif+U2Bc0swT
dVnYFA+tyjQL+4gIu+WqdGtxWWJ5O2pyW1lvv5KtJsV2itaYtq2GSl5qLhUMMd1xyOAZAgMBAAEC
gYA97WNBTSpyaceeuhy3qQhnfTpWmYM4ZMaJdoorrPlLbrqhWLqRFRWn2nv58spo1z36SxOUqImn
dRnK2GdG2CrNTiCI5JyomGn2UGwV1I/uSsj9p2aF81O71dEmDrCDafgbqrjKrRPE5MBGPVChbTo2
mQ/ivYVprhkIbvAiQtNsAQJBANFZV1MbGSmQjvqDbaztWauOvk/oAeRv7BXTOLGpheiR/HdvpS4v
diipB3boa2UFfAl3fuRxnkMIKLbB1sFZzYECQQDKPxdxrxtBWy+AOdVtWJj1f1s7TxCC+luInRWB
g2cJZ5S26wWVT05W9uGzVumOiSnTuvQyPVO2qKqkMjOp4A6ZAkEAo7Ej4suRhTqPUbpqi4ibUNWw
YXKb6C7LftVFw0U2e3+K1SjrE43w6iIgwA1DzB3Zut1Azwc4JFnA3AX9EfpSAQJANIB+YIe5hpTa
Vuosio9GXeyqzVGwEqBVZLiKna1z8RAPnhCSyXjl+FNssfas+NCIqCtPOz+KXM+aRLe3i7DbeQJB
AM6GMbwSfi6qXpaHhLBd+om7t0KHf4elSc5PNA7fNhPoIrgmi3WhKTcAP5MXM8KxtA96rgDZKTaX
PGHB9FhPK10=

-----END PRIVATE KEY-----


copy past the encrypted response and this Private key in the below url and click on Decrypt XML button, we can see the decrypted XML:



create SOAP based Webservice - Spring & CXF

web.xml:

<?xml version="1.0" encoding="UTF-8"?><web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee"         xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"         id="WebApp_ID" version="2.5">
    <display-name>myws</display-name>
    
    <context-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>
            /WEB-INF/application-config.xml
        </param-value>
    </context-param>
    <listener>
        <listener-class>
            org.springframework.web.context.ContextLoaderListener
        </listener-class>
    </listener>
    <servlet>
        <servlet-name>CXFServlet</servlet-name>
        <servlet-class>
            org.apache.cxf.transport.servlet.CXFServlet
        </servlet-class>
        <load-on-startup>1</load-on-startup>
    </servlet>
    <servlet-mapping>
        <servlet-name>CXFServlet</servlet-name>
        <url-pattern>/services/*</url-pattern>
    </servlet-mapping>
    <servlet-mapping>
        <servlet-name>CXFServlet</servlet-name>
        <url-pattern>/rest/*</url-pattern>
    </servlet-mapping>
</web-app>

application-config.xml :

<beans xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"       xmlns:jaxws="http://cxf.apache.org/jaxws"       xmlns:jaxrs="http://cxf.apache.org/jaxrs"       xmlns:soap="http://cxf.apache.org/bindings/soap"       xmlns:context="http://www.springframework.org/schema/context"       xmlns="http://www.springframework.org/schema/beans"       xsi:schemaLocation="http://www.springframework.org/schema/beans                            http://www.springframework.org/schema/beans/spring-beans.xsd                            http://cxf.apache.org/jaxws http://cxf.apache.org/schemas/jaxws.xsd                            http://cxf.apache.org/jaxrs http://cxf.apache.org/schemas/jaxrs.xsd                            http://cxf.apache.org/bindings/soap                            http://cxf.apache.org/schemas/configuration/soap.xsd                            http://www.springframework.org/schema/context                            http://www.springframework.org/schema/context/spring-context.xsd">

    <context:component-scan base-package="com.my.webservice"/>

    <import resource="classpath:META-INF/cxf/cxf.xml"/>
    <import resource="classpath:META-INF/cxf/cxf-servlet.xml"/>
    <import resource="db-config.xml"/>


    <bean id="myWebService" class="com.my.webservice.v1.service.impl.WebServiceImpl"/>
 <bean id="auditInInterceptor" class="com.my.webservice.interceptors.AuditLogInterceptor"/>
    <bean id="logOut" class="org.apache.cxf.interceptor.LoggingOutInterceptor"/>
    <bean id="logIn" class="org.apache.cxf.interceptor.LoggingInInterceptor"/>

    <jaxws:endpoint id="WebService" implementor="#myWebService" address="/MyWebService">
        <jaxws:binding>
            <soap:soapBinding mtomEnabled="true" version="1.2"/>
        </jaxws:binding>
        <jaxws:properties>
            <entry key="schema-validation-enabled" value="true"/>
            <entry key="faultStackTraceEnabled" value="true"/>
        </jaxws:properties>
        <jaxws:inInterceptors>
            <ref bean="logIn"/>
            <ref bean="auditInInterceptor"/>
        </jaxws:inInterceptors>
        <jaxws:outInterceptors>
            <ref bean="logOut"/>
        </jaxws:outInterceptors>
    </jaxws:endpoint>

   <!-- <bean id="xmlSigInHandler" class="org.apache.cxf.rs.security.xml.XmlSigInHandler"/>-->    <bean id="xmlEncInHandler" class="org.apache.cxf.rs.security.xml.XmlEncInHandler">
        <property name="encryptionProperties" ref="encProps"/>
    </bean>

    <bean id="xmlEncOutHandler" class="org.apache.cxf.rs.security.xml.XmlEncOutInterceptor">
        <property name="symmetricEncAlgorithm" value="aes128-cbc"/>
    </bean>

    <bean id="encProps" class="org.apache.cxf.rs.security.xml.EncryptionProperties">
        <property name="encryptionKeyTransportAlgo"                  value="http://www.w3.org/2001/04/xmlenc#rsa-oaep-mgf1p"/>
        <property name="encryptionSymmetricKeyAlgo"                  value="http://www.w3.org/2001/04/xmlenc#aes128-cbc"/>
    </bean>

    <jaxrs:server id="myRestService" address="/myRestServices">
        <jaxrs:serviceBeans>
            <ref bean="myWebService"/>
        </jaxrs:serviceBeans>
        <jaxrs:extensionMappings>
            <entry key="json" value="application/json"/>
            <entry key="xml" value="application/xml"/>
        </jaxrs:extensionMappings>
        <jaxrs:providers>
            <bean class="org.codehaus.jackson.jaxrs.JacksonJaxbJsonProvider"/>
            <bean class="org.codehaus.jackson.jaxrs.JacksonJsonProvider"/>
            <!--<ref bean="xmlEncInHandler"/>-->        </jaxrs:providers>
        <jaxrs:inInterceptors>
            <ref bean="logIn"/>
            <ref bean="auditInInterceptor"/>
        </jaxrs:inInterceptors>
        <jaxrs:outInterceptors>
           <ref bean="xmlEncOutHandler"/>
        </jaxrs:outInterceptors>
        <jaxrs:properties>
            <entry key="security.callback-handler" value="com.my.webservice.v1.service.impl.KeystorePasswordCallback"/>
            <entry key="security.encryption.username" value="tomcat"/>
            <entry key="security.encryption.properties" value="file:///C:/Users/kuku/tomcat.properties"/>
        </jaxrs:properties>
    </jaxrs:server>
</beans>


import javax.jws.WebService;

@WebService(targetNamespace = "http://webservice.my.com/v1", name = "MyWebServicePortType")
public interface WebServiceInterface {
.
.
.
}

import org.apache.cxf.annotations.SchemaValidation;

import javax.jws.WebParam;
import javax.jws.WebService;
import javax.ws.rs.*;
import java.io.IOException;
import java.util.List;

@WebService(name = "MyWebService", targetNamespace = "http://webservice.my.com/v1", serviceName = "MyWebService", endpointInterface = "com.my.webservice.v1.service.MyWebService", portName = "MyWebServicePortName")
@SchemaValidation(type = SchemaValidation.SchemaValidationType.BOTH)
public class WebServiceImpl implements WebServiceInterface {
.
.
.
}


http://localhost:8080/MyWS/services/MyWebService?wsdl

MyWS - Project name (war name)


Create Symmectric key - command

keytool -genseckey -alias tomcat -keyalg AES -keysize 128 -storetype jceks -keystore tomcatSymmectrickey.jks