Friday, December 17, 2010

How to store a SecretKey in Java

This demo shows how to maintain a secret (symmetric) key in a java class. This key can then be used for encrypting / decrypting data that should be secret outside that class but must be transported. The Cipher used here is DESede, other ciphers could be used as well.

When using a KeyGenerator each time the class is initialized, the encrypted messages can not be read by a another process. Therefore the SecretKey is generated once, and then revived when the class is loaded.

** IMPORTANT **
Note that the SecretKey is now in your java source file, and will be in the compilation result. Your secrets can be read by anyone who can access your source or your binaries.


Generating the key

SecretKey key = KeyGenerator.getInstance("DESede").generateKey();
BigInteger num = new BigInteger(1, key.getEncoded());
System.out.println("Key: "+ num.toString())


Copy the resulting string (a big number)


Making the SecretKey available


public class YourClass {
private static String algorithm = "DESede";
private static byte[] encodedKey = new BigInteger("[[[[ Post the big number here ]]]]", 16).toByteArray();
}


Using the encoded SecretKey


DESedeKeySpec keySpec = new DESedeKeySpec(encodedKey);
SecretKeyFactory keyFactory = SecretKeyFactory.getInstance(algorithm);
SecretKey key = keyFactory.generateSecret(keySpec);

Cipher cipher = Cipher.getInstance(algorithm);
Cipher decipher = Cipher.getInstance(algorithm);

cipher.init(Cipher.ENCRYPT_MODE, key);
decipher.init(Cipher.DECRYPT_MODE, key);


Encrypting and decrypting


String message = "Hello World";
byte[] encryptedBytes = cipher.doFinal(message.getBytes());
String encryptedMessage = Base64.encode(encryptedBytes);

// Transport the base64 string, for example over http

byte[] messageToDecrypt = Base64.decode(encryptedMessage);
byte[] decryptedBytes = decipher.doFinal(messageToDecrypt);
String decryptedMessage = new String(decryptedBytes);
System.out.println(decryptedMessage);


References



Thursday, November 25, 2010

Merging svn using Meld

Meld is a great tool, and it can ease the pain of svn greatly. Unfortunately, until recently (not yet in version 1.3), it did not support a merge result file argument.

But now it does! (still experimental and not officially released)

So how to use it (under linux, or unix compatible systems):
Check if your Meld is > 1.3, if not,
Check the meld website to see if Meld > 1.3 is released and install it.
If you got Meld > 1.3 go ahead with "SVN Meld glue".

Build Meld source


Fetch the Meld source and build it using:
cd ~/bin
git clone git://git.gnome.org/meld
cd meld
make
./bin/meld

If all went fine, you should be running Meld > 1.3 now. Close it off.

SVN Meld glue


Start a text editor.
Write the following to a file named ~/bin/svn-merge-meld
#!/usr/bin/env python
# svn merge-tool python wrapper for meld
import sys
import subprocess

# path to meld ($ which meld)
meld = "~/bin/meld/bin/meld"
log = False
f = open('/tmp/svn-merge-meld.log', 'a')

def main():
if log:
f.write("call: %r\n" % sys.argv)

# file paths
base = sys.argv[1]
theirs = sys.argv[2]
mine = sys.argv[3]
merged = sys.argv[4]
partial = sys.argv[5]

# the call to meld
cmd = [meld, mine, base, theirs, merged]

# Call meld, making sure it exits correctly
subprocess.check_call(cmd)

try:
main()
except Exception as e:
print "Oh noes, an error: %r" % e
if log:
f.write("Error: %r\n" % e)
sys.exit(-1)
Change the file permissions to +x:
chmod +x ~/bin/svn-merge-meld

With the text editor, edit ~/.subversion/config
Locate this section:
### Set merge-tool-cmd to the command used to invoke your external
### merging tool of choice. Subversion will pass 4 arguments to
### the specified command: base theirs mine merged
# merge-tool-cmd = merge_command
Add this below it:
merge-tool-cmd = ~/bin/svn-merge-meld

Usage


svn merge -r 14829:HEAD http://path/to/trunk my/branch
Select: (p) postpone, (df) diff-full, (e) edit, (r) resolved,
(mc) mine-conflict, (tc) theirs-conflict,
(s) show all options:
Press l-Enter (the letter L) to fire up Meld.
In this case:
  • the left side is the change in my/branch
  • the middle part is the merge result which you can edit
  • the right side are the changes in the trunk
Merge, save and quit, then in the console press r-Enter, and your done. (Almost) painless merging in svn!

References


Friday, November 19, 2010

How to change the logging facility in java from org.apache.commons.logging.Log to java.util.logging.Logger;

With a shellscript and some Perl of course!


#!/bin/sh

#
# Note 1: make a backup.
# Note 2: check result and edit manually
#

find . -name \*.java -exec perl -pi -e's/([\s\t](?:(?:private|static|final)[\s\t]+)*)Log(\s+\w+\s+=\s+)LogFactory.getLog\(\s*([^.]+)\.class\s*\)/${1}Logger${2}Logger.getLogger($3.class.getName())/' \{\} \;

find . -name \*.java -exec perl -pi -e's/(import\s+)org.apache.commons.logging.Log\s*;\s*(\r?\n)/import java.util.logging.Logger;$2import java.util.logging.Level;$2/' \{\} \;
find . -name \*.java -exec perl -pi -e's/import\s+org.apache.commons.logging.LogFactory\s*;\s*\r?\n//' \{\} \;

#isWarnEnabled
#isInfoEnabled
#isDebugEnabled
#isTraceEnabled

find . -name \*.java -exec perl -pi -e's/log.isWarnEnabled\(\)/log.isLoggable(Level.WARNING)/g' \{\} \;
find . -name \*.java -exec perl -pi -e's/log.isInfoEnabled\(\)/log.isLoggable(Level.INFO)/g' \{\} \;
find . -name \*.java -exec perl -pi -e's/log.isDebugEnabled\(\)/log.isLoggable(Level.FINE)/g' \{\} \;
find . -name \*.java -exec perl -pi -e's/log.isTraceEnabled\(\)/log.isLoggable(Level.FINER)/g' \{\} \;

#fatal
#error
#warn
#info
#debug
#trace

find . -name \*.java -exec perl -pi -e's/log.fatal\(/log.log(Level.SEVERE, /g' \{\} \;
find . -name \*.java -exec perl -pi -e's/log.error\(/log.log(Level.WARNING, /g' \{\} \;
find . -name \*.java -exec perl -pi -e's/log.warn\(/log.log(Level.WARNING, /g' \{\} \;
find . -name \*.java -exec perl -pi -e's/log.info\(/log.log(Level.INFO, /g' \{\} \;
find . -name \*.java -exec perl -pi -e's/log.debug\(/log.log(Level.FINE, /g' \{\} \;
find . -name \*.java -exec perl -pi -e's/log.trace\(/log.log(Level.FINER, /g' \{\} \;