Monday, 13 December 2010

OpenSSL - Java password based DES encryption roundtrip

A short guide to encrypt strings with openssl (such as in Linux) and decrypt them in Java and vice-versa


Open SSL:

To encrypt a string using a password (using a random salt and base64 encoding the binary result):
echo -n 'string to encrypt' | openssl enc -des -a -e -k 'password to use' 



To decrypt a string (such as the one produced by the statement above):
echo 'base64 encoded string to decrypt' | openssl enc -des -a -d -k 'password to use'


To make sure this works for you, just type the following (the "-n" is omitted from echo so a new line is printed):
echo 'test' | openssl enc -des -a -e -k 'pwd' | openssl enc -des -a -d -k 'pwd' 
This should print 'test' to the standard output (without quotes) 


Java:

The full source code of the class is at the end of the post. Full maven based project can be obtained from "svn checkout http://tomas-sample-code.googlecode.com/svn/trunk/openssl-roundtrip".


To decrypt a string encrypted with the above method, we have to understand the structure of the generated bytes. The openssl command creates the following structure (this is the "raw" bytes that get base64 encoded later):
bytes 1 - 8: "magic" word, fixed to "Salted__"
bytes 9 - 16: salt used to encrypt the string
bytes 17 and up: the actual encrypted value
The algorithm used in java is "PBEWithMD5AndDES" and the iteration count is 1. 


Encryption in java follows the same rules, only the salt is randomly generated, to make sure that when we encrypt the same text twice with the same password, we get a different result (mostly).


I am using the Apache commons-codec library for base64 encoding.


Tuesday, 24 August 2010

JRockit Mission Control (JRMC) Console Connectivity (R28) through Firewall

When connecting JRMC to a remote machine protected by a firewall, the following options can help:
  • Enable JRockit management (details on JRockit -X Command Line Options): -Xmanagement:autodiscovery=true,ssl=false,authenticate=false,port=7491,interface=<IP address or DNS hostname>
    • port - the port on which JRockit opens the management port
    • interface - the port will listen on all addresses, but JRockit will accept only requests for the IP address/hostname defined here
  • Specify a listen host for the java RMI server - this host is reported by the JVM back to the console and used for further connectivity. If not defined on multi-IP machines this can cause connectivity issues, as the first IP is always returned, even if a virtual IP was used to connect to the server. JVM option: -Djava.rmi.server.hostname=<IP address or DNS hostname>
  • Choose a port for MemLeak and configure it on the client (In JRMC client, go to Window/Preferences/JRockit Mission Control/Memory Leak Detector/Communication and choose "Use fixed port" and set the value to the port chosen) - I would recommend a single port for all servers, so you do not have to reconfigure your client each time you connect (usually you don't need to start MemLeak on more than one node of a cluster).