Programming and So

Tips and tricks in Java

Archive for July 2008

Where I come from?

without comments

Sometimes, inside of a java method, it’s needed to know which is the invoking method. I don’t know any documented procedure/technique to provide this information. So I use to develop a low performance piece of code based on an exception throwing and catching.

public void mockMethod() {
    // Invoking Class
    String invokingClass = "";
    String invokingMethod = "";
   
    // Where I come from?
    try {
      throw new Exception();
    } catch (Exception e) {
   
      // StackTrace to String
      StringWriter sw = new StringWriter();
      e.printStackTrace(new PrintWriter(sw));

      // Split lines using "at " substring as separator
      // Invoker is located at position 2 of the array
      String[] lines = sw.toString().split("at ");

      // a dot followed by a capital letter (ex. package.Class)
      boolean dotCapital = false;
      // find dotCapital position
      int i = 0;
      while (!dotCapital) {
        dotCapital =
            lines[2].charAt(i) == '.' &&
            Character.isUpperCase(lines[2].charAt(i + 1));
        i++;
      }
     
      // Class substring
      while(!(lines[2].charAt(i) == '.')) {
        invokingClass = invokingClass + lines[2].charAt(i);
        i++;
      }
      i++;
     
      // Method substring
      while(!(lines[2].charAt(i) == '(')) {
        invokingMethod = invokingMethod + lines[2].charAt(i);
        i++;
      }
     
    }
    System.out.println("Invoking class: " + invokingClass + "." + invokingMethod);
  }

Inelegant but effective.

Written by angelborroy

July 30, 2008 at 4:06 pm

Posted in java

Tagged with

WSS in Java

with 2 comments

WSS stands for Web Services Security or, shortly, WS-Security. This standard is commonly used to perform secure communications between web services and it’s underlying based on XMLDSig.

Most used toolkits in Java for WSS are:

  • XWSS from Sun (as part of the project Glassfish)
  • WSS4J from Apache

Both are mature solutions and both cover obligatory part of the standard. However, the implementation of optional parts of the standard produces conflicts in client-server communications between this toolkits.

Recently, we had to work with systems communicating through secure web services based on XWSS and WSS4j and we had to solve two problems:

  1. WSS4J doesn’t support InclusiveNamespaces in canonicalization methods of XMLDSig (WSS estandar covers this functionality as optional). 
  2. WSS4J doesn’t support signed timestamp (WSS estandar covers this functionality as optional).

For the first issue, we configured XWSS in order to avoid the unsupported use of the prefix in XML canonicalization.

 
<xwss:Sign includeTimestamp="false">
    <xwss:CanonicalizationMethod disableInclusivePrefix="true" />
    <xwss:SignatureTarget type="qname" value="SOAP-BODY">
        <xwss:Transform algorithm="http://www.w3.org/2001/10/xml-exc-c14n#" disableInclusivePrefix="true"/>
    </xwss:SignatureTarget>
</xwss:Sign>

Someone decided for the second issue to use non-signed timestamp. In my opinion, this option is unwise because of timestamp manipulation risk. But one can’t always win…

A deep comparison of XWSS and WSS4j can be found at http://blogs.cocoondev.org/dims/wss4j/compare.html

Written by angelborroy

July 29, 2008 at 1:27 pm

Posted in java

Tagged with ,

Generating, storing and retrieving Private Keys

without comments

Some applications does not work with certificates to perform security operations. Instead of this, raw private keys are used for signature or ciphering. Hence, private keys must be stored as PCKS#8 rather than PCKS#12.  

The following code shows how to generate and use a DSA private key of 1024 bits. Note that this key is stored using Base64 encoding in order to achieve appropiate results. And also Base64 code it’s not provided, any available code would work.

import java.io.BufferedWriter;
import java.io.FileInputStream;
import java.io.FileWriter;
import java.security.KeyFactory;
import java.security.KeyPair;
import java.security.KeyPairGenerator;
import java.security.PrivateKey;
import java.security.SecureRandom;
import java.security.spec.DSAPrivateKeySpec;
import java.security.spec.PKCS8EncodedKeySpec;

import sun.security.provider.DSAPrivateKey;

public class PrivateKeyOps {

  /**
   * Generate a DSA private key 1024 bits
   * @return DSA private key 1024 bits
   * @throws Exception
   */
  @SuppressWarnings( "unchecked" )
  private static PrivateKey generate() throws Exception {

    KeyPairGenerator kpg = KeyPairGenerator.getInstance("DSA");
    kpg.initialize(1024, new SecureRandom());
    KeyPair kp = kpg.generateKeyPair();

    Class spec = Class.forName("java.security.spec.DSAPrivateKeySpec");
    KeyFactory kf = KeyFactory.getInstance("DSA");
    DSAPrivateKeySpec dsaPrivKeySpec =
      (DSAPrivateKeySpec)kf.getKeySpec(kp.getPrivate(), spec);

    return new DSAPrivateKey(
        dsaPrivKeySpec.getX(),
                dsaPrivKeySpec.getP(),
                dsaPrivKeySpec.getQ(),
                dsaPrivKeySpec.getG());

  }

  /**
   * Store a PKCS8 base64 encoded private key in a file
   * @param fileName
   * @param generatedPK
   * @throws Exception
   */
  private static void store(String fileName, byte[] generatedPK) throws Exception {
        BufferedWriter keybw = new BufferedWriter(new FileWriter(fileName));
        keybw.write(Base64.encode(generatedPK));
        keybw.close();
  }

  /**
   * Retrieve a PKCS8 base64 encoded private key from a file
   * @param fileName
   * @return
   * @throws Exception
   */
  private static byte[] retrieve(String fileName) throws Exception {
        FileInputStream keyfis = new FileInputStream(fileName);
        byte[] loadedEncKey = new byte[keyfis.available()];
        keyfis.read(loadedEncKey);
        keyfis.close();
        return Base64.decode(new String(loadedEncKey));
  }

  /**
   * Load a PrivateKey object from an encoded key
   * @param encKey Encoded key
   * @return PrivateKey object
   * @throws Exception
   */
  private static PrivateKey load(byte[] encKey) throws Exception {
        PKCS8EncodedKeySpec privKeySpec = new PKCS8EncodedKeySpec(encKey);
        KeyFactory keyFactory = KeyFactory.getInstance("DSA");
        return keyFactory.generatePrivate(privKeySpec);
  }

  /**
   * Generate a private key
   * Store it on a file using base64 encoding
   * Retrieve it from the file using base64 decoding
   * Load the private key
   * @param args No args required
   * @throws Exception
   */
  public static void main(String...args) throws Exception {

    // Generate and store DSA Private Key
    byte[] generatedPK = generate().getEncoded();
    store("key.pem", generatedPK);

        // Retrieve and load DSA Private Key
    byte[] retrievedEncKey = retrieve("key.pem");
    byte[] loadedPK = load(retrievedEncKey).getEncoded();

    // See how it looks
    System.out.println(Base64.encode(loadedPK));

  }

}

Written by angelborroy

July 28, 2008 at 2:13 pm

Posted in java

Tagged with