My favorites | Sign in
Project Home Downloads Wiki Issues Source
Search
for
SAcctUserGuide_0_1_0  
SAcct 0.1.0 User Guide.
Phase-Support, Featured
Updated Jul 8, 2009 by John.Jian.Fang@gmail.com

Introduction

In the Payment Card Industry (PCI), security is always a major concern. A lot of enterprise applications have application passwords hard-coded in configuration files, which are not allowed by the Payment Card Industry Data Security Standard (PCI DSS). Smart Account Management (SAcct) is a light-weight Security Framework to ease your pain of removing the account passwords from application configuration files. The SAcct server reads in the account information from a secured soft token and acts as an account server. The SAcct client communicates with the SAcct Server over a secured channel to retrieve account passwords on behalf of the application on start-up. In this way, you also gain the benefit that you have a central place to manage your application accounts.

Key Words

Security, Password, Application Account, Encrypt, Decrypt, Diffie-Hellman Key Exchange, One Time Password, PCI Compliance, JSON, Java, Spring, Guice, Maven.

Problems and Challenges

Take a Spring application as an example, the following wiring file includes a database user name and a user password,

    <bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">
        <property name="driverClassName" value="${jdbc.driverClassName}"/>
        <property name="url" value="${jdbc.url}"/>
        <property name="username" value="${jdbc.username}"/>
        <property name="password" value="${jdbc.password}"/>
        <property name="maxActive" value="100"/>
        <property name="maxWait" value="1000"/>
        <property name="poolPreparedStatements" value="true"/>
        <property name="defaultAutoCommit" value="true"/>
    </bean>

To put the database user password into the configuration file is a serious security problem and it is not allowed by the Payment Card Industry Data Security Standard (PCI DSS). Some frameworks try to encrypt the passwords, but they still need to wire in the encryption password, which does not really solve the problem. We propose to store the accounts in a secured token file, which you can put into a USB drive or other secured devices, then the SAcct framework can retrieve them on behalf of the application during the application start-up phase.

SAcct Features

SAcct is a Java application and suitable for Enterprise Java applications. SAcct features are highlighted as follows,

  • Light-Weight
  • Use Google Guice as the dependency injection framework for the SAcct Server
  • Account information are encrypted and stored as a soft token on a carry on device
  • Utility tools are provided to encrypt and decrypt the soft token
  • Use the Diffie-Hellman key exchange protocol to derive the session key
  • The communications between the SAcct Server and the SAcct Client are encrypted by the session key
  • An One Time Password (OTP) is used to prevent session replay attack
  • All encryptions use the Advanced Encryption Standard (AES) algorithm
  • Spring support
  • Many security utility classes

SAcct Modules

The SAcct 0.1.0 code structure is as follows,

sacct-0.1.0
|-- assembly
|   `-- sacct-server
|-- sacct-client
|-- sacct-common
|-- sacct-server
`-- tools
    `-- sacct-spring

SAcct 0.1.0 includes the following modules

  • sacct-common: common and shared classes between the SAcct server and the SAcct client.
  • sacct-server: SAcct server is a standalone Java application.
  • sacct-client: SAcct client acts as a client stub communicate with the SAcct server.
  • tools/sacct-spring: Utility classes for the Spring framework.
  • assembly/sacct-server: SAcct server Maven assembly project

SAcct Architecture

The SAcct architecture is shown in the following diagram,

SAcct Server

The SAcct server is a standalone Java application and it listens on a TCP port for requests. Upon receiving a request, it creates a socket worker from the thread pool to process the request.

The SAcct server mainly consists of the following components:

  • Session Manager: create a session key for each connection based on the Diffie-Hellman Key Exchange protocol. It also generates a session id and maintains the sessions in the cache.
  • Account Manager: read account data from the account token file and service client account requests.
  • Connector: read requests from the client and write the responses back to the client. Another function is to decrypt requests and encrypt response. As shown in the above diagram, the responses are all encrypted with the AES algorithm except the initial handshake messages.

SAcct Client

The SAcct client is usually one part of the business application. It derives the session key by exchanging information with the SAcct server based on the Diffie-Hellman Key Exchange protocol and then stores the session information in a token. The SAcct client also includes a socket connector to communicate with the SAcct server. All requests are encrypted except the session id as shown in the above system diagram. Be aware, there is no key transmitted over the socket channel. The SAcct server and the client derive the same key on their own based on the Diffie-Hellman Key Exchange protocol.

Message Formats

The client request is represented by the Request Java class

public class Request {
    //a random string padding to the request
    private String rnd;

    private String command;

    private RequestContext requestContext;

    private List parameters;
}

where the RequestContext is defined as

public class RequestContext {

    private String locale;

    private String clientId;

    //Use One Time Password sequence in the requestId to prevent session replay attack
    private String requestId;
}

and the command is the service call name, which will be described later.

The actual request being sent over the socket channel is the SecureRequest

public class SecureRequest{
    private String sessionId;

    private String request;

Where the original request is first converted into a JSON string, compressed, encrypted with the session key, and then encoded in the base 64 format.

Similarly, the response class is defined as follows,

public class Response extends Entity {
    //a random string padding to the response
    private String rnd;

    private String command;

    private boolean isSuccessful;

    private String errorCode;

    protected List returnValue;
}

The SAcct server will convert any exception to the isSuccessful flag and the error code so that the client knows how to react to different exceptions. The response is also converted to a JSON string, compressed, encrypted, and then encoded in the base 64 format.

public class SecureResponse {

    private String response;
}

Services

The SAcct server provides two services, i.e., SessionService and AccountService. The SessionService is used to initiate and close sessions.

public interface SessionService extends Service{

    SessionInfo handshake(RequestContext context, String clientPubKey);

    String closeSession(RequestContext context, String goodbye);

    String hello(RequestContext context);
}

and AccountService handles all account-related requests.

public interface AccountService extends Service{

    ApplicationAccount fetchAccount(RequestContext context, String account);

    List<ApplicationAccount> fetchAllAccounts(RequestContext context);
}

Communication Flows

Let's look a bit closer at the communication flows in the architecture diagram.

  1. handshake request: The client generates two big numbers, Cr as the private key, Cp as the public key, and initiates the connection by sending the public key Cp to the SAcct server.
  2. handshake response: Upon receiving the client request, the SAcct Server generates its own private key Sr and public key Sp. In the meanwhile, it derives a secret key as the session key based the client's public key Cp and its own keys. Then the SAcct server responds back to the client with its public key Sp and a random session id.
  3. account service request: The client derives the same secret key after received the server's public key Sp and starts to send a secured service request to the server using the session key.
  4. account service response: The SAcct server decrypts the request and replies back the encrypted service response with the session key.
  5. closeSession request: The client finishes its job and sends a closeSession request to the SAcct server.
  6. closeSession response: The SAcct server replies back and the client closes the socket connection.

The communication flows can be better illustrated by the following sequence diagram,

Apart from the above message flows, the SAcct server also provides a hello service call for the client to do health check with the server.

Account Token

The SAcct server reads in the account token on start-up. The plain text token is in the JSON format:

{
   "records" :
      [
         {
            "accounts" :
               [
                  {
                     "name" : "custApp",
                     "password" : "PwD4CustApp"
                  },
                  {
                     "name" : "prodApp",
                     "password" : "PwD4ProdApp"
                  }
               ],
            "clientId" : "server"
         },
         {
            "accounts" :
               [
                  {
                     "name" : "johnfang@mycompany.com",
                     "password" : "P@ssword"
                  },
                  {
                     "name" : "johnfang@myhome.com",
                     "password" : "P@ssw0rd"
                  }
               ],
            "clientId" : "jianfang"
         }
      ]
}

For each client, you need to provide a client id and then add the account information into the token file. SAcct provides two utility scripts, i.e., encrypt and decrypt, for you to encrypt and decrypt the account token file.

The encrypted token file looks like the following string,

CnUWakPDCwjhYijf7cyxw0ScugrHuWFkv+4LV8TJnn5kK8/o25lWBnHgc0JuQOLXhO/Dc71vF4jAKiiQl7EHc5/gFF5+r9G/TmXBx6kkynfuh8giq2TISxgatlp/gpxbzEs9SZ9kF1iYaH20TgZq/zpbPXc0+HIefwIT9VjW8deUrr9h/0b/qHb9NVFJ438gK4T/u6pqxxeGDmYIzQkWZg==

How to Obtain SAcct

Direct Download

SAcct includes two parts, i.e., SAcct Server and SAcct client. You should download the SAcct server and other jar files from the SAcct download page.

For a regular Java application, you will need the following jar files

  • sacct-common-0.1.0.jar
  • sacct-client-0.1.0.jar
  • sacct-0.1.0-dependency.zip, which includes Guice, Log4J, commons-codec, and JSON libraries.

For a Spring application, you need one more extra jar file

  • sacct-spring-0.1.0.jar

Maven

To obtain SAcct from Maven, you need to add SAcct Maven repositories to your Maven settings.xml or your project POM file.

        <repository>
            <id>kungfuters-public-releases-repo</id>
            <name>Kungfuters.org Public Releases Repository</name>
            <url>http://kungfuters.org/nexus/content/repositories/releases</url>
        </repository>
        <snapshotRepository>
            <id>kungfuters-public-snapshots-repo</id>
            <name>Kungfuters.org Public Snapshot Repository</name>
            <url>http://kungfuters.org/nexus/content/repositories/snapshots</url>
        </snapshotRepository>

For a regular Java application, please include the following Maven dependencies

        <dependency>
            <groupId>commons-codec</groupId>
            <artifactId>commons-codec</artifactId>
            <version>1.3</version>
        </dependency>
        <dependency>
            <groupId>caja</groupId>
            <artifactId>json_simple</artifactId>
            <version>r1</version>
        </dependency>
        <dependency>
            <groupId>org.stringtree</groupId>
            <artifactId>stringtree-json</artifactId>
            <version>2.0.10</version>
        <dependency>
            <groupId>org.osomit</groupId>
            <artifactId>sacct-common</artifactId>
            <version>0.1.0</version>
        </dependency>
        <dependency>
            <groupId>org.osomit</groupId>
            <artifactId>sacct-client</artifactId>
            <version>0.1.0</version>
        </dependency>

For a Spring application, you need the following extra dependency

        <dependency>
            <groupId>org.osomit</groupId>
            <artifactId>sacct-spring</artifactId>
            <version>0.1.0</version>
        </dependency>

How to Use SAcct

SAcct Server

Prerequisites

Since SAcct uses the AES algorithm for encryption, you need to use Java 6 and download it from the Sun JDK download page. On the same page, you also need to download Java 6 Cryptography Extension (JCE) Unlimited Strength Jurisdiction Policy Files in the Other Downloads section. Then unzip the file jce_policy-6.zip and move local_policy.jar and US_export_policy.jar to JAVA_HOME/jre/lib/security.

Structure

The SAcct Server is a standalone Java application and the application structure is listed as follows,

sacct-server-0.1.0/
|-- LICENSE.txt
|-- README.txt
|-- bin
|   |-- decrypt
|   |-- encrypt
|   `-- sacct_server
|-- conf
|   |-- log4j.xml
|   `-- sacct.properties
|-- data
|   `-- accounts.reg
|-- lib
|   |-- antlr.jar
|   |-- aopalliance.jar
|   |-- avalon-framework.jar
|   |-- commons-codec.jar
|   |-- commons-logging.jar
|   |-- guice.jar
|   |-- json_simple.jar
|   |-- jsontools-core.jar
|   |-- log4j.jar
|   |-- logkit.jar
|   |-- sacct-common.jar
|   |-- sacct-server.jar
|   `-- stringtree-json.jar
`-- logs
    `-- sacct.log

The conf directory includes the SAcct global configuration file, sacct.properties, and Log4J configuration file, log4j.xml. The data directory includes a sample account token, accounts.reg, which is encrypted using the AES algorithm with the default password P@ssw0rd.

Manage the Account Token

The bin directory includes two utility scripts, encrypt and decrypt, for you to manage the soft token file. For example, use the following command to decrypt the account token file,

./decrypt ../data/accounts.reg accounts.txt

You will see the decrypted account file in the JSON format. You can update the plain text token file and encrypt it again.

./encrypt accounts.txt accounts.reg

Then replace the old token file with the new one

mv accounts.reg ../data/accounts.reg

Remember to remove the plain text token file after you are done.

rm accounts.txt

Configure the Server

The SAcct server configuration file, sacct.properties, is pretty simple and self-explaining,

useOTP = false         <---Whether to use One Time Password to prevent session replay attack
sessionExpirationPolicy = IdleTimeout <-- This is the only option now
idletimeInMilliSeconds = 3000000  <--- Session maximum idle time in milliseconds
maxSessionNum = 200               <--- Maximum concurrent sessions
numToCleanSession = 25            <--- Clean up the session when the session number is builtup
accountFileName = accounts.reg    <--- Account token file
serverPort = 9000                 <--- SAcct server service port 
poolSize = 12                     <--- Thread pool size
randomIdLength = 12               <--- Session Id random part size

Be aware, if you turn on the One Time Password (OTP), SAcct client must also turn on this feature.

Start the Server

Go to the bin directory and run

./sacct_server

You can simply use Contrl+C to stop the server. The SAcct server shutdown hook will do all the cleanup work before it exits.

Windows System

The shell scripts are for Unix/Linux systems. If you need to run the SAcct Server in a Window system, you can create the Window batch scripts very easily based on these scripts.

SAcct Client

Account Provider

The Account Provider is an abstraction of the SAcct client and the interface is defined as,

public interface AccountProvider {
    
     public boolean isActive();

     public String getAccountPassword(String accountName);
}

The account provider implementation also need to implement the following AccountProviderCifeCycle interface,

public interface AccountProviderLifeCycle {
    
    public void create();

    public void destroy();
}

Regular Java Applications

For regular Java applications, SAcct provides a default Account Provider implementation, org.osomit.sacct.provider.imp.AccountProviderImpl, which has the following constructor

public AccountProviderImpl(String clientId, String accountServerHost, int accountServerPort, boolean useOTP, boolean isActive)

The AccountProviderImpl class provides the follow methods at your disposal,

public void create();

public boolean isActive(); 

public String getAccountPassword(String accountName);

public void destroy();

Spring Applications

The sacct-spring module provides two factory beans for the Spring framework, i.e., AccountProviderFactoryBean and AccountFactoryBean. The AccountProviderFactoryBean is an encapsulation of the SAcct client and is responsible for communicating with the SAcct server to retrieve application accounts. It also handles the account provider lifecycle, i.e., create and destroy, automatically.

The constructor of the SAcct account provider factory bean is defined as follows,

public AccountProviderFactoryBean(String clientId, String accountServerHost, int accountServerPort, boolean useOTP, boolean active)

In your Spring application, you can define the account provider similar to the following Spring bean.

    <bean id="accountProvider" class="org.osomit.sacct.provider.impl.spring.AccountProviderFactoryBean">
        <constructor-arg index="0" type="java.lang.String" value="server"/>   <-- Client ID
        <constructor-arg index="1" type="java.lang.String" value="localhost"/>  <-- SAcct Server Host
        <constructor-arg index="2" value="9000"/>    <-- SAcct Server Port
        <constructor-arg index="3" value="false"/>   <-- Wheather to Use One Time Password
        <constructor-arg index="4" value="false"/>   <-- Is active?
    </bean>

The AccountFactoryBean is used to provide the application password for an individual account. What it really does is to fetch the account information from the AccountProviderFactoryBean and its constructor is shown as follows,

public AccountFactoryBean(AccountProvider provider, String accountName, String accountPassword)

Optionally, you can provide the default/dummy password in the certain situations that the SAcct is not available.

    <bean id="databasepassword" class="org.osomit.sacct.provider.impl.spring.AccountFactoryBean">
        <constructor-arg index="0" ref="accountProvider"/>    <-- Account Provider
        <constructor-arg index="1" value="${jdbc.username}"/>  <-- Account Name
        <constructor-arg index="2" value="defaultDataBasePwD"/>  <-- Account default/dummy password (optional)
    </bean>

Finally, the dataSource bean can be rewritten as

    <bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">
        <property name="driverClassName" value="${jdbc.driverClassName}"/>
        <property name="url" value="${jdbc.url}"/>
        <property name="username" value="${jdbc.username}">
        <property name="password" ref="databasepassword"/> <-- Provide Data Source Password
        <property name="maxActive" value="100"/>
        <property name="maxWait" value="1000"/>
        <property name="poolPreparedStatements" value="true"/>
        <property name="defaultAutoCommit" value="true"/>
    </bean>

As you can see, you can turn off SAcct and switch back to original Spring wiring in some situation simply by setting the active flag in the "accountProvider" bean to be false. That's all and you do not need to change any other bean configuration.

Resources


Sign in to add a comment
Powered by Google Project Hosting