<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	xmlns:georss="http://www.georss.org/georss" xmlns:geo="http://www.w3.org/2003/01/geo/wgs84_pos#" xmlns:media="http://search.yahoo.com/mrss/"
	>

<channel>
	<title>These go to eleven!</title>
	<atom:link href="http://gustlik.wordpress.com/feed/" rel="self" type="application/rss+xml" />
	<link>http://gustlik.wordpress.com</link>
	<description>These go to eleven!</description>
	<lastBuildDate>Thu, 26 Jan 2012 06:41:21 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.com/</generator>
<cloud domain='gustlik.wordpress.com' port='80' path='/?rsscloud=notify' registerProcedure='' protocol='http-post' />
<image>
		<url>http://s2.wp.com/i/buttonw-com.png</url>
		<title>These go to eleven!</title>
		<link>http://gustlik.wordpress.com</link>
	</image>
	<atom:link rel="search" type="application/opensearchdescription+xml" href="http://gustlik.wordpress.com/osd.xml" title="These go to eleven!" />
	<atom:link rel='hub' href='http://gustlik.wordpress.com/?pushpress=hub'/>
		<item>
		<title>Importance of block cipher modes</title>
		<link>http://gustlik.wordpress.com/2008/10/15/importance-of-block-cipher-modes/</link>
		<comments>http://gustlik.wordpress.com/2008/10/15/importance-of-block-cipher-modes/#comments</comments>
		<pubDate>Wed, 15 Oct 2008 20:28:57 +0000</pubDate>
		<dc:creator>Zbigniew Cyktor</dc:creator>
				<category><![CDATA[Java]]></category>
		<category><![CDATA[cryptography]]></category>
		<category><![CDATA[images]]></category>

		<guid isPermaLink="false">http://gustlik.wordpress.com/?p=69</guid>
		<description><![CDATA[While writing software dealing with cryptography, it&#8217;s important to be familiar with a concept of block cipher modes. Most of common encryption algorithms work on data grouped together into blocks. For instance, in case of DES cipher, the block size is equal to 64 bits. While encrypting larger amounts of data, cipher implementation will divide [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=gustlik.wordpress.com&amp;blog=4027708&amp;post=69&amp;subd=gustlik&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>While writing software dealing with cryptography, it&#8217;s important to be familiar with a concept of block cipher modes. Most of common encryption algorithms work on data grouped together into blocks. For instance, in case of DES cipher, the block size is equal to 64 bits. While encrypting larger amounts of data, cipher implementation will divide the input into 8 byte chunks and encrypt each of them separately.</p>
<p>This is definitely not desired &#8211; in case of specific input that contains repeatable sets of information (like text documents, bitmaps with large areas of the same color), the encrypted chunks might repeat just like original plain-text values do. As a result of that, encrypted data might <a href="http://www.techworld.com/security/news/index.cfm?newsid=105263" target="_blank">reveal important details of the original content</a>.</p>
<p><span id="more-69"></span></p>
<p>You might want to have a look at a very interesting article about this subject on (ahem) <a href="http://en.wikipedia.org/wiki/Block_cipher_modes_of_operation" target="_blank">Wikipedia</a>. It clearly describes, how block cipher modes solve the problem and additionaly demonstrates how it manifests itself in case of bitmaps. I wanted to play with various block cipher modes and in order to do so I wrote a simple tool that encrypts a user-provided BMP file while leaving its headers intact. As a result of that we are still able to view the encrypted bitmap file in image browser and observe how particular ciphers, key sizes and block modes influence the output. Below are some examples showing:</p>
<ol>
<li>raw image</li>
<li>image encrypted with 56 bit DES using Electronic Codebook (ECB) mode</li>
<li>image encrypted with 56 bit DES using Cipher-block Chaining (CBC) mode</li>
</ol>
<p><img class="alignnone size-full wp-image-77" title="small_spaceman" src="http://gustlik.files.wordpress.com/2008/10/small_spaceman.png" alt="" width="218" height="237" /><img class="alignnone size-full wp-image-79" title="small_spaceman_des_ecb_pkcs5padding_56" src="http://gustlik.files.wordpress.com/2008/10/small_spaceman_des_ecb_pkcs5padding_56.png" alt="" width="218" height="237" /><img class="alignnone size-full wp-image-78" title="small_spaceman_des_cbc_pkcs5padding_56" src="http://gustlik.files.wordpress.com/2008/10/small_spaceman_des_cbc_pkcs5padding_56.png" alt="" width="218" height="237" /></p>
<p>In case of the second example I chose a rather high resolution (3923&#215;4656) scan of an old document. What you see here is just a small cropped part of it, which is hopefully more than enough to observe the effect. I guess I could spare us all pictures representing the CBC mode since they are pretty noisy.</p>
<p><img class="alignnone size-full wp-image-81" title="small_doi1" src="http://gustlik.files.wordpress.com/2008/10/small_doi1.png" alt="" width="218" height="186" /><img class="alignnone size-full wp-image-83" title="small_doi_des_ecb_pkcs5padding_561" src="http://gustlik.files.wordpress.com/2008/10/small_doi_des_ecb_pkcs5padding_561.png" alt="" width="218" height="186" /><img class="alignnone size-full wp-image-82" title="small_doi_des_cbc_pkcs5padding_56" src="http://gustlik.files.wordpress.com/2008/10/small_doi_des_cbc_pkcs5padding_56.png" alt="" width="218" height="186" /></p>
<p>We can also look at this subject from slightly different perspective. The chart below shows how byte values are distributed in a file. Horizontal axis represents bytes from 0 to 255 obviously, while vertical axis stands for count of bytes of given value.</p>
<p><a href="http://gustlik.files.wordpress.com/2008/10/chart.png"><img class="alignnone size-full wp-image-86" title="chart" src="http://gustlik.files.wordpress.com/2008/10/chart.png" alt="" width="481" height="288" /></a></p>
<p>You can clearly see that in case of raw data as well as ECB mode some bytes show up more often than others. But if we look at the green line representing CBC mode &#8211; the distribution is very even across the whole scale which suggests that the encrypted data would contain less information valuable to a person willing to find out what is behind it.</p>
<p>The code to the BMP encrypter is below.</p>
<p><pre class="brush: java;">

import java.io.*;
import java.security.GeneralSecurityException;

import javax.crypto.*;
import javax.crypto.spec.IvParameterSpec;

public class BitmapPaddingTest {

    public static void main(String[] args) throws Exception {
        if (args.length &lt; 4) {
            throw new Exception(&quot;Parameters: [file] [cipher] [keySize] [useInitVector]&quot;);
        }
        new BitmapPaddingTest().encrypt(
                new File(args[0]), args[1], Integer.parseInt(args[2]), Boolean.parseBoolean(args[3]));
    }

    public void encrypt(File file, String cipherName, int keySize, boolean useIv) throws Exception {
        File encryptedFile = buildEncryptedFile(file, cipherName, keySize);
        System.out.print(&quot;Encrypting &quot; + file.getName() + &quot; to &quot; + encryptedFile.getName() + &quot;... &quot;);

        OutputStream outputStream = new BufferedOutputStream(new FileOutputStream(encryptedFile));
        InputStream fileStream = new BufferedInputStream(new FileInputStream(file));
        byte[] data = new byte[54]; // first 54 bytes of BMP file contain its header (in most cases)
        fileStream.read(data);
        outputStream.write(data);
        outputStream.flush();        

        CipherOutputStream cipherStream =
            new CipherOutputStream(outputStream, createCipher(cipherName, keySize, useIv));
        data = new byte[1024];
        int size = 0;
        while ((size = fileStream.read(data)) &gt; 0) {
            cipherStream.write(data, 0, size);
        }
        cipherStream.flush();
        cipherStream.close();
        System.out.println(&quot;done.&quot;);
    }

    private SecretKey createSymmetricKey(String cipherName, int keySize) throws GeneralSecurityException {
        KeyGenerator keyGenerator = KeyGenerator.getInstance(cipherName.substring(0, cipherName.indexOf(&quot;/&quot;)));
        keyGenerator.init(keySize);
        return keyGenerator.generateKey();
    }

    private Cipher createCipher(String cipherName, int keySize, boolean useIv) throws GeneralSecurityException {
        SecretKey symmetricKey = createSymmetricKey(cipherName, keySize);
        Cipher cipher = Cipher.getInstance(cipherName);
        IvParameterSpec iv = useIv ? new IvParameterSpec(symmetricKey.getEncoded()) : null;
        cipher.init(Cipher.ENCRYPT_MODE, symmetricKey, iv);
        return cipher;
    }

    private File buildEncryptedFile(File file, String cipherName, int keySize) {
        String cipherNameUnderscored = cipherName.replaceAll(&quot;/&quot;, &quot;_&quot;);
        return new File(file.getParentFile(),
                file.getName().replace(&quot;.bmp&quot;, &quot;_&quot; + cipherNameUnderscored + &quot;_&quot; + keySize + &quot;.bmp&quot;));
    }
}

</pre></p>
<p>If run as follows:</p>
<p>java BitmapPaddingTest source.bmp DES/ECB/PKCS5Padding 56 false<br />
java BitmapPaddingTest source.bmp DES/CBC/PKCS5Padding 56 true</p>
<p>will generate two files located in the same directory as the source bitmap.</p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/gustlik.wordpress.com/69/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/gustlik.wordpress.com/69/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/gustlik.wordpress.com/69/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/gustlik.wordpress.com/69/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/gustlik.wordpress.com/69/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/gustlik.wordpress.com/69/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/gustlik.wordpress.com/69/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/gustlik.wordpress.com/69/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/gustlik.wordpress.com/69/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/gustlik.wordpress.com/69/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/gustlik.wordpress.com/69/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/gustlik.wordpress.com/69/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/gustlik.wordpress.com/69/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/gustlik.wordpress.com/69/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=gustlik.wordpress.com&amp;blog=4027708&amp;post=69&amp;subd=gustlik&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://gustlik.wordpress.com/2008/10/15/importance-of-block-cipher-modes/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="http://1.gravatar.com/avatar/1b86b37267763e08b3bcf2fc9e05bd6b?s=96&#38;d=wavatar" medium="image">
			<media:title type="html">rozbryzg</media:title>
		</media:content>

		<media:content url="http://gustlik.files.wordpress.com/2008/10/small_spaceman.png" medium="image">
			<media:title type="html">small_spaceman</media:title>
		</media:content>

		<media:content url="http://gustlik.files.wordpress.com/2008/10/small_spaceman_des_ecb_pkcs5padding_56.png" medium="image">
			<media:title type="html">small_spaceman_des_ecb_pkcs5padding_56</media:title>
		</media:content>

		<media:content url="http://gustlik.files.wordpress.com/2008/10/small_spaceman_des_cbc_pkcs5padding_56.png" medium="image">
			<media:title type="html">small_spaceman_des_cbc_pkcs5padding_56</media:title>
		</media:content>

		<media:content url="http://gustlik.files.wordpress.com/2008/10/small_doi1.png" medium="image">
			<media:title type="html">small_doi1</media:title>
		</media:content>

		<media:content url="http://gustlik.files.wordpress.com/2008/10/small_doi_des_ecb_pkcs5padding_561.png" medium="image">
			<media:title type="html">small_doi_des_ecb_pkcs5padding_561</media:title>
		</media:content>

		<media:content url="http://gustlik.files.wordpress.com/2008/10/small_doi_des_cbc_pkcs5padding_56.png" medium="image">
			<media:title type="html">small_doi_des_cbc_pkcs5padding_56</media:title>
		</media:content>

		<media:content url="http://gustlik.files.wordpress.com/2008/10/chart.png" medium="image">
			<media:title type="html">chart</media:title>
		</media:content>
	</item>
		<item>
		<title>Non-repudiative logging</title>
		<link>http://gustlik.wordpress.com/2008/09/07/non-repudiative-logging/</link>
		<comments>http://gustlik.wordpress.com/2008/09/07/non-repudiative-logging/#comments</comments>
		<pubDate>Sun, 07 Sep 2008 13:20:10 +0000</pubDate>
		<dc:creator>Zbigniew Cyktor</dc:creator>
				<category><![CDATA[Java]]></category>
		<category><![CDATA[log4j]]></category>
		<category><![CDATA[non-repudiation]]></category>

		<guid isPermaLink="false">http://gustlik.wordpress.com/?p=45</guid>
		<description><![CDATA[Non-repudiation is a very interesting subject at the intersection of technology and law. For the sake of exercise let&#8217;s imagine a very simple scenario in which we&#8217;d like to have some specific user actions logged into a file in a way that would allow us to find out later, whether anybody has modified the content [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=gustlik.wordpress.com&amp;blog=4027708&amp;post=45&amp;subd=gustlik&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>Non-repudiation is a very interesting subject at the intersection of technology and <strong><a href="http://world.std.com/~cme/non-repudiation.htm" target="_blank">law</a></strong>. For the sake of exercise let&#8217;s imagine a very simple scenario in which we&#8217;d like to have some specific user actions logged into a file in a way that would allow us to find out later, whether anybody has modified the content of such a log file. Let&#8217;s naively assume that anything that the application puts to logs can be trusted.</p>
<p>In order to accomplish this task, we will create a <strong><a href="http://logging.apache.org/log4j/" target="_blank">Log4j</a></strong> appender that will calculate an <a href="http://en.wikipedia.org/wiki/HMAC" target="_blank"><strong>HMAC</strong></a> (hash) of every logged event and attach it to the log file as well.</p>
<p><span id="more-45"></span></p>
<p>This would be enough to ensure that any change to a log entry can be spotted. But since we also want to be safe against having <strong>log entries removed from the file</strong>, we need to create a relation between consecutive entries. In order to do that &#8211; each log entry hash will be calculated based on its content as well as the previous entry&#8217;s hash value. Removal of any entry will then &#8216;break the chain&#8217; and result with wrong hashes of all the following ones.</p>
<p>For the solution to be complete, it is necessary to <strong>initialize the hash generator with a secret salt value</strong> &#8211; otherwise a person modifying our data could easily recalculate all hashes from the beginning and bypass the whole mechanism. The salt should be known only to the appender calculating hashes and to the third party willing to validate integrity of the log file. This of course assumes that the third party is trustworthy &#8211; in some more sophisticated scenarios you might want to use a <strong><a href="http://en.wikipedia.org/wiki/Public_key_infrastructure" target="_blank">public key infrastructure</a></strong> to avoid using the same secret by the two parties.</p>
<p>The code below consists of five files:</p>
<p><strong>DigestAppender.java</strong> &#8211; the appender itself, based on parameters provided by Log4j configuration will write all log events with their hashes to System.out (for the sake of simplicity)</p>
<p><strong>Test.java</strong> &#8211; a simple class logging a few events.</p>
<p><strong>Validator.java</strong> &#8211; a tool that will verify the integrity of user-provided log file and also output it&#8217;s content stripped of lines containing hashes (so it&#8217;s easier to read)</p>
<p><strong>Util.java</strong> &#8211; container for some shared pieces of code.</p>
<p><strong>log4j.properties</strong> &#8211; a simple configuration specifying (among others) a hashing algorithm (SHA-256 in this case) and the salt etc.</p>
<p>Example usage:</p>
<p>java -cp .;./lib/log4j-1.2.15.jar Test &gt; output.log<br />
java -cp .;./lib/log4j-1.2.15.jar Validator output.log SHA-256 a$ecret$eed</p>
<p>DigestAppender.java:</p>
<p><pre class="brush: java;">

import java.security.MessageDigest;

import org.apache.log4j.AppenderSkeleton;
import org.apache.log4j.spi.LoggingEvent;

public class DigestAppender extends AppenderSkeleton {

	private String algorithm;
	private transient String seed;
	private transient MessageDigest messageDigest;

	public void append(LoggingEvent event) {
		String eventString = layout.format(event) + Util.LINE_SEPARATOR;
		String digest = Util.digestAndUpdate(eventString, getMessageDigest());
		System.out.println(eventString.length() + &quot;,&quot; + digest);
		System.out.print(eventString);
	}

	private MessageDigest getMessageDigest() {
		if (messageDigest == null) {
			try {
				messageDigest = MessageDigest.getInstance(algorithm);
				Util.digestAndUpdate(seed, messageDigest);
				seed = null; // will not be needed anymore
			}
			catch (Exception e) {
				e.printStackTrace();
			}
		}
		return messageDigest;
	}

	public boolean requiresLayout() {
		return true;
	}

	public void setAlgorithm(String algorithm) {
		this.algorithm = algorithm;
	}

	public void setSeed(String seed) {
		this.seed = seed;
	}

	public void close() {
	}
}

</pre></p>
<p>Test.java:</p>
<p><pre class="brush: java;">

import org.apache.log4j.Logger;

public class Test {

	private static Logger log = Logger.getLogger(Test.class);

	public static void main(String[] args) {
		new Test().run(args);
	}

	public void run(String[] args) {

		for (int i = 0; i &lt; 10; i++) {
			log.info( &quot;This is an info message number &quot; + i);
			log.debug(&quot;This is a debug message number &quot; + i);
			log.warn( &quot;This is a warn  message number &quot; + i);
		}
	}
}
</pre></p>
<p>Validator.java:</p>
<p><pre class="brush: java;">
import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.security.MessageDigest;

public class Validator {

	protected MessageDigest messageDigest;

	public static void main(String[] args) throws Exception {
		if (args.length &lt; 3) {
			throw new Exception(&quot;Usage: [logFile] [algorithm] [seed]&quot;);
		}
		new Validator().validate(new File(args[0]), args[1], args[2]);
	}

	public void validate(File logFile, String algorithm, String seed) throws Exception {
		messageDigest = MessageDigest.getInstance(algorithm);
		Util.digestAndUpdate(seed, messageDigest);
		processFile(logFile);
	}

	public void processFile(File file) throws Exception {
		BufferedReader br = null;
		try {
			br = new BufferedReader(new FileReader(file));
			while (true) {
				String line = br.readLine();
				if (line == null) {
					break;
				}
				String[] entryDetails = line.split(&quot;,&quot;);
				int logEntryLength = Integer.parseInt(entryDetails[0]);
				String expectedDigest = entryDetails[1];
				char[] logEntryBuffer = new char[logEntryLength];
				if (br.read(logEntryBuffer) == -1) {
					break;
				}
				validateLogEntry(String.valueOf(logEntryBuffer), expectedDigest);
			}
		}
		finally {
			if (br != null) br.close();
		}
	}

	protected void validateLogEntry(String logEntry, String expectedDigest) throws Exception {
		String digest = Util.digestAndUpdate(logEntry, messageDigest);
		if (digest.equals(expectedDigest) == false) {
			throw new Exception(&quot;Wrong checksum of entry:&quot; + Util.LINE_SEPARATOR + logEntry);
		}
		System.out.print(logEntry);
	}
}
</pre></p>
<p>Util.java:</p>
<p><pre class="brush: java;">
import java.security.MessageDigest;

public class Util {

	public static final String LINE_SEPARATOR = System.getProperty(&quot;line.separator&quot;);

	public static String digestAndUpdate(String input, MessageDigest messageDigest) {
		try {
			byte[] digestResult = messageDigest.digest(input.getBytes());
			messageDigest.update(digestResult);

			StringBuilder hexResult = new StringBuilder();
			for (byte b : digestResult) {
				String hexByte = Integer.toHexString(0xFF &amp; b);
				if (hexByte.length() == 1) {
					hexResult.append(&quot;0&quot;);
				}
				hexResult.append(hexByte);
			}
			return hexResult.toString();
		}
		catch (Exception e) {
			e.printStackTrace();
			return null;
		}
	}
}
</pre></p>
<p>log4j.properties:</p>
<p><pre class="brush: java;">
log4j.rootLogger=INFO, digestAppender
log4j.appender.digestAppender=DigestAppender
log4j.appender.digestAppender.algorithm=SHA-256
log4j.appender.digestAppender.seed=a$ecret$eed
log4j.appender.digestAppender.layout=org.apache.log4j.PatternLayout
log4j.appender.digestAppender.layout.ConversionPattern=[%d{MMM dd HH:mm:ss}] %-5p (%F:%L) - %m
log4j.appender.digestAppender.threshold=INFO
log4j.category.Test=INFO
log4j.logger.Test=digestAppender
</pre></p>
<p>Finally, here is the example log file:</p>
<p><pre class="brush: java;">
75,68d724760f6892dec0b1612848e4ae1665af05254ea0715a5dc09423d74306ae
[sep 07 15:04:28] INFO  (Test.java:14) - This is an info message number 0
75,0703a6444f0704a66fb14ed87a718ebf821f23fccd375dd5ffbe56da704fc902
[sep 07 15:04:28] WARN  (Test.java:16) - This is a warn  message number 0
75,59c5d9319632139389e71b522d74ca17112b67fda8ba3a5dd7ace692d6c024b6
[sep 07 15:04:28] INFO  (Test.java:14) - This is an info message number 1
75,937edac9d2570c0c6d1c5083145971305b21f0ebd00fbb23abf9862646867284
[sep 07 15:04:28] WARN  (Test.java:16) - This is a warn  message number 1
75,a05e8219cda5e2f95b9846f5a98d7654713950ab71a4960aec32364024391ed4
[sep 07 15:04:28] INFO  (Test.java:14) - This is an info message number 2
75,479010bf0ebd11031733e035a1aa793b38887fe91201e534b3cfd4678778af31
[sep 07 15:04:28] WARN  (Test.java:16) - This is a warn  message number 2
</pre></p>
<p>Enjoy!</p>
<br /><img alt="" border="0" src="http://feeds.wordpress.com/1.0/categories/gustlik.wordpress.com/45/" /> <img alt="" border="0" src="http://feeds.wordpress.com/1.0/tags/gustlik.wordpress.com/45/" /> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/gustlik.wordpress.com/45/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/gustlik.wordpress.com/45/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/gustlik.wordpress.com/45/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/gustlik.wordpress.com/45/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/gustlik.wordpress.com/45/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/gustlik.wordpress.com/45/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/gustlik.wordpress.com/45/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/gustlik.wordpress.com/45/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/gustlik.wordpress.com/45/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/gustlik.wordpress.com/45/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/gustlik.wordpress.com/45/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/gustlik.wordpress.com/45/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/gustlik.wordpress.com/45/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/gustlik.wordpress.com/45/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=gustlik.wordpress.com&amp;blog=4027708&amp;post=45&amp;subd=gustlik&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://gustlik.wordpress.com/2008/09/07/non-repudiative-logging/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
	
		<media:content url="http://1.gravatar.com/avatar/1b86b37267763e08b3bcf2fc9e05bd6b?s=96&#38;d=wavatar" medium="image">
			<media:title type="html">rozbryzg</media:title>
		</media:content>
	</item>
		<item>
		<title>Decryption of configuration passwords in WebLogic</title>
		<link>http://gustlik.wordpress.com/2008/08/06/decryption-of-configuration-passwords-in-weblogic/</link>
		<comments>http://gustlik.wordpress.com/2008/08/06/decryption-of-configuration-passwords-in-weblogic/#comments</comments>
		<pubDate>Wed, 06 Aug 2008 10:11:12 +0000</pubDate>
		<dc:creator>Zbigniew Cyktor</dc:creator>
				<category><![CDATA[Java]]></category>
		<category><![CDATA[security]]></category>
		<category><![CDATA[WebLogic]]></category>

		<guid isPermaLink="false">http://gustlik.wordpress.com/?p=6</guid>
		<description><![CDATA[BEA/Oracle WebLogic application server being an enterprise-ready piece of software treats security seriously. One of the symptoms of that is the fact that all sensitive pieces of information like logins, passwords etc. are kept in encrypted form. While browsing through config.xml or boot.properties files you can easily spot them since they are usually prefixed with [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=gustlik.wordpress.com&amp;blog=4027708&amp;post=6&amp;subd=gustlik&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p><strong>BEA/Oracle WebLogic</strong> application server being an enterprise-ready piece of software treats security seriously. One of the symptoms of that is the fact that all sensitive pieces of information like logins, passwords etc. are kept in encrypted form. While browsing through <strong>config.xml </strong>or <strong>boot.properties</strong> files you can easily spot them since they are usually prefixed with <strong>&#8216;{3DES}&#8217;</strong> string which obviously suggests the encryption algorithm used.</p>
<p>The interesting thing is that with a little bit of efford it&#8217;s actually quite easy to extract the decrypted values from config files by using a few undocumented APIs buried in <strong>WebLogic </strong>itself. Below you will find a simple tool that will output a content of either .xml or .properties configuration file provided as input, replacing all encrypted values with their original content. It works with <strong>WebLogic 10</strong> but can be easily adapted for versions <strong>8</strong> and <strong>9</strong> as well (domain directory structure is slightly different between these versions). I wrote it some time ago in order to be able to easily retrieve logins and passwords of development domains that I kept forgetting too often. <img src='http://s0.wp.com/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' />  Obviously there are many other uses, like configuration management, application server migration tools etc.</p>
<p><span id="more-6"></span></p>
<p>You might get worried that since it&#8217;s so easy to get to this supposedly safe data then your production environments are endangered. It isn&#8217;t so &#8211; the decryption mechanism is useless without a file <strong>SerializedSystemIni.dat</strong> which contains the <strong>3DES</strong> key necessary to decrypt the data and is uniqe for every domain. If this file is properly protected from unauthorized access on OS level then have no worries.</p>
<p>(I was going to put here a link to a interesting blog entry on <a href="http://dev2dev.bea.com" target="_blank">dev2dev.bea.com</a> portal with some insightful comments on this subject but it seems that <strong>Dev2Dev</strong> has been shut down due to the BEA acquisition by Oracle. I will update this entry if it pops up somewhere else.)</p>
<p><span style="color:#0000ff;"><strong>Update: </strong></span>I have noticed that this article is getting quite many views every day &#8211; it seems that forgetting domain passwords is more common problem than it seems <img src='http://s0.wp.com/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> . Some users reported issues while processing their configuration files, which often is caused by the poor use of REGEXP in my original code. In order to make it easy to all of us I have prepared a new version of the tool. It uses XPATH to find all XML nodes and attributes containing encrypted data. I hope that this approach is more robust.</p>
<p><span style="color:#0000ff;"><strong>Update 2: </strong></span>If you are concerned about the risk of accessing the configuration data by deployed applications, then please have a look at comments #32 &#8211; #34.</p>
<p><span style="font-family:Consolas, Monaco, 'Courier New', Courier, monospace;line-height:18px;font-size:12px;white-space:pre;"> </span></p>
<p><pre class="brush: java;">
import java.util.*;
import java.io.*;
import javax.xml.parsers.*;
import javax.xml.xpath.*;
import org.w3c.dom.*;

import weblogic.security.internal.*; // requires weblogic.jar in the class path
import weblogic.security.internal.encryption.*;

public class WebLogicDecryptor {

	private static final String PREFIX = &quot;{3DES}&quot;;
	private static final String XPATH_EXPRESSION
		= &quot;//node()[starts-with(text(), '&quot; + PREFIX + &quot;')] | //@*[starts-with(., '&quot; + PREFIX + &quot;')]&quot;;

	private static ClearOrEncryptedService ces;

	public static void main(String[] args) throws Exception {
		if (args.length &lt; 2) {
			throw new Exception(&quot;Usage: [domainDir] [configFile]&quot;);
		}

		ces = new ClearOrEncryptedService(SerializedSystemIni.getEncryptionService(new File(args[0]).getAbsolutePath()));
		File file = new File(args[1]);
		if (file.getName().endsWith(&quot;.xml&quot;)) {
			processXml(file);
		}
		else if (file.getName().endsWith(&quot;.properties&quot;)){
			processProperties(file);
		}
	}

	private static void processXml(File file) throws Exception {
		Document doc = DocumentBuilderFactory.newInstance().newDocumentBuilder().parse(file);
		XPathExpression expr = XPathFactory.newInstance().newXPath().compile(XPATH_EXPRESSION);
		NodeList nodes = (NodeList)expr.evaluate(doc, XPathConstants.NODESET);
		for (int i = 0; i &lt; nodes.getLength(); i++) {
			Node node = nodes.item(i);
			print(node.getNodeName(), node.getTextContent());
		}
	}

	private static void processProperties(File file) throws Exception {
		Properties properties = new Properties();
		properties.load(new FileInputStream(file));
		for (Map.Entry p : properties.entrySet()) {
			if (p.getValue().toString().startsWith(PREFIX)) {
				print(p.getKey(), p.getValue());
			}
		}
	}

	private static void print(Object attributeName, Object encrypted) {
		System.out.println(&quot;Node name: &quot; + attributeName);
		System.out.println(&quot;Encrypted: &quot; + encrypted);
		System.out.println(&quot;Decrypted: &quot; + ces.decrypt((String)encrypted) + &quot;\n&quot;);
	}
}
</pre></p>
<p>Feel free to comment and improve.</p>
<div id="_mcePaste" style="overflow:hidden;position:absolute;left:-10000px;top:419px;width:1px;height:1px;">import java.util.*;<br />
import java.io.*;<br />
import javax.xml.parsers.*;<br />
import javax.xml.xpath.*;<br />
import org.w3c.dom.*;</p>
<p>import weblogic.security.internal.*; // requires weblogic.jar in the class path<br />
import weblogic.security.internal.encryption.*;</p>
<p>public class WebLogicDecryptor {</p>
<p>private static final String PREFIX = &#8220;{3DES}&#8221;;<br />
private static final String XPATH_EXPRESSION<br />
= &#8220;//node()[starts-with(text(), '" + PREFIX + "')] | //@*[starts-with(., '" + PREFIX + "')]&#8220;;</p>
<p>private static ClearOrEncryptedService ces;</p>
<p>public static void main(String[] args) throws Exception {<br />
if (args.length &lt; 2) {<br />
throw new Exception(&#8220;Usage: [domainDir] [configFile]&#8220;);<br />
}</p>
<p>ces = new ClearOrEncryptedService(SerializedSystemIni.getEncryptionService(new File(args[0]).getAbsolutePath()));<br />
File file = new File(args[1]);<br />
if (file.getName().endsWith(&#8220;.xml&#8221;)) {<br />
processXml(file);<br />
}<br />
else if (file.getName().endsWith(&#8220;.properties&#8221;)){<br />
processProperties(file);<br />
}<br />
}</p>
<p>private static void processXml(File file) throws Exception {<br />
Document doc = DocumentBuilderFactory.newInstance().newDocumentBuilder().parse(file);<br />
XPathExpression expr = XPathFactory.newInstance().newXPath().compile(XPATH_EXPRESSION);<br />
NodeList nodes = (NodeList)expr.evaluate(doc, XPathConstants.NODESET);<br />
for (int i = 0; i &lt; nodes.getLength(); i++) {<br />
Node node = nodes.item(i);<br />
print(node.getNodeName(), node.getTextContent());<br />
}<br />
}</p>
<p>private static void processProperties(File file) throws Exception {<br />
Properties properties = new Properties();<br />
properties.load(new FileInputStream(file));<br />
for (Map.Entry p : properties.entrySet()) {<br />
if (p.getValue().toString().startsWith(PREFIX)) {<br />
print(p.getKey(), p.getValue());<br />
}<br />
}<br />
}</p>
<p>private static void print(Object attributeName, Object encrypted) {<br />
System.out.println(&#8220;Node name: &#8221; + attributeName);<br />
System.out.println(&#8220;Encrypted: &#8221; + encrypted);<br />
System.out.println(&#8220;Decrypted: &#8221; + ces.decrypt((String)encrypted) + &#8220;\n&#8221;);<br />
}<br />
}</p>
</div>
<br /><img alt="" border="0" src="http://feeds.wordpress.com/1.0/categories/gustlik.wordpress.com/6/" /> <img alt="" border="0" src="http://feeds.wordpress.com/1.0/tags/gustlik.wordpress.com/6/" /> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/gustlik.wordpress.com/6/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/gustlik.wordpress.com/6/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/gustlik.wordpress.com/6/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/gustlik.wordpress.com/6/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/gustlik.wordpress.com/6/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/gustlik.wordpress.com/6/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/gustlik.wordpress.com/6/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/gustlik.wordpress.com/6/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/gustlik.wordpress.com/6/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/gustlik.wordpress.com/6/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/gustlik.wordpress.com/6/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/gustlik.wordpress.com/6/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/gustlik.wordpress.com/6/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/gustlik.wordpress.com/6/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=gustlik.wordpress.com&amp;blog=4027708&amp;post=6&amp;subd=gustlik&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://gustlik.wordpress.com/2008/08/06/decryption-of-configuration-passwords-in-weblogic/feed/</wfw:commentRss>
		<slash:comments>65</slash:comments>
	
		<media:content url="http://1.gravatar.com/avatar/1b86b37267763e08b3bcf2fc9e05bd6b?s=96&#38;d=wavatar" medium="image">
			<media:title type="html">rozbryzg</media:title>
		</media:content>
	</item>
		<item>
		<title>User context tracking in log4J</title>
		<link>http://gustlik.wordpress.com/2008/07/05/user-context-tracking-in-log4j/</link>
		<comments>http://gustlik.wordpress.com/2008/07/05/user-context-tracking-in-log4j/#comments</comments>
		<pubDate>Sat, 05 Jul 2008 11:39:55 +0000</pubDate>
		<dc:creator>Zbigniew Cyktor</dc:creator>
				<category><![CDATA[Java]]></category>

		<guid isPermaLink="false">http://gustlik.wordpress.com/?p=5</guid>
		<description><![CDATA[Majority of web applications based on Java platform use log4j library to record user activities. All is fun and games until the number of users and logged messages per unit of time exceed a specific threshold. Since log entries for multiple users are intermixed &#8211; it gets very difficult to analyze what exactly did a [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=gustlik.wordpress.com&amp;blog=4027708&amp;post=5&amp;subd=gustlik&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>Majority of web applications based on Java platform use <strong>log4j </strong>library to record user activities. All is fun and games until the number of users and logged messages per unit of time exceed a specific threshold. Since log entries for multiple users are intermixed &#8211; it gets very difficult to analyze what exactly did a specific user do within a single request.</p>
<p>Fortunately log4j provides a very convenient way of solving this problem. A class <a title="http://logging.apache.org/log4j/1.2/apidocs/org/apache/log4j/MDC.html" href="http://logging.apache.org/log4j/1.2/apidocs/org/apache/log4j/MDC.html">org.apache.log4j.MDC</a> provides a mechanism to &#8216;attach&#8217; any arbitrary information to a given thread that processes a request and to output this information into the log entry. What we need to do is to invoke a static method <strong>MDC.put(&#8220;userId&#8221;, userId) </strong>somewhere at the beginning of request processing chain (by using servlet filter for example) and add the element <strong>%X{userId}</strong> to the row format definition in log4j configuration, for example:</p>
<p>log4j.appender.file.layout.ConversionPattern=%d %5p %c <strong>%X{userId}</strong> (%F:%L) &#8211; %m%n</p>
<p>After that every log entry will contain user identifier which is all we need in most cases. Sometimes we might want to put into the log some additional data. If our application uses <strong>AJAX </strong>a lot, then a single user might issue multiple requests at the same time, which still can get mixed. It might be a good idea then to add a unique index value incremented after each request etc.</p>
<p>If you add this feature to your application, the people who routinely have to analyze its logs and solve user problems will be most grateful!</p>
<br /><img alt="" border="0" src="http://feeds.wordpress.com/1.0/categories/gustlik.wordpress.com/5/" /> <img alt="" border="0" src="http://feeds.wordpress.com/1.0/tags/gustlik.wordpress.com/5/" /> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/gustlik.wordpress.com/5/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/gustlik.wordpress.com/5/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/gustlik.wordpress.com/5/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/gustlik.wordpress.com/5/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/gustlik.wordpress.com/5/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/gustlik.wordpress.com/5/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/gustlik.wordpress.com/5/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/gustlik.wordpress.com/5/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/gustlik.wordpress.com/5/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/gustlik.wordpress.com/5/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/gustlik.wordpress.com/5/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/gustlik.wordpress.com/5/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/gustlik.wordpress.com/5/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/gustlik.wordpress.com/5/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=gustlik.wordpress.com&amp;blog=4027708&amp;post=5&amp;subd=gustlik&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://gustlik.wordpress.com/2008/07/05/user-context-tracking-in-log4j/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
	
		<media:content url="http://1.gravatar.com/avatar/1b86b37267763e08b3bcf2fc9e05bd6b?s=96&#38;d=wavatar" medium="image">
			<media:title type="html">rozbryzg</media:title>
		</media:content>
	</item>
		<item>
		<title>Hierarchical stopwatch measuring code performance</title>
		<link>http://gustlik.wordpress.com/2008/06/20/hierarchical-stopwatch-measuring-code-performance/</link>
		<comments>http://gustlik.wordpress.com/2008/06/20/hierarchical-stopwatch-measuring-code-performance/#comments</comments>
		<pubDate>Fri, 20 Jun 2008 14:09:11 +0000</pubDate>
		<dc:creator>Zbigniew Cyktor</dc:creator>
				<category><![CDATA[Java]]></category>
		<category><![CDATA[hierarchical stopwatch]]></category>

		<guid isPermaLink="false">http://gustlik.wordpress.com/?p=4</guid>
		<description><![CDATA[While developing software it is a good habit to keep an eye on performance of specific parts of code. There are obviously many ways to do it &#8211; we can for instance benchmark specific methods or modules as part of unit tests, we can use tools like JMeter to simulate larger number of users, we [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=gustlik.wordpress.com&amp;blog=4027708&amp;post=4&amp;subd=gustlik&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>While developing software it is a good habit to keep an eye on performance of specific parts of code. There are obviously many ways to do it &#8211; we can for instance benchmark specific methods or modules as part of unit tests, we can use tools like JMeter to simulate larger number of users, we can run a profiler from time to time etc. Despite having all these advanced approaches in reach, sometimes the most convenient (or lazy) way to measure performance is to wrap code with something like this:</p>
<p><pre class="brush: java;">

long t = System.currentTimeMillis();
doSomething();
System.out.println(&quot;took &quot; + (System.currentTimeMillis() - t) + &quot;ms&quot;);

</pre></p>
<p>There are definitely many cons to this approach &#8211; it&#8217;s not elegant, the results are scattered all over the log file, it can not be turned off and so on. If you happen to be using Spring Framework or Apache Commons, you might use one of their implementations of StopWatch class (<a href="http://static.springframework.org/spring/docs/2.0.x/api/org/springframework/util/StopWatch.html">here </a>and <a href="http://commons.apache.org/lang/api/org/apache/commons/lang/time/StopWatch.html">here</a>), which is a wrapper with some additional capabilities, like report formatting, providing of statistics etc.</p>
<p>Some time ago I was in a need to use a stop watch for a web application based on Spring. After spending some time with mentioned implementations it became obvious that what I needed was a slightly different mechanism &#8211; one that would allow me to see a hierarchical structure of time consumption of individual pieces of code. Something like:</p>
<p><pre class="brush: java;">
run() : 2753 ms
	foo() : 2753 ms
		bar() : 417 ms
			bang() : 60 ms
			bang() : 119 ms
			bang() : 238 ms
		bar() : 2336 ms
			bang() : 477 ms
			bang() : 953 ms
			bang() : 906 ms
</pre></p>
<p><span id="more-4"></span></p>
<p>At the end of this post you will find a source code of the class that I came up with. I hope that it might be useful either as  it is, or as basis to a more sophisticated implementation. The output looks very much like the example above. The interesting thing about this particular implementation is that since it uses ThreadLocal under the hood, it can be accessed through its static methods. Example usage might look like that:</p>
<p><pre class="brush: java;">
public class StopWatchTest {

	public static void main(String[] args) {
		StopWatch.reset();
		new StopWatchTest().run();
		System.out.println(StopWatch.prettyPrint());
	}

	public void run() {
		StopWatch.start(&quot;run()&quot;);
		foo();
		StopWatch.stop();
	}

	public void foo() {
		StopWatch.start(&quot;foo()&quot;);
		bar();
		bar();
		StopWatch.stop();
	}

	public void bar() {
		StopWatch.start(&quot;bar()&quot;);
		bang();
		bang();
		bang();
		StopWatch.stop();
	}

	public void bang() {
		StopWatch.start(&quot;bang()&quot;);
		sleepRandomly();
		StopWatch.stop();
	}

	public void sleepRandomly() {
		try {
			Thread.sleep(System.currentTimeMillis() % 1000);
		}
		catch (Exception e) {
			e.printStackTrace();
		}
	}
}
</pre></p>
<p>You can also easily deactivate it by setting threshold of it&#8217;s log4j logger above DEBUG level. In case of web applications it is a good idea to wrap it in a Servlet filter that will call StopWatch.reset() at the beginning of a request and StopWatch.prettyPrint() at the end. You might also easily wrap all Spring managed beans with a simple AOP advice that would transparently track performance of individual methods etc. Here&#8217;s the code:</p>
<p><pre class="brush: java;">

import java.util.*;
import org.apache.log4j.Logger;

public class StopWatch {

	private static final Logger log = Logger.getLogger(StopWatch.class);
	private static ThreadLocal&lt;StopWatch&gt; threadLocal = null;

	private long eventIndex = 0;
	private Stack&lt;Event&gt; events = new Stack&lt;Event&gt;();
	private Set&lt;Event&gt; eventsDone = new TreeSet&lt;Event&gt;(new EventComparator());

	private StopWatch() {
	}

	public static void reset() {
		if (log.isDebugEnabled() == false) return;
		getThreadLocal().set(new StopWatch());
	}

	public static void start(String eventName) {
		if (log.isDebugEnabled() == false) return;

		StopWatch stopWatch = getInstance();
		if (stopWatch != null) {
			stopWatch.startEvent(eventName);
		}
	}

	public static void stop() {
		if (log.isDebugEnabled() == false) return;

		StopWatch stopWatch = getInstance();
		if (stopWatch != null) {
			stopWatch.stopEvent();
		}
	}

	public static String prettyPrint() {
		if (log.isDebugEnabled() == false) return null;

		StopWatch stopWatch = getInstance();
		return (stopWatch != null) ? stopWatch.internalPrettyPrint() : null;
	}

	private void startEvent(String eventName) {
		eventIndex++;
		events.push(new Event(eventIndex, events.size(), eventName));
	}

	private void stopEvent() {
		if (events.size() == 0) return;

		Event event = events.pop();
		event.stop();
		eventsDone.add(event);
	}

	private String internalPrettyPrint() {
		StringBuilder sb = new StringBuilder();
		if  (events.size() != 0) {
			sb.append(&quot;WARNING: same events have not been marked as closed, &quot;);
			sb.append(&quot;the summary might contain wrong data...\n&quot;);
		}
		for (Event event : eventsDone) {
			sb.append(getTabs(event.getDepth()))
			.append(event.getName()).append(&quot; : &quot;).append(event.getTime()).append(&quot; ms\n&quot;);
		}

		return sb.toString();
	}

	private static String getTabs(int count) {
		StringBuilder sb = new StringBuilder(count);
		for (int i = 0; i &lt; count; i++) {
			sb.append(&quot;\t&quot;);
		}
		return sb.toString();
	}

	private static StopWatch getInstance() {
		return getThreadLocal().get();
	}

	private static ThreadLocal&lt;StopWatch&gt; getThreadLocal() {
		if (threadLocal == null) {
			threadLocal = new ThreadLocal&lt;StopWatch&gt;();
		}
		return threadLocal;
	}

	private class Event {

		private long index;
		private int depth;
		private String name;
		private long startTime;
		private long time;

		public Event(long index, int depth, String name) {
			this.index = index;
			this.depth = depth;
			this.name = name;
			startTime = System.currentTimeMillis();
		}

		public void stop() {
			time = System.currentTimeMillis() - startTime;
		}

		public long getIndex()  { return index; }
		public int getDepth()   { return depth; }
		public String getName() { return name; }
		public long getTime()   { return time; }
	}

	private class EventComparator implements Comparator&lt;Event&gt; {
		public int compare(Event left, Event right) {
			if (left == null &amp;&amp; right == null) return 0;
			if (left == null) return 1;
			if (right == null) return -1;
			return (int) (left.getIndex() - right.getIndex());
		}
	}
}

</pre></p>
<p>If you have suggestions on how to optimize or improve it in any way, I will be happy to hear from you!</p>
<br /><img alt="" border="0" src="http://feeds.wordpress.com/1.0/categories/gustlik.wordpress.com/4/" /> <img alt="" border="0" src="http://feeds.wordpress.com/1.0/tags/gustlik.wordpress.com/4/" /> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/gustlik.wordpress.com/4/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/gustlik.wordpress.com/4/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/gustlik.wordpress.com/4/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/gustlik.wordpress.com/4/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/gustlik.wordpress.com/4/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/gustlik.wordpress.com/4/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/gustlik.wordpress.com/4/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/gustlik.wordpress.com/4/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/gustlik.wordpress.com/4/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/gustlik.wordpress.com/4/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/gustlik.wordpress.com/4/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/gustlik.wordpress.com/4/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/gustlik.wordpress.com/4/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/gustlik.wordpress.com/4/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=gustlik.wordpress.com&amp;blog=4027708&amp;post=4&amp;subd=gustlik&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://gustlik.wordpress.com/2008/06/20/hierarchical-stopwatch-measuring-code-performance/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
	
		<media:content url="http://1.gravatar.com/avatar/1b86b37267763e08b3bcf2fc9e05bd6b?s=96&#38;d=wavatar" medium="image">
			<media:title type="html">rozbryzg</media:title>
		</media:content>
	</item>
		<item>
		<title>Cross-site scripting and HttpOnly attribute</title>
		<link>http://gustlik.wordpress.com/2008/06/20/cross-site-scripting-and-httponly-attribute/</link>
		<comments>http://gustlik.wordpress.com/2008/06/20/cross-site-scripting-and-httponly-attribute/#comments</comments>
		<pubDate>Fri, 20 Jun 2008 13:28:06 +0000</pubDate>
		<dc:creator>Zbigniew Cyktor</dc:creator>
				<category><![CDATA[Java]]></category>

		<guid isPermaLink="false">http://gustlik.wordpress.com/?p=3</guid>
		<description><![CDATA[Microsoft Internet Explorer(1) has an interesting feature which is not very well known. If a cookie has been set with attribute &#8216;HttpOnly&#8217; then the browser will forbid any access to it from client-side code. Javascript will not be able to read, write or acknowledge information stored in the cookie. At first sight this might not [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=gustlik.wordpress.com&amp;blog=4027708&amp;post=3&amp;subd=gustlik&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>Microsoft Internet Explorer<sup>(1)</sup> has an interesting feature which is not very well known. If a <strong>cookie </strong>has been set with attribute <strong>&#8216;HttpOnly&#8217;</strong> then the browser will forbid any access to it from client-side code. Javascript will not be able to read, write or acknowledge information stored in the cookie.</p>
<p>At first sight this might not seem to be very useful, but if we bring into the picture security of web applications and especially <strong>cross-site scripting (XSS)</strong> vulnerabilities &#8211; things get interesting. One of the classical examples of XSS attack is the one in which a hacker manages to read user&#8217;s session identifier from a cookie and use it to access a resource<sup>(2)</sup>.</p>
<p>The most obvious way to remediate that would be to use HttpOnly attribute while setting the <strong>JSESSIONID </strong>cookie. Unfortunately this step is done by the application server itself and as on now most of them do not use HttpOnly<sup>(3)</sup>. What we might try to do is to rewrite the cookie after it has been created as shown here: <a title="http://keepitlocked.net/archive/2007/11/05/java-and-httponly.aspx" href="http://keepitlocked.net/archive/2007/11/05/java-and-httponly.aspx" target="_self">http://keepitlocked.net/archive/2007/11/05/java-and-httponly.aspx</a>.</p>
<p>But there&#8217;s also another way which you might consider.</p>
<p><span id="more-3"></span></p>
<p>We are going to use a Servlet filter to do following:</p>
<ol>
<li>On the first request within a session we create a token &#8211; it should be a random value, just as JSESSIONID is. We store the token as a HttpOnly cookie and also as a session attribute.</li>
<li>On every subsequent request we compare whether the cookie token is equal to the value stored in session.</li>
<li>If cookie token is missing or they are different &#8211; we can assume that a third party is trying to impersonate the user by using stolen JSESSIONID.</li>
<li>In such case we can invalidate the whole session, inform an administrator about the attempt or even let the original user know that somebody has been trying to hack in.</li>
</ol>
<p>Aside of giving us a chance to trace this particular type of abuse, this mechanism can also be used to deal with one more case. Some older servlet containers (that will remain nameless <img src='http://s0.wp.com/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' />  ) create session identifiers of a fixed length without providing any configuration option to make them longer. If your application happens to be audited &#8211; too short session identifier will most likely by treated as a vulnerability and required to be fixed.</p>
<p>By using the mechanism described above we can effectively <strong>control the length of session id</strong>, because from practical perspective the session identifier length will be equal to JSESSIONID length plus our hand-generated token length. In real life this approach has helped me to get approval of the ethical hacking team more than once.</p>
<p>A proof-of-concept code below, feel free to suggest changes.</p>
<p><pre class="brush: java;">

import java.io.IOException;
import javax.servlet.*;
import javax.servlet.http.*;

public class HttpOnlyTokenFilter implements Filter {

    private static final String TOKEN_KEY = &quot;HTTP_ONLY_TOKEN&quot;;

    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
        throws IOException, ServletException {

        validateToken((HttpServletRequest)request, (HttpServletResponse)response);
        chain.doFilter(request, response);
    }

    private void validateToken(HttpServletRequest request, HttpServletResponse response) {
        HttpSession session = request.getSession(true);
        String token = (String)session.getAttribute(TOKEN_KEY);
        if (token == null) {
            token = getRandomString();
            session.setAttribute(TOKEN_KEY, token);
            response.addHeader(&quot;Set-Cookie&quot;, TOKEN_KEY + &quot;=&quot; + token + &quot;;httpOnly&quot;);
        }
        else {
            String cookieToken = getCookieValue(request.getCookies(), TOKEN_KEY);
            if (token.equals(cookieToken) == false) {
                session.invalidate();
            }
        }
    }

    private String getCookieValue(Cookie[] cookies, String cookieName) {
        if (cookies == null) return null;
        for (Cookie cookie : cookies) {
            if (cookieName.equals(cookie.getName())) return cookie.getValue();
        }
        return null;
    }

    private String getRandomString() {
        return String.valueOf(System.currentTimeMillis()); // TODO: replace with more random value. I mean it!
    }

    public void init(FilterConfig filterConfig) throws ServletException {}
    public void destroy() {}
}

</pre></p>
<p><sup>(1)</sup>It seems that soon all mayor browsers will support this feature as well, for example  <a title="http://blogs.securiteam.com/index.php/archives/849" href="http://blogs.securiteam.com/index.php/archives/849">http://blogs.securiteam.com/index.php/archives/849</a><br />
<sup>(2)</sup> As in <a title="http://www.owasp.org/index.php/Session_hijacking_attack" href="http://www.owasp.org/index.php/Session_hijacking_attack">http://www.owasp.org/index.php/Session_hijacking_attack</a><br />
<sup>(3)</sup> Things are improving here as well: <a title="https://issues.apache.org/bugzilla/show_bug.cgi?id=44382" href="https://issues.apache.org/bugzilla/show_bug.cgi?id=44382">https://issues.apache.org/bugzilla/show_bug.cgi?id=44382</a></p>
<br /><img alt="" border="0" src="http://feeds.wordpress.com/1.0/categories/gustlik.wordpress.com/3/" /> <img alt="" border="0" src="http://feeds.wordpress.com/1.0/tags/gustlik.wordpress.com/3/" /> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/gustlik.wordpress.com/3/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/gustlik.wordpress.com/3/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/gustlik.wordpress.com/3/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/gustlik.wordpress.com/3/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/gustlik.wordpress.com/3/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/gustlik.wordpress.com/3/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/gustlik.wordpress.com/3/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/gustlik.wordpress.com/3/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/gustlik.wordpress.com/3/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/gustlik.wordpress.com/3/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/gustlik.wordpress.com/3/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/gustlik.wordpress.com/3/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/gustlik.wordpress.com/3/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/gustlik.wordpress.com/3/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=gustlik.wordpress.com&amp;blog=4027708&amp;post=3&amp;subd=gustlik&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://gustlik.wordpress.com/2008/06/20/cross-site-scripting-and-httponly-attribute/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
	
		<media:content url="http://1.gravatar.com/avatar/1b86b37267763e08b3bcf2fc9e05bd6b?s=96&#38;d=wavatar" medium="image">
			<media:title type="html">rozbryzg</media:title>
		</media:content>
	</item>
	</channel>
</rss>
