Tag: Java Security

When it comes to application security,  Secure coding is the first line of defense….and it is very critical to follow the best practice patterns and avoid pitfalls to secure the application from known risks and vulnerabities. The Java Security team has just released the updated – “Secure Coding Guidelines for the Java Programming Language, Version 3.0“ .  Certainly it included a newer set of fundamentals and enhanced set of secure coding guidelines.  

 A must have URL for your quick reference…if you are a security conscious developer !

Onlinerel Facebook Twitter Myspace Friendfeed Technorati del.icio.us Digg Google Yahoo Buzz StumbleUpon

Java EE 6 RI was released few weeks ago….I am bit late to have my first look :-)   Without a doubt, the new Web container security enhancements are very compelling for any budding or experienced Java developer working on Web applications. The Java EE 6 has unveiled several new security features with ease of use and targetted for simplified Web application security deployments. Based on Servlet 3.0 specification, the Java EE 6 Web applications can take advantage of an enriched set of programmatic and declarative security features and Security annotations previously available to EJB 3.x applications. Also, the deployed Web applications/Web Services can use JSR-196 based pluggable authentication/authorization modules (based on SOAP Web Services) that can be configured as part of the Servlet container.

 

 Java EE 6 : Programmatic Security for Web Applications

The newly introduced Java EE 6 programmatic security features for Web applications are represented by the following methods of HttpServletRequest interface:

 

1. authenticate()

  • This method helps to initiate authentication of the calling user by launching an authentication dialog for acquiring username/password and perform BASIC authentication by the container within an unconstrained request context.

import java.io.*;
import javax.servlet.*;
import javax.servlet.http.*;

 

public class MyAuthServlet extends HttpServlet {

 

protected void processRequest(HttpServletRequest request, HttpServletResponse response)

                     throws ServletException, IOException {

            response.setContentType(“text/html;charset=UTF-8″);
            PrintWriter out = response.getWriter();

   try {

     //Launch the BASIC authentication dialog
                request.authenticate(response);
                     out.println(“Authenticate Successful”);

            } finally {

                          out.close();

         }

 

          public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {

                   processRequest(request, response);

        }

 

           public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {

                processRequest(request, response);

          }

}

 

 

2. login() and logout ()

  • The login() method allows to programmatically collect with the provided username/password credentials (as an alternative to FORM-based authentication) and perform user authentication.
  • The logout() method performs logging out the user and resets the context.

 
import java.io.*;
import javax.servlet.*;
import javax.servlet.http.*;

 

public class MySecurityServlet extends HttpServlet {

 

protected void processRequest(HttpServletRequest request, HttpServletResponse response)

                                                   throws ServletException, IOException {

   response.setContentType(“text/html;charset=UTF-8″);
   PrintWriter out = response.getWriter();

   try {

              String myUsername = request.getParameter(“UserName”);
             String myPassword = request.getParameter(“Password”);

           try {

                 request.login(myUsername, myPassword);

                   } catch(ServletException ex) {

                            out.println(“Login Failed” + ex.getMessage());

              return;

     }

    }   catch (Exception e) {

                 throw new ServletException(e);

            } finally {

                request.logout();
              out.close();

             }

     }

      public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {

             processRequest(request, response);

        }

      public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {

              processRequest(request, response);

      }

}

 

The above code assumes the authentication is configured to BASIC by setting the login-config element in web.xml. If the authentication is the successful, the Web application can take advantage of the following methods in the HttpServletRequest interface to identify the remote user, role attributes and to perform business logic decisions.

 

3. getRemoteUser()

  • Determines the authenticate username of the remote user associated with the request. If no authentication occured, it will return a null value.

4. IsUserInRole(..rolename..)

  • Determines whether the authenticated user is in a specified security role. If the user is not authenticated, it returns false.

5. getUserPrincipal()

  • Determines the principal name that represents the authenticated user entity (name of the remote user) and returns a java.security.Principal object corresponding to the user.

Here is my sample code that I tested it on Glassfish v3 (Developer Sample):

 

 

import java.io.*;
import javax.servlet.*;
import javax.servlet.http.*;
import javax.servlet.annotation.WebServlet;
import javax.annotation.security.DeclareRoles;

 

  //Annotation for defining the Servlet name and its URL pattern
  @WebServlet(name=”MySecurityServlet”, urlPatterns={“/MySecurityServlet”})

 

  // Annotation for declaring roles
   @DeclareRoles(“securityguy”)

public class MySecurityServlet extends HttpServlet {

 

              protected void processRequest(HttpServletRequest request, HttpServletResponse response) 

                                   throws ServletException, IOException {

 

                                     response.setContentType(“text/html;charset=UTF-8″);
                                     PrintWriter out = response.getWriter();

               try {

                                    String myUsername = request.getParameter(“UserName”);
                                    String myPassword = request.getParameter(“Password”);

              try {

                                   request.login(myUsername, myPassword);

                                  }      catch(ServletException ex) {

                                   out.println(“Login Failed” + ex.getMessage());

                                   return;

                   }

                                              out.println(“The authenticated user is in Role: ” + request.isUserInRole(“securityguy”));
                                              out.println(“The authenticated remote username: ” + request.getRemoteUser());
                                             out.println(“The authenticated Principal name: ” + request.getUserPrincipal());
                                             out.println(“The authentication type: ” + request.getAuthType());

                   } catch (Exception e) {

                                  throw new ServletException(e);

                }  finally {

                                request.logout();

                                out.close();

             }

   }

       public void doGet(HttpServletRequest request, HttpServletResponse response)  throws ServletException, IOException {

                    processRequest(request, response);

        }

        public void doPost(HttpServletRequest request, HttpServletResponse response)  throws ServletException, IOException {

                   processRequest(request, response);

      }

}
 

To test the code, it is assumed that you have the Java EE runtime deployment descriptor include the appropriate role mapping that associated the user with the specified role-name.

 

Security Annotations for the Web Applications

With Servlet 3.0 implementation, we would able to use standard Java annotations for declaring security constraints as equivalent to those defined in a standard Web deployment descriptor (web.xml). With Security annotation you should able to define roles, access control to HTTP methods, transport-layer protection (for enforcing SSL/TLS). To make use of security annotations in Servlets, Servlet 3.0 has introduced @ServletSecurity annotation to support defining security constraints.

 

Using @ServletSecurity

 

The @ServletSecurity annotation allows to define the security constraints as its fields:

  1. @HttpConstraint  – Used as a field of @ServletSecurity to specify roles to all methods and ensure transport-layer security)
    • ex.  @ServletSecurity(@HttpConstraint(rolesAllowed={“customer”})) - Ensures all HTTP methods (GET, POST, TRACE) are protected and access is allowed to security role “customer”.
    • ex. @ServletSecurity(@HttpConstraint(transportGuarantee=ServletSecurity.TransportGuarantee.CONFIDENTIAL)) – Ensures all methods require SSL transport
  2. @HttpMethodConstraint (Applied to define methods ex. GET, POST, TRACE)
    • ex. ServletSecurity(value=@HttpConstraint(httpMethodConstraints={ @HttpMethodConstraint(value=”POST”, transportGuarantee=ServletSecurity.TransportGuarantee.NONE, rolesAllowed={“customer”}) })  – Ensures only authenticated users with security role is allowed to access HTTP POST method and transport-layer security/SSL is supported but not required.
  3. @DeclareRoles (Allows to define security roles)
  4. @RoleAllowed (Allows to define authorized roles)

Here is a quick usage scenario of @ServletSecurity annotation (Developer Sample):

 import java.io.*;
 import javax.servlet.*;
 import javax.servlet.http.*;
 import javax.annotation.security.*;
 @DeclareRoles("customer","guest")
 @ServletSecurity(@HttpConstraint(rolesAllowed={"customer"}))
 public class MyHelloWorld extends HttpServlet {
     public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    PrintWriter out = response.getWriter();
    out.println("Hello World");
  }
  public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    response.setContentType("text/html");
    PrintWriter out = response.getWriter();
     out.println("Hello World");
     out.close();
  }
}  
 

Sometimes, it’s the small things that make even complex things much easier. Way to go…Java EE 6 ! 

 

Here is couple of references, you may consider to explore Java EE 6:

Java EE 6: New Enhancements

Glassfish v3/Java EE 6 Sample Applications

 

Enjoy :-)

Onlinerel Facebook Twitter Myspace Friendfeed Technorati del.icio.us Digg Google Yahoo Buzz StumbleUpon

Java Card technology has been a passion of mine for so long and I always tried my best to keep updated on Smart card technologies…… not just because of my role at Sun, I did get several opportunities to work closely with citizen-scale Java Card deployments with multiple National ID, eID/ICAO, US DoD/CAC, PIV/FIPS-201 cards and related Identity management projects.  It is always been quite adventurous everytime to experience a card issuance architecture and deployment scenario – right from applicant enrollment, demographic data provisioning, Biometrics/PKI credentialing, adjudication/background checks, post-issuance maintenance including card authentication/verification/usage and final retirement/termination.  In the early 2000′s, I even had an opportunity to write couple of Java Card applets for a big 5 financial organization using Java Card 2.x and it is still exists on production (No kidding! one of them may be in your wallet). With all those experiences, I did have my own stumbling issues with programming Smartcards, where I pulled my hair-out on understanding those evil ”Application Protocol Data Units” (APDU) based commands and responses. In my opinion, APDUs are quite complex to understand when you jump in unless you read the docs in-and-out beforehand and then test-driving APDUs are even more hard unless you have the luxury of having a debugging environment –  seriously, you may not want to experience those pains.  Havingsaid, now we can breathe a sigh of relief – I am bit late to experience the newer features of Java Card 3.0 -  It has introduced “network-centric” and “Java/J2EE developer” friendly features that radically changed the way we originally designed, developed, deployed, and integrated Smartcard applications.  Interestingly, there are very compelling aspects about Java Card 3.0 technology -  As I digged with my little experience… here is my observations.  

 

Understanding Java Card 3.0  

  1. A Smartcard can act as a ”Personal Web Application Server”  or an user-centric miniature Java EE application server on a network.  Java Card 3.0 has introduced a Servlet container environment referred to as “Connected Edition” – which allows the smartcard applications can built as Java servlets (Web applications) using Servlet 2.4 APIs and deployed as a “WAR” file to the Web container running on a Java Card 3.0 compliant Smart card. This Servlet based deployment is an addition to existing Java card applet deployment model referred to as Classic Edition (exists with Java card 2.2.x). The Java Card clients access the applications using a Web browser (ex. http://localhost:8019/myJavaCardServlet).   
    Java Card Platform - Architecture

    Java Card Platform - Architecture

  2. Java Card 3.0 supports 32-bit processor based Smartcards and handles more memory – upto 128k.
  3. Enough with pain of understanding/testing APDUs, now you can readily develop Java Servlet 2.4 API compliant Web applications and deploy them to a Smart card.
  4. With Java Card 3.0, we can perform interact with using standards based communication with the card using HTTP/HTTPS and also its supporting XML based protocols such as SOAP, REST etc.
  5. Support for Java crypto APIs and additionally you can enable access control with the card similiar to performing container-managed authentication in Java EE – using SSL/TLS mechanisms.     

    Java card 3.0 - Communication Protocols

    Java card 3.0 - Communication Protocols

     

     

  6. Java Card 3.0 based Web applications can be developed, debugged and deployed using Netbeans 6.7.1 and up.
  7. Smart card issuance (for Card holders) and updates using GCF can be done through Web based deployment model (via HTTP, TCP) – using both contact and contactless communication interfaces.
  8. Other features include full Java language support (Java 1.6 features) including all data types (except float and double), multi-threading, garbage collection, XML parsing/generation capabilities etc.
  9. Allows Java developers to explore Java Card platform easily with strong potential for deploying security applications intended for National ID card schemes, passports and simplifying deployment of  ”Match-to-card Biometrics”, “On-card” credential persistence and secure transaction based applications.

 

Try it yourself

If you are curious to test drive Java Card 3.0 reference implementation especially using its “Connected Edition” to deploy Java Servlet based application to Smart card - Before you begin, make sure you obtain the list of pre-requistes :

  1. Java Card Connected Development Kit 3.0.1
  2. Netbeans 6.7.1

and then proceed with the following steps for deploying a “Hello World” Web application – creating Java card applications can’t get easier than this :

  1. Install the Java Card 3.0 plugins for Netbeans 6.7.1 – Go to Tools, Plugins and search for card to select plugins for “Java Card Projects” and “Java Card Console”.  
    Installing Java Card plugins for Netbeans
    Installing Java Card plugins for Netbeans

     

  2.  Go to Netbeans IDE,  Choose Project – “Java Card” and select Projects type “Web Project”. 
    Creating a Java Card "Web Project"

    Creating a Java Card "Web project"

  3.  Assign Project name/location/folder and then select “Manage Platforms” to assign the Java Card 3.0 runtime environment.   

     

     

    Assigning "Java Card" runtime environment

    Assigning Java Card Runtime Info

     

     

  4.  To assign the Java Card runtime info, select “Manage Platforms” and choose “Platform type” to Java Card Platform.  
    Choosing "Java Card" runtime environment

    Choosing Java Card as runtime

  5.  Select the location of your ”Java Card 3.0 Connected Edition Dev kit” installation. 

      

     

    Select "Java Card 3.0 Connected Edition Dev Kit" folder

    Select "Java Card 3.0" Connected Edition

     

  6.  Define the default device (assuming your Smartcard) attributes and press “Finish”: 
    Select your "Java Card"

    Select your "Java Card"

     

  7.  As a result, you should see the Netbeans console showing your “Java Card Platform” environment for test-driving your applications.     
  8. With above steps complete, now you are ready to develop/debug/deploy your Java Card web applications…. here is my first “Hello World” Java Card Web application excercise.       
  9.  Compile the application -  In the Projects window, right-click the project node and choose Build to build the project.     
  10. To deploy and run the Web application from your target Smartcard device (in my case the JavaCard RI), In the Projects window, right-click the project node and choose Load/Create Instance or just Run to run the application.  Netbeans will launch the browser, displaying the Hello world application prompting for your name….  and push the button to see – what happens !    

Netbeans does all the magic for you – if something not working, no worries ! Like implementing anyother Web application in IDE,  it is now easy for you to painlessly debug and redeploy the application – I am sure, you’ll find deploying applications on Java Card is nolonger a mystery.

 

With Billions+ Java Cards already in use and so much demand for the Smartcard technology,  Java Card 3.0 promises beyond citizen IDs and can potentially act as your “Personal Web application server” on your wallet.

 

Thanks to Anki Nelaturu and Saqib Ahmad who introduced me to Java Card 3 with their JavaOne ’09 sessions. After playing with my first excercise on Java Card 3.0 RI, now I am chasing my friendly Smartcard vendors to loan me couple of Java Card 3.0 cards :-)

Onlinerel Facebook Twitter Myspace Friendfeed Technorati del.icio.us Digg Google Yahoo Buzz StumbleUpon

FIPS-140* compliance has gained overwhelming attention these days and it has become a mandatory requirement for several security sensitive applications (mostly in Government and Security solutions and recently with select finance industry solutions and particularly for achieving compliance with regulatory mandates such as PCI DSS, FISMA, HIPPA, etc ). FIPS-140 also helps defining security requirements for supporting integration with cryptographic hardware and software tokens.  Ensuring FIPS compliance to Java based application security has been one of demanding needs of security enthusiasts but unfortunately neither Sun JCE or JSSE is not yet FIPS-140 certified – hopefully soon !  Sun JDK 6 (and above) has also introduced several enhancements including support for enabling FIPS-140 compliance for Sun JSSE using FIPS-140 certified cryptographic providers for supporting SSL/TLS communication and associated cryptographic operations. To accomplish this, Java 6 uses the PKCS#11 support for JSSE to integrate with PKCS#11 based FIPS-140 cryptographic token.

 

Lately I worked on a security solution using SunJSSE with NSS as a software cryptographic token… and here is my tipsheet for those keen on playing FIPS conformance with SunJSSE.

 

  • SunJSSE can be configured to run on FIPS-140 compliant mode as long as it uses a FIPS-140 certified cryptographic hardware or software provider that implements all cryptographic algorithms required by JSSE  (ex. Network Security Services – NSS, Sun Cryptographic Accelerator 6000, nCipher, etc).

 

  • To enable FIPS mode, edit the file ${java.home}/lib/security/java.security and modify the line that lists com.sun.net.ssl.internal.ssl.Provider and associate the name of the FIPS-140 cryptographic provider (ex. SunPKCS11-NSS). The name of the provider is a string that concatenates the prefix SunPKCS11- with the name of the specified PKCS#11 provider in its configuration file.

                            security.provider.4=com.sun.net.ssl.internal.ssl.Provider SunPKCS11-NSS

 

  • In case of using NSS as cryptographic software token (Make use of NSS 3.1.1. or above), assuming the libraries are located under the /opt/nss/lib directory and its key database files  (with the suffix .db) are under the /opt/nss/fipsdb directory, the sample configuration for representing NSS will be as follows:
                           # Use NSS as a FIPS-140 compliant cryptographic token 
                           # SunPKCS11-NSS
                          name = NSS
                          nssLibraryDirectory = /opt/nss/lib
                          nssSecmodDirectory = /opt/nss/fipsdb
                          nssModule = fips
  • In FIPS mode, SunJSSE will perform SSL/TLS 1.0 based communication and cryptographic operations including symmetric and asymmetric encryption, signature generation and verification, message digests and message authentication codes, key generation and key derivation, random number generation, etc.
  • To refer to the SunJSSE supported Ciphersuites suites refer to the Sun JSSE’s documentation and notes for FIPS guidance.

 

* FIPS-140 is a US Federal data security standard approved by the National Institute of Standards and Technology (NIST) – The current version is FIPS-140-2. All US government agencies are mandated to use only FIPS-conformant/validated products for deploying security sensitive applications and solutions.

Onlinerel Facebook Twitter Myspace Friendfeed Technorati del.icio.us Digg Google Yahoo Buzz StumbleUpon

One thing I noticed lately…is lot of interest about understanding the usage of ‘Obfuscated Transfer Object (OTO) ‘ from Core Security Patterns.  I got multiple emails about its code and implementation .. understandably there is a growing security concern about using Transfer Object (aka Value Object) that passes security-sensitive data elements between Java EE tiers (especially between Presentation/Business/Persistence), when the application components does’nt run in a co-existing environment and risks associated with getting captured in console messages, log files and by rogue administrators. Think about “User Profile” or “Credit Card” or any other sensitive data in transit, it becomes quite critical to ensure privy of the data with appropriate data protection in place.  When we wrote Core Security Patterns, Chris and I discussed more  about this pattern and its implementation than anything else….agreed, this has its own implementation complexities . The worst you could see is, if you screw up the implementation it masks all the Java EE components from consuming the data elements of the passed OTO…. from a security perspective, it is a good thing as it fails safely.

Let’s dig into the finer details of why and how you would choose to implement an Obfuscated Transfer Object:

Why OTO ?

  • To protect sensitive data passed in Transfer Objects from being captured in console messages (JMX, Adminstration), log files and audit logs.
  • To ensure Transfer object be responsible for protecting the data and prevent target application components from inadverently exposing sensitive data.
  • To protect select data elements and not all data elements should be protected or exposed.

How it works ?

In simpler terms, Obfuscated Transfer Object allows  to define data elements within it that are to be protected using mechanisms to prevent purposeful or inadvertent unauthorized access to its data. The means of protection can vary between applications or implementations depending on your target business requirements. The OTO provides the producers and consumers of the data can agree upon the sensitive data
elements that need to be protected and on their means of access. OTO will then take the responsibility of protecting that data from any intervening components that it is passed to on its way between producer and consumer. For example, Credit card and other sensitive information can be protected from being accidentally dumped to a log file or audit trail, or worse, such as being captured and stored for malicious purposes.

How to Implement OTO ?

Although there are several ways to implement OTO, the two easier ways we found to implement OTO are  Masked List Strategy and Sealed Object/Encryption Strategy.

Masked List Strategy

In this strategy, the client sets data as name-value (NV) pairs in the Obfuscated Transfer Object. Internally, the Obfuscated Transfer Object maintains two maps, one for holding NV pairs that should be obfuscated and another for NV pairs that do not require obfuscation. In addition to the two maps, the Obfuscated Transfer Object contains a list of NV pair names that should be protected. Data passed in with names corresponding to names in the masked list, are placed in the map for the obfuscated data. This map is then protected. In the sequence above, when the Component logs the ObfuscatedTransferObject, the data in the obfuscated map is not logged, and thus it is protected.

Sealed Object/Encryption Strategy

With encryption Strategy for Obfuscated Transfer Object provides the highest level of protection for the data elements protected within. The data elements are stored in a Data Map, and then the Data Map as a whole is encrypted using a symmetric key. To retrieve the Data Map and the elements within it, the consumer must supply a symmetric key identical to the one used by the producer to seal the Data Map.

private SealedObject sealedMap;
// Seal object
HashMap map = sealedMap.getObject(cipher);
// Unseal object
sealedMap = new SealedObject(map, cipher);

As shown above, we can implement this using Java Sealed Object class that allows to easily encrypt objects by passing in a serialized object and a Cipher object in the constructor. The serialized object can then be retrieved by either passing in an identical Cipher or a Key object that can be used to recreate the Cipher. This encapsulates all of the underlying work associated with encrypting and decrypting objects. The only issue remaining is the management of symmetric keys within the application. This poses a significant challenge because it requires the producers and consumers to share symmetric keys without providing any intermediary components with access to those keys. This may be simple or overwhelmingly complex depending on the architecture of the application and the structure of the component trust model. Use this strategy with caution, because the key-management issues may be harder to overcome than architecting the application again to eliminate the need for the Sealed Object :-) .

Hope this helped my two EU friends…who keep pestering me last two days via email. Due to my contractual obligations with Prentice Hall, I cannot dump the contents and source code in my blog…so I leave the rest to your way and you know where to look for :-) . Also don’t ask how it is being implemented in Microsoft .NET – that’s not my forte.

Onlinerel Facebook Twitter Myspace Friendfeed Technorati del.icio.us Digg Google Yahoo Buzz StumbleUpon

Few weeks ago, US Dept. of Homeland security (National Cyber Security Division) in collaboration with SANS Institute/MITRE teams worked together and released a list of 25 dangerous programming errors as common security flaws, which opens doors for easy exploitation. My first look at this list, I thought it is a old wine in a new bottle as the document sounded a bit more high-level without applied countermeasures and reality checks. The list did go extra mile highlighting the mitigation strategies and countermeasures. For those follow OWASP Top 10 (Most compelling), the CWE Top 25 list is a bit more augmented to include the weakest links of security in target resource and client/server environment. At the outset, the Top 25 list certainly helps our budding developers on understanding the potential weaknesses and vulnerabilities arise due to poor coding practices.

Here is the list of SANS/MITRE’s Top 25 Most Dangerous Programming Errors, in no particular order…

1. Improper Input Validation
2. Improper Encoding or Escaping of Output
3. Failure to Preserve SQL Query Structure (SQL Injection)
4. Failure to Preserve Web Page Structure (Cross-site Scripting)
5. Failure to Preserve OS Command Structure (OS Command Injection)
6. Cleartext Transmission of Sensitive Information
7. Cross-Site Request Forgery (CSRF)
8. Race Condition
9. Error Message Information Leak
10. Failure to Constrain Operations within the Bounds of a Memory Buffer
11. External Control of Critical State Data
12. External Control of File Name or Path
13. Untrusted Search Path
14. Failure to Control Generation of Code (Code Injection)
15. Download of Code Without Integrity Check
16. Improper Resource Shutdown or Release
17. Improper Initialization
18. Incorrect Calculation
19. Improper Access Control (Authorization)
20. Use of a Broken or Risky Cryptographic Algorithm
21. Hard-Coded Password
22. Insecure Permission Assignment for Critical Resource
23. Use of Insufficiently Random Values
24. Execution with Unnecessary Privileges
25. Client-Side Enforcement of Server-Side Security

It is an impressive list…that leaves me with some hard questions, when it comes to how to implement the required safeguards and countermeasures – Yes, the Devil is always in the Implementation details as there is No Magic Silver Bullet and it becomes critical to the developer to choose, adopt and practice the appropriate “Security Design and Best Practices” that identifies the safeguard and helps proactively defend against those known errors.  As a developer – in the first place you must understand – how to bake-in security in your application choosing the relevant “Security patterns, Best practices, Pitfalls and Reality checks”…for your target application development and deployment environment.

This gives me another opportunity for my shameless book promotion (is here), especially for those who is interested in knowing the security patterns and require implementation guidance for securing Java/J2EE/Web Services environments.

Onlinerel Facebook Twitter Myspace Friendfeed Technorati del.icio.us Digg Google Yahoo Buzz StumbleUpon

Last week, I was test driving a PIV Smartcard based PKI as a keystore (via Java PKCS#11)  to support using the PKI/certificate credentials for performing encryption/decryption and digital signature operations  (PKI based logins to Web applications, Encryption/decryption of documents, Digitally signing email). There is no secret receipe but some of you may find it a bit difficult – if you are doing it for first time.  So, here is my quick cheat sheet for your better understanding :

Since J2SE 5.0,  JCE introduced support for the PKCS#11 standard that allows the following:

  • Using hardware cryptographic accelerators for enhancing performance of cryptographic operations.
  • Using smart cards as key stores for key and trust management.

To use these services, it is necessary to install the PKCS#11 implementation provided by the hardware accelerator and smart card vendors. As part of the J2SE 5.0 bundle (and up), Sun facilitates a SunPKCS#11 provider.

To use a smart card as a keystore or trust store, set the javax.net.ssl.keyStoreType and javax.net.ssl.trustStoreType of the Java runtime system properties  to “pkcs11“, and set the javax.net.ssl.keyStore and javax.net.ssl.trustStore system properties to NONE. To specify the use of a vendor smart-card provider, use the javax.net.ssl.keyStoreProvider and javax.net.ssl.trustStoreProvider
Java runtime system properties to identify them. (For example: “SunPKCS11-smart card”). By setting these properties, you can configure an application to use a smart-card keystore with no changes to the application that previously accessed a file-based keystore.

Configuring a Smart card as a Java Keystore (using OpenSC Framework)

OpenSCThe following example shows how to configure OpenSC supported smart card as a Java keystore and list the certificates using the keytool utility. The OpenSC framework can be downloaded from http://www.opensc.org.

  1. Add the OpenSC PKCS#11 module as the keystore provider in java.security file located at $JAVA_HOME/jre/lib/security/java.security.

    security.provider.1=sun.security.pkcs11.SunPKCS11   /opt/openSC/openscpkcs11-solaris.cfg

  2. Create the OpenSC PKCS#11 configuration file. For example, the openscpkcs11-solaris.cfg looks like as follows:
    name = OpenSC-PKCS11
    description = SunPKCS11 w/ OpenSC Smart card Framework
    library = /usr/lib/pkcs11/opensc-pkcs11.so
  3. With the above settings, it is possible to use the smart card as a keystore and retrieve information about the certificates from your Smartcard. For example,  you may use the keytool utility to list certificate entries from a smart card:

$ keytool -keystore NONE -storetype PKCS11 -providerName SunPKCS11-OpenSC -list -v
Enter keystore password: <SMARTCARD_PIN>
Keystore type: PKCS11
Keystore provider: SunPKCS11-OpenSC
Your keystore contains 4 entries

Alias name: Signature
Entry type: keyEntry
Certificate chain length: 1
Certificate[1]:
Owner: SERIALNUMBER=79797900036, GIVENNAME=Nagappan Expire1779,
SURNAME=R, CN=Nagappan (Signature), C=US
Issuer: CN=Nagappan OpenSSL CA, C=US
Serial number: 1000000000102fdf39941
Valid from: Sat Nov 01 15:29:22 EST 2008 until: Wed Jun 01 15:29:22 EST 2009
Certificate fingerprints:
MD5: 12:20:AC:2F:F2:F5:5E:91:0A:53:7A:4B:8A:F7:39:4F
SHA1:
77:76:48:DA:EC:5E:9C:26:A2:63:A9:EC:A0:14:42:BF:90:53:0F:BC
Alias name: Root
Entry type: trustedCertEntry
Owner: CN=Nagappan OpenSSL Root CA, C=US
Issuer: CN=Nagappan OpenSSL Root CA, C=US

Serial number: 11111111111111111111111111111112
Valid from: Sat Nov 01 15:29:22 EST 2008 until: Wed Jun 01 15:29:22 EST 2009
Certificate fingerprints:
MD5: 5A:0F:FD:DB:4F:FC:37:D4:CD:95:17:D5:04:01:6E:73
SHA1:
6A:5F:FD:25:7E:85:DC:60:81:82:8D:D1:69:AA:30:4E:7E:37:DD:3B
Alias name: Authentication
Entry type: keyEntry
Certificate chain length: 1
Certificate[1]:
Owner: SERIALNUMBER=79797900036, GIVENNAME=Nagappan Expire1779,
SURNAME=R, CN=NAGAPPAN, C=US
Issuer: CN=Nagappan OpenSSL CA, C=US
Serial number: 1000000000102fd10d2d9
Valid from: Sat Nov 01 15:29:22 EST 2008 until: Wed Jun 01 15:29:22 EST 2009
Certificate fingerprints:
MD5: 29:7E:8A:5C:91:34:9B:05:52:21:4E:49:5B:45:F8:C4
SHA1:
15:B7:EA:27:E1:0E:9D:94:4E:7B:3B:79:00:48:A2:31:7E:9D:72:1A

—————–

Using Sun Ray DTU as your Smart card Reader

In our case, the customer chose to use Sun Ray as the Smartcard reader where the inserted card is used for performing session mobility and PKI/Certificate based cryptographic operations. To enable access to Smartcard based PKI credentials on Sun Rays, make sure you install the Sun Ray PC/SC Lite to support accessing smart cards. You may download the PC/SC Lite for Sun Ray Server (SRSS 4.x) from:

http://www.sun.com/download/products.xml?id=46af59b2

Enjoy

Onlinerel Facebook Twitter Myspace Friendfeed Technorati del.icio.us Digg Google Yahoo Buzz StumbleUpon

Important Disclaimer:The information presented in this weblog is provided “AS IS” with no warranties, and confers no rights. It solely represents our opinions. This weblog does not represent the thoughts, intentions, plans or strategies of our employers.
.