Skip to Content
0
Former Member
Dec 29, 2006 at 07:42 AM

Howto decode - decrypt MYSAPSSO2 Ticket with native JAVA - (No JNI)

524 Views

Howto decode - decrypt MYSAPSSO2 Ticket with native JAVA - (No JNI)

I need to decode a Portal Ticket for a non SAP System. I was searching the

SAPNET and SDN but there was no matching Sample - nor a detailed HOWTO.

For this Reason - to save others - hours of searching i will post this Sample.

It is a plain java solution without overhead of the JNI Interface. Following the

Steps as given - you are able to decode a ticket send from your Browser to this

Java program. The sample will open a server socket port (80) and listen on it.

If the program receives a http request it will parse the request for the MYSAPSSO2

Cookie. If it found the cookie will decoded and the content is displayed at the

console.

1.)

Copy the following jar files from your local portal installation into the a new directory.

(this jars are the neccessary external resources for the java class of this example)

\usr\sap\<sid>\JC01\j2ee\cluster\server0\bin\ext\com.sap.security.api.sda\com.sap.security.api.jar

\usr\sap\<sid>\JC01\j2ee\cluster\server0\bin\ext\com.sap.security.core.sda\com.sap.security.core.jar

\usr\sap\<sid>\JC01\j2ee\cluster\server0\bin\system\logging.jar

2.)

Donwload SAP Crypot Toolkit (java) from SAP Service Portal. (the jar iaik_jce.jar is also needes as external resource for this example).

service.sap.com/swdc -> SAP Cryptographic Software -> SAP JAVA CryptoToolkit (J2EE Engine as of Release 6.30)

unpack with sapcar e.g sapcar -xvf crypttoolkit.car

you will find a new folder named jdk1.4x. rename file tc_sec_java_crypto_signed_fs_lib.sda to tc_sec_java_crypto_signed_fs_lib.zip

unzip this file.

you will find a new folder named tc_sec_java_crypto_signed_fs_lib. in this folder open the folder tools.

take the file iaik_jce.jar and copy it to the directory with the other jars. Folder was created in 1.)

3.)

Open your eclipse development environment and create a new java project named SSO.

4.)

Create a new java class named SSO.

5.)

Replace the default Code for SSO.java with this - given in this sample

6.)

Add the copied jars from point 1.) and 2.) to your Project as external Jars. (Project->Java Build Path->Libraries->Add External Jars

7.)

Compile the whole Project.

8.)

Log on to your local Portal ad Administrator to get the public Zertificate (must be stored into a local Java PSE Store).

Navigate: Systemadministration->System Configuration->Key Store.

Download File verify.der to a local directory.

unzip verify.der.zip. you will find a file called verify.der

9.)

create a local java PSE with the java keytool.

Navigate to the binaries of your local java installation directory (eg. j2sdk1.4.2\bin)

create a new PSE with this command: keytool -import -alias ep -file c:\verify.der -keystore c:\ep.pse -storepass password

You will be asked to trust the certificate in verify.der. Reply with yes.

Result: a new PSE file named ep.pse is created and the public certificate of your portal is imported.

The passord of the store is password. The password and the path to the store is used in java coding.

10.)

Open a command prompt in your in the directory where the eclipse project is stored.

start the java class with this command:

java -classpath .;iaik_jce.jar;com.sap.security.api.jar;com.sap.security.core.jar;sap.logging.jar SSO

11.)

You will find the following output onto your console

  • waiting for http request **

  • http headers of request begin *******

now logon to your local portal to get a valid cookie. (keep in mind to use a valid domain e.g. hostname.domainname.com)

after logon in the portal use the same browser and navigate via browser url to you local pc. (maybe it is necessary to add a

entry into your local hosts file to reach you local pc with a valid domain. (enter 127.0.0.1 yourlocalpc.domainname.com)

After successful connect to you pc you will get this information onto the console.

  • Ticket Content begin *******

Userid:Administrator

SystemID:J2E

Client:000

CodePage:ISO8859_1

ExpirationDate:11.7.2006

SignerCertificate:Version: 0

Serial number: 0

12.)

Thats all foks - now you have successful decoded a sap logon ticket.

  • the following lines are the source code of SSO.java

import iaik.security.provider.IAIK;

import java.io.BufferedInputStream;

import java.io.BufferedOutputStream;

import java.io.DataInputStream;

import java.io.PrintStream;

import java.net.ServerSocket;

import java.net.Socket;

import java.net.URLDecoder;

import java.security.Security;

import java.util.Calendar;

import java.util.StringTokenizer;

public class SSO {

public static java.security.cert.X509Certificate[] certificates = null;

public static Socket clientSocket = null;

// ************** get Cookie from HTTP Request ***********************

public static String getSSOCookie() {

ServerSocket serverSocket = null;

try {

serverSocket = new ServerSocket(80);

clientSocket = serverSocket.accept();

DataInputStream is =

new DataInputStream(

new BufferedInputStream(clientSocket.getInputStream()));

String inLine = new String();

String Cookie = new String();

while (true) {

inLine = is.readLine();

if (inLine.length() == 0)

break;

System.out.println(inLine);

if (inLine.substring(0, 7).compareToIgnoreCase("Cookie:")

== 0) {

StringTokenizer st =

new StringTokenizer(inLine.substring(7), ";");

while (st.hasMoreTokens()) {

Cookie = st.nextToken();

if (Cookie

.substring(0, 10)

.compareToIgnoreCase(" MYSAPSSO2")

== 0) {

Cookie = Cookie.substring(11);

String base64Value =

URLDecoder.decode(Cookie, "UTF-8");

return (base64Value);

}

}

}

}

is.close();

} catch (Exception e) {

System.err.println("Exception: " + e);

e.printStackTrace();

}

return ("* no MYSAPSSO2 Cookie found *");

}

// ****************** load Certificates from PSE ***************

public static void loadCertsFromPSE(String pse, String pwd) {

char passwd[] = pwd.toCharArray();

java.io.InputStream stream = null;

java.util.ArrayList certs = new java.util.ArrayList();

try {

stream = new java.io.FileInputStream(pse);

java.security.KeyStore store =

java.security.KeyStore.getInstance("JKS", "SUN");

store.load(stream, passwd);

java.util.Enumeration enu = store.aliases();

while (enu.hasMoreElements()) {

String alias = (String) enu.nextElement();

if (store.isCertificateEntry(alias)) {

certs.add(store.getCertificate(alias));

}

}

stream.close();

if (certs.size() < 1) {

System.out.println("PSE does not contain any certificates");

}

System.out.println(certs.toString());

certificates =

(java.security.cert.X509Certificate[]) certs.toArray(

new java.security.cert.X509Certificate[0]);

} catch (Exception e) {

}

}

public static void sendResponse(String portalUser) {

try {

PrintStream os =

new PrintStream(

new BufferedOutputStream(clientSocket.getOutputStream()),

true);

os.print("HTTP/1.1 200 OK \n");

os.print("Content-Type: text/html \n");

os.print(

"<html><head><title>Ticket Response</title></head><body>\n");

os.print("Userid from Ticket:" + portalUser + "\n");

os.print("</body></html>\n");

os.close();

} catch (Exception e) {

}

}

//*********** main *************************************

public static void main(String[] args) {

System.out.println("** waiting for http request ** ");

System.out.println("***** http headers of request begin *******");

String Cookie = getSSOCookie();

System.out.println("***** http headers of request end *******" + "\n");

System.out.println(

"***** extracted MYSAPSSO2 Cookie begin (as UTF-8 encoded) *******");

System.out.println(Cookie);

System.out.println(

"***** extracted MYSAPSSO2 - Cookie end *******" + "\n");

System.out.println("***** loading certs from pse begin *******");

loadCertsFromPSE("c:
ep.pse", "password");

System.out.println("***** loading certs from pse end *******" + "\n");

IAIK provider = new IAIK();

Security.addProvider(provider);

com.sap.security.core.ticket.imp.Ticket ticket =

new com.sap.security.core.ticket.imp.Ticket();

try {

ticket.setCertificates(certificates);

ticket.setTicket(Cookie);

ticket.verify();

com.sap.security.api.ticket.InfoUnit iu = ticket.getInfoUnit(0x20);

String portalUser = new String();

if (iu != null) {

String portal_user = iu.getString("UTF8");

portalUser = portal_user.substring(7);

}

System.out.println("***** Ticket Content begin *******");

System.out.println("Userid:" + portalUser);

System.out.println("SystemID:" + ticket.getSystemID());

System.out.println("Client:" + ticket.getSystemClient());

System.out.println("CodePage:" + ticket.getCodepage());

Calendar cal = ticket.getStartValidDate();

System.out.println(

"StartValidDate:"

+ cal.get(Calendar.DATE)

+ "."

+ cal.get(Calendar.MONTH)

+ "."

+ cal.get(Calendar.YEAR)

+ "/"

+ cal.get(Calendar.HOUR)

+ "."

+ cal.get(Calendar.MINUTE)

+ "."

+ cal.get(Calendar.SECOND)

+ "_"

+ cal.get(Calendar.AM_PM));

cal = ticket.getExpirationDate();

System.out.println(

"ExpirationDate:"

+ cal.get(Calendar.DATE)

+ "."

+ cal.get(Calendar.MONTH)

+ "."

+ cal.get(Calendar.YEAR)

+ "/"

+ cal.get(Calendar.HOUR)

+ "."

+ cal.get(Calendar.MINUTE)

+ "."

+ cal.get(Calendar.SECOND)

+ "_"

+ cal.get(Calendar.AM_PM));

System.out.println(

"SignerCertificate:" + ticket.getSignerCertificate());

System.out.println("***** Ticket Content end *******");

sendResponse(portalUser);

} catch (Exception e) {

System.out.println(e);

}

}

}