How to extract Certificate and private key from jks

WSO2 products are shipped with jks key store. In this post we are going to see how to extract the public key certificate and private key from wso2cabon.jks to PEM using keytool and openssl.

  1.  Convert JKS to PCKS12 using keytool

     keytool -importkeystore -srckeystore wso2carbon.jks -destkeystore mystore.p12 -srcstoretype JKS -deststoretype PKCS12 -srcstorepass wso2carbon -deststorepass destpass -srcalias wso2carbon -destalias myalias -srckeypass wso2carbon -destkeypass destpass -noprompt

    This will create mystore.p12 keystore which is  PKCS12 type

  2. Extract public certificate from mystore.p12 to PEM using openssl

     openssl pkcs12 -in mystore.p12 -out wso2.pem

    This will create wso2.pem file with public certificate as follow,


    -----BEGIN CERTIFICATE-----
    MIICNTCCAZ6gAwIBAgIES343gjANBgkqhkiG9w0BAQUFADBVMQswCQYDVQQGEwJV
    UzELMAkGA1UECAwCQ0ExFjAUBgNVBAcMDU1vdW50YWluIFZpZXcxDTALBgNVBAoM
    BFdTTzIxEjAQBgNVBAMMCWxvY2FsaG9zdDAeFw0xMDAyMTkwNzAyMjZaFw0zNTAy
    MTMwNzAyMjZaMFUxCzAJBgNVBAYTAlVTMQswCQYDVQQIDAJDQTEWMBQGA1UEBwwN
    TW91bnRhaW4gVmlldzENMAsGA1UECgwEV1NPMjESMBAGA1UEAwwJbG9jYWxob3N0
    MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCUp/oV1vWc8/TkQSiAvTousMzO
    M4asB2iltr2QKozni5aVFu818MpOLZIr8LMnTzWllJvvaA5RAAdpbECb+48FjbBe
    0hseUdN5HpwvnH/DW8ZccGvk53I6Orq7hLCv1ZHtuOCokghz/ATrhyPq+QktMfXn
    RS4HrKGJTzxaCcU7OQIDAQABoxIwEDAOBgNVHQ8BAf8EBAMCBPAwDQYJKoZIhvcN
    AQEFBQADgYEAW5wPR7cr1LAdq+IrR44iQlRG5ITCZXY9hI0PygLP2rHANh+PYfTm
    xbuOnykNGyhM6FjFLbW2uZHQTY1jMrPprjOrmyK5sjJRO4d1DeGHT/YnIjs9JogR
    Kv4XHECwLtIVdAbIdWHEtVZJyMSktcyysFcvuhPQK8Qc/E/Wq8uHSCo=
    -----END CERTIFICATE-----

  3.  Extract private key from mystore.p12 to PEM using openssl

     openssl pkcs12 -in mystore.p12 -nocerts -out wso2.key -passin pass:destpass

    once executed this command you will be asked for pass phrase.Private key will be encrypted by this pass phrase to enforce security.

    Encrypted private key(wso2.key file) will looks like this,


    -----BEGIN ENCRYPTED PRIVATE KEY-----
    MIICxjBABgkqhkiG9w0BBQ0wMzAbBgkqhkiG9w0BBQwwDgQIUOibMhIr4VUCAggA
    MBQGCCqGSIb3DQMHBAhUdc2GGS3L8gSCAoAs/RzzpoW8G3AHKQPAELcTzAic6nDx
    lccNoAzbO6yAdfodYqsjFYICwVg9fYMo7hDF0C3W/TkT1/Wk4ettmWO4J7dPVpeA
    uUW1kD9HmzRlizcg8+Ot0wO+RV1gTiB73uB2pPllcZmXSVxc9JDWWUzO+DDv+gbN
    dtqq+8n9so7NIgMHy+zNC0hVL4IWRevAcN6zzu4qLKj/YdwrjNGjN15wuLZZgYnG
    Bd4zfil+nH9bjrG1hGnei6F8GDbZ79KspL0b99rZKkScU8ND0dyZRm06ItXTD2Rv
    emwFAV0rBfm8IVKdRQ0v2z5hHl808okX6d4vgensc1QYoEG9LuDpBcZRPXizdoSu
    89DVxWJgtiad5mPc67VHPBQMU/tO1yzZJuuw9bZEITbkWQNB0XMEYkIiCEFJVjF6
    ifLUKj35x6a8uJvbZTPJZcMbdGfWtwP/RnXxmjK5GF2e+JmAjZl2VuiBftF5IAth
    CMh/0qarIlpwzXB+My1o1dGVCk9TyQ0UO/wQD+uVRA29pmX8NuyHPx9B6v+KUXvJ
    GZwLYeI1DAGG/H64HSRaiUihSBDC1fY5rX24pQAgPn5fc90ENAzIn+a9rQOMa6az
    LkJQH7yC1Gkz1npIoIZAaYvcpJ2X9/CltPzf7oK/ZQ2BHI1bcYvyALO/QW1SnB1M
    yjRBtjcfoSpDCQo8BuXzyNOjjTDxn6UbVMqlbzuiU4k5Gqlqslji1vvttKerQqwn
    NTY4Xf/4Nhsxp/Tf/fOFYsLocMwhwjJdMpEBz9Co6cKZvkyXMYxoiHoFLeoB2Gor
    bHmHJ/xWYCQHSVQvF8e2QnjmQHBTwD7+EbaRgPZCK2EJ3tFk7aA4EykC
    -----END ENCRYPTED PRIVATE KEY-----

  4. Get the DECRYPTED private key/Remove pass phrase from private key

    openssl rsa -in wso2.key -out wso2.key

    Now wso2.key file will have decrypted private key as follow,

    -----BEGIN RSA PRIVATE KEY-----
    MIICXAIBAAKBgQCUp/oV1vWc8/TkQSiAvTousMzOM4asB2iltr2QKozni5aVFu81
    8MpOLZIr8LMnTzWllJvvaA5RAAdpbECb+48FjbBe0hseUdN5HpwvnH/DW8ZccGvk
    53I6Orq7hLCv1ZHtuOCokghz/ATrhyPq+QktMfXnRS4HrKGJTzxaCcU7OQIDAQAB
    AoGAS/+ooju4a9po67zIGTEkqrQmsJC1HAPZo0bOmQK38LRzcps8Bmao9tjjbuVq
    ogEj2xgjtHyNPSn3oBUA3v33usJ6YqwVrWsC6FwmZhq8Avsf94qm4hiTHe1AdxWm
    ZGTs1eSYc6JnPIp0iVjHEfssIlGN+7LX1Q6kdbCf482dTnUCQQDvLwmtjlUASW84
    zL5PEnNCorlcJ8qjGKlbcur2Lrn3vSCyX4cIWMxPNsCGvS2IO1Ctmz7yssnobhX6
    iOaFOZVPAkEAnxuSwN4Kdw9Zku8cc7aifnJuEjzuEemM1cmwGSqilL0xUijVeeyq
    fyy+1o7VFDa/nWPmmEZSqPNR6utcvLQU9wJAIycmpPtmQsSINDDjR3vOtNx1obW3
    coENYwNgxQ3ZBzAkvhKMJg3m+T1yzlq/dmZBVUKb3c+pHSAQ2uGD/9CWwQJAVRy4
    6ndc/ce2UQWcIMJINoAcJaF2cRqQfiTAERZfllWGtr6lQ+24XwOeqsQJdCC9bAJu
    7nJf8YUIAzUYjNGAjQJBAKskkwcdhzvVcs7llm3+wWEzbMXzvNBmkZGRhDX6jtUI
    J4U9RTHivqMeym4vp0mggaD4zc8qzG1NPDOp0p5AxBg=
    -----END RSA PRIVATE KEY-----

Advertisements

Decode WSO2 App Manager generated JWT in PHP Web App

In this post we are going to see how to decode the JWT token in a PHP app which is published through APP Manager.

Environment – Ubuntu
IDE – NetBeans
JWT library for php – firebase/php-jwt
Server – apache web server

1. Create PHP web app to decode the JWT token and display

1.1 Create a new PHP project in netbeans – Lets say JWTDecode

1.2 Add the  firebase/php-jwt library as dependency to the project

Install composer to ubuntu. (Find what is composer and how to use it here)
Add firebase/php-jwt library as dependency to project using composer.

a. Right click the project -> composer->add dependency

composer-add-dependancy1

b. Type firebase/php-jwt in token text box and search. Select the firebase/php-jwt from
the search result. Select the latest release version and press require button

composer-add-dependancy2

c. Once dependency is added project will look like this

composer-add-dependancy3

1.3 Write code to decode and display jwt token. Add follwoing code to index.php


<?php
//for login
openlog("myScriptLog", LOG_PID | LOG_PERROR, LOG_LOCAL0);
//include firbase jwt library
require_once('vendor/autoload.php');
use \Firebase\JWT\JWT;
//public key of appmanager(default wso2cabon servers public key)
$publicKey = "-----BEGIN PUBLIC KEY-----
MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCUp/oV1vWc8/TkQSiAvTousMzO
M4asB2iltr2QKozni5aVFu818MpOLZIr8LMnTzWllJvvaA5RAAdpbECb+48FjbBe
0hseUdN5HpwvnH/DW8ZccGvk53I6Orq7hLCv1ZHtuOCokghz/ATrhyPq+QktMfXn
RS4HrKGJTzxaCcU7OQIDAQAB
-----END PUBLIC KEY-----
";

$headers = getallheaders();
//Read jwt token from http header X-JWT-Assertion;
$encodedJwtToken = $headers['X-JWT-Assertion'];
echo "<b>encoded jwt token recevied from appamanger</b>
";
echo $encodedJwtToken."";

//decode the token with signature verification.
$decodedJwtToken = JWT::decode($encodedJwtToken, $publicKey, array('RS256'));
echo "<b>decoded jwt token payload :</b>"."
";

foreach($decodedJwtToken as $key=>$val){
echo $key . ': ' . $val . '';
}

?>

2. Deploy the created web app in apache web server
(How to install Apache webs server on Ubuntu can be found here)

2.1 Navigate to  /var/www/ directory and add the web app
2.2 Start the Apache server  with command “sudo /etc/init.d/apache2 start”. Now web app can be directly access with url : http://localhost/JWTDecode/

3. Publish the deployed web app through app manager  to decode and display the jwt token 

3.1 Publish the app through App Manager (give the create webapp url http://localhost/JWTDecode/ as web app url )

create-jwt-webapp1

3.2  Go to the store find the created web app (jwt demo) and access the url http://xxxx:8280/jwt/1/.  As you can see in the image .,JWT sent from gateway to back-end app is processed(decoded) and displayed.

default-jwt-claim
By default only role claim is sent to the back-end web app. If you want to send more claims of user  then you have to do following steps
a.  Set <AddClaimsSelectively> element value as ‘true’ in  <AppM_HOME>/repository/conf/app-manager.xml
b. Restart the App Manager server
c. Go to the edit view of created web app in publisher web app
d. Under advanced configuration select the claims which should be included in JWT

create-jwt-webapp2

e. Update and access the web app .Now you will get selected claims in JWT

selective-claim

 

Download the sample php project here

WSO2 App Manager -Extract JWT token from wire log

App Manager provides SSO based on SAML for web apps published through it.So developers no need to worry about handling authentication in their web apps. They can develop unsecured web app and simply secure it via App Manager.

When a user try to access the unsecured web app though app manager(gateway component), authentication will be checked at gateway. If user is authenticated successfully he/she will be allowed to access the unsecured web app through gateway.

In some cases , unsecured web app may need the information of authenticated user to provide data/details related authenticated user.In such scenarios gateway should send the authenticated user information securely to the back end. Gateway is capable to send authenticated user’s information to back end app using JWT[1].  Configuring App Manager for JWT support can be found here[2].

In this post I am going to discuss on how to

1. Extract the encoded JWT token which is sent to back end web app by App Manager gateway.

2. Decode and verify the signature of the extracted token.

1. Extract the encoded JWT token

By default encoded JWT token is attached to “X-JWT-Assertion” http header. You can change the header where JWT token should be attached by configuring
<SecurityContextHeader/>  element in app-manger.xml[2].

By enabling the wire log in gateway ,  can find all the messages coming in to gateway and going out from gateway. So encoded JWT token can be extracted from the messages which going out from gateway to back end application.

1. Enable wire log
a. Open 
open log4j.properties file from <APPM_HOME>/repository/config
b. Un-comment the following entry.
log4j.logger.org.apache.synapse.transport.http.wire=DEBUG

2. Invoke the web app through gateway

3. Extract the message with http header X-JWT-Assertion
e.g

[2016-02-22 11:19:50,709] DEBUG – wire << “X-JWT-Assertion: eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiIsIng1dCI6Ik5rSkdPRVV4TXpaRlFqTTJSRFJCTlRaRlFUQTFRemRCUlRSQ09VRTBOVUkyTTBKR09UYzFSQT09In0=.eyJpc3MiOiJ3c28yLm9yZy9wcm9kdWN0cy9hcHBtIiwiZXhwIjoxNDU2MTIwOTE0NDM2LCJzdWIiOiJhZG1pbkBjYXJib24uc3VwZXIiLCJodHRwOi8vd3NvMi5vcmcvY2xhaW1zL3JvbGUiOiJJbnRlcm5hbC9hcHAxLXNpdGUtMSxJbnRlcm5hbC9hcHAxLXdlYi0xLEludGVybmFsL3B1Ymxpc2hlcixJbnRlcm5hbC9qd3QtMSxJbnRlcm5hbC9QbGFuWW91clRyaXBfYWRtaW4tMS4wLjAsSW50ZXJuYWwvYW5vbjEtc2l0ZS0xLEludGVybmFsL2NyZWF0b3IsYWRtaW4sSW50ZXJuYWwvcm9sZS13ZWJhcHAtMSxJbnRlcm5hbC9zdWJzY3JpYmVyLEludGVybmFsL3N0b3JlLWFkbWluLEludGVybmFsL2V2ZXJ5b25lLEludGVybmFsL2Fub24xLXdlYmFwcC0xIn0=.D17S22rLu+jjqEXrcqK9CnZuUGrIOVT7zPoUIq+AsnQTSqyUsvsR7CSvLK23w5hNrRapTgRdoCem2OxMLd3eLXZQN1mnMI4rzh+yYst8WhssPYC+RgedXf/J79PWTitg1ZJf/dogwUTx81YB7/gXlh8Tp34qf0djxVcwbpL/THA=[\r][\n]”

4. Extract the encoded JWT token(which is in bold text) from above message
Encoded token
eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiIsIng1dCI6Ik5rSkdPRVV4TXpaRlFqTTJSRFJCTlRaRlFUQTFRemRCUlRSQ09VRTBOVUkyTTBKR09UYzFSQT09In0=.eyJpc3MiOiJ3c28yLm9yZy9wcm9kdWN0cy9hcHBtIiwiZXhwIjoxNDU2MTIwOTE0NDM2LCJzdWIiOiJhZG1pbkBjYXJib24uc3VwZXIiLCJodHRwOi8vd3NvMi5vcmcvY2xhaW1zL3JvbGUiOiJJbnRlcm5hbC9hcHAxLXNpdGUtMSxJbnRlcm5hbC9hcHAxLXdlYi0xLEludGVybmFsL3B1Ymxpc2hlcixJbnRlcm5hbC9qd3QtMSxJbnRlcm5hbC9QbGFuWW91clRyaXBfYWRtaW4tMS4wLjAsSW50ZXJuYWwvYW5vbjEtc2l0ZS0xLEludGVybmFsL2NyZWF0b3IsYWRtaW4sSW50ZXJuYWwvcm9sZS13ZWJhcHAtMSxJbnRlcm5hbC9zdWJzY3JpYmVyLEludGVybmFsL3N0b3JlLWFkbWluLEludGVybmFsL2V2ZXJ5b25lLEludGVybmFsL2Fub24xLXdlYmFwcC0xIn0=.D17S22rLu+jjqEXrcqK9CnZuUGrIOVT7zPoUIq+AsnQTSqyUsvsR7CSvLK23w5hNrRapTgRdoCem2OxMLd3eLXZQN1mnMI4rzh+yYst8WhssPYC+RgedXf/J79PWTitg1ZJf/dogwUTx81YB7/gXlh8Tp34qf0djxVcwbpL/THA=

2. Decode and verify the signature of the extracted token
Here we are not going to focus on how to decode the token in detail. Instead we are going to user the jwt.io to decode the token and and verify the signature.

1. Copy the extracted token and paste to jwt.io debugger tool.
It will decode the token and display the header and payload of the token.but as you can see in the image signature is not verified.

jwt-io-decode-no-sig
2. Verify the signature.

By default app manager(gateway) sign the jwt token with RS256 algorithm. This information should be available in the jwt token header(“alg”: “RS256”,) .  You can find more on signature configuration here[2].

To verify the signature in jwt.io for RS256, we need to provided the certificate of gateway .

This is the default public key of carbon server.

—–BEGIN CERTIFICATE—–
MIICNTCCAZ6gAwIBAgIES343gjANBgkqhkiG9w0BAQUFADBVMQswCQYDVQQGEwJV
UzELMAkGA1UECAwCQ0ExFjAUBgNVBAcMDU1vdW50YWluIFZpZXcxDTALBgNVBAoM
BFdTTzIxEjAQBgNVBAMMCWxvY2FsaG9zdDAeFw0xMDAyMTkwNzAyMjZaFw0zNTAy
MTMwNzAyMjZaMFUxCzAJBgNVBAYTAlVTMQswCQYDVQQIDAJDQTEWMBQGA1UEBwwN
TW91bnRhaW4gVmlldzENMAsGA1UECgwEV1NPMjESMBAGA1UEAwwJbG9jYWxob3N0
MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCUp/oV1vWc8/TkQSiAvTousMzO
M4asB2iltr2QKozni5aVFu818MpOLZIr8LMnTzWllJvvaA5RAAdpbECb+48FjbBe
0hseUdN5HpwvnH/DW8ZccGvk53I6Orq7hLCv1ZHtuOCokghz/ATrhyPq+QktMfXn
RS4HrKGJTzxaCcU7OQIDAQABoxIwEDAOBgNVHQ8BAf8EBAMCBPAwDQYJKoZIhvcN
AQEFBQADgYEAW5wPR7cr1LAdq+IrR44iQlRG5ITCZXY9hI0PygLP2rHANh+PYfTm
xbuOnykNGyhM6FjFLbW2uZHQTY1jMrPprjOrmyK5sjJRO4d1DeGHT/YnIjs9JogR
Kv4XHECwLtIVdAbIdWHEtVZJyMSktcyysFcvuhPQK8Qc/E/Wq8uHSCo=
—–END CERTIFICATE—–

Copy and paste the above key  to text box which require public key in jwt.io debugger. Now as you can see in the image signature is verified
jwt-io-signature-verified

1. https://docs.wso2.com/display/APPM100/Securing+Web+Applications+Using+JWT
2. https://docs.wso2.com/display/APPM100/Passing+End+User+Attributes+to+the+Backend+Using+JWT

How to use mobile store in WSO2 APPManager without MDM

WSO2 APP Manager 1.0.0 has  feature to manage the mobiles apps. It supports to manage mobile apps under 3 categories.

  1. android apps
  2. iOS apps
  3. web apps

Steps to create  different mobile apps can be found in doc[1]

Once apps are created life cycle of apps can be managed as mentioned in the doc[2] . Apps which have life cycle status Published will appear in the store of app manager.

When select the “Mobile application” menu in the store, by default it will show all published mobile apps(image 1). if you want to browse only particular category e.g android apps. you can filter it by selecting the category in the drop down menu(image 2).

 

mobile-store

image 1

mobile-app-categories

image 2

 

Configure App Manager to Enable mobile app to download directly to the mobile device from the App Manager without MDM

  1. Stop the app manager server if it is running.
  2. Open app-manager.xml which can be found under APPMANAGER_HOME>/repository/conf directory.
  3. Find the element  <Config name=”EnableDirectDownload”> under <MDMConfig> and set its value as true .
    <Config name=”EnableDirectDownload”>true</Config>
  4. Start the app manager server

 

Now go to the store via mobile device and select the published mobile app,which will take you to the overview section of the mobile app. There you can find “install” button(image 3) ,which will let you to download the mobile app to your mobile device. Once downloaded you can install it in you device.




mobileapp-isntall image 3

 

[1]. https://docs.wso2.com/display/APPM100/Creating+Mobile+Applications

[2]. https://docs.wso2.com/display/APPM100/Mobile+Application+Lifecycle+Management

 

How to read dynamic query parameter in ESB/APIM synapse.

Following way you will be able to get the dynamic parameters
For e.g
1. My api has the following url  http://xxxx8243/uridynamic/1
2. and i have added a GET resource(uri-template) to api  /add?*
that means there can be zero or many query parameters.
3. Now my get request takes following format
4. in the sequence you can read the value of ‘a‘ and ‘b‘ as using $url
if a and b is not present in the url value of SYMBOL and value of SYMBOL2 will have
null value.
<log level=”custom”>
            <property name=”SYMBOL” expression=”$url:a“></property>
            <property name=”SYMBOL2″ expression=”$url:c“></property>
 </log>

Wso2 ESB/APIM add query parameter to endpoint

Lets say there is a http endpoint http://localhost:8080/restapi defined in a api and want to add query parameter in sequence level before invoking the endpoint.

i.e   http://localhost:8080/restapi?id=2&name=admin&role=admin

By using Property “REST_URL_POSTFIX” this can be achieved as follow.


<?xml version="1.0" encoding="UTF-8"?>
<sequence
 xmlns="http://ws.apache.org/ns/synapse" name="admin--test:v1--In">
 <log level="full">
 <property name="IN_MESSAGE" value="IN_MESSAGE"/>
 </log>
 <property name="id" value="2"/>
 <property name="name" value="admin"/>
 <property name="role" value="admin"/>
 <property name="REST_URL_POSTFIX" expression="fn:concat('?id=',$ctx:id,'&amp;name=',$ctx:name,'&amp;role=',$ctx:role)" scope="axis2"/>
 <endpoint
 xmlns="http://ws.apache.org/ns/synapse" name="HTTPEndpoint">
 <http uri-template="http://localhost:8080/restapi" method="GET"></http>
 </endpoint>
</sequence>

How to access wso2 admin service from jaggery

This post explain how to access wso2 admin service from jaggary code.

By default admin services are hidden from consumers in wso2 products. Discovering the admin service wslds of a product can be found here[1]

As an example we are going to see how to add a role to a user in any wso2 product using admin service.

1 . Create a role called “subsciber”  via admin console

2. Create a user called “jena” via admin console

3. Assign the role created in 1 to user created in 2 via admin service call.

(for this post assume step 1 and 2 are done in carbon super tenant)

For this particular scenario we need use https://localhost:9443/services/UserAdmin?wsdl. In the wsdl there is a operation called “addRemoveRolesOfUser”  which is used to add or remove roles of a user.

In order to invoke this method in jaggery code we need to know
1. Endpoint of the service
2. Request payload
3. Admin user credential of the tenant where particular user exists(admin service is protected with basic authentication)
Both can be taken from the wsdl manually or taken by creating new soap ui project using this wsld.

add_role_soapui

jaggery code – User WSRequest object[2] to send the request


<%
 var ws = require("ws");
 var version = new ws.WSRequest();
 var options = new Array();
 options.usesSOAP = 1.2;
 options.mep = "in-only";
 options.action = "urn:addRemoveRolesOfUser";
 var log=new Log();
 var username = "jena"

 var paylod = '<xsd:addRemoveRolesOfUser xmlns:xsd="http://org.apache.axis2/xsd"><xsd:userName>'+username+'</xsd:userName><xsd:newRoles>subscriber</xsd:newRoles><xsd:deletedRoles>?</xsd:deletedRoles></xsd:addRemoveRolesOfUser>';
var result;
try {
 version.open(options, "https://localhost:9443/services/UserAdmin.UserAdminHttpsSoap12Endpoint", false, "admin", "admin");
 version.send(paylod);
 } catch (e) {
 log.error(e.toString());
 }
%>

  1. https://docs.wso2.com/display/AM160/WSO2+Admin+Services
  2. http://jaggeryjs.org/documentation.jag?api=ws