HOME - Recent Changes - Search:

Academic Work


Personal

* pot de départ


dblp


(:twitter:)

-----

[ edit | logout ]
[ help | sandbox | passwd ]

Cryptography Notes

#############################

Intro

I had to write a simple program that implements a symmetric encoding. Here I collect what I learnt for future references.

Requirement

We have a string that we want to encode with a key (secret password). Decoding the ciphered text using the same password we want to get back the original string. This is a symmetric encoding case since we want to use the same key for both encoding and decoding.

About Cryptography

Tutorials and Examples

Base64 encoding

For doing the base64 encoding, I used the Bouncy Castle implementation. The file that I downloaded is called bcprov-jdk16-145.jar.

Important! At http://www.di-mgt.com.au/properpassword.html it is pointed out:

"Ciphertext is not text! Ciphertext is a bit string that should not be stored in a "string" type. Encode the ciphertext in hexadecimal or base64, which can be safely stored and transmitted as a string type."

I had a problem here that I could solve with the base64 encoding. The scenario was the following:

  • I had a plain (input) text that I encoded.
  • The result of the encoding was a byte array. I converted it to string and stored it in a file.
  • For testing the decoding part, I read the string back and converted it back to a byte array.
  • However, this byte array was now different from the byte array that I got after the encoding.

Lesson learned: if you have a byte array, don't store it in a string because you will lose the data. Converting back from the string to a byte array will not result the original byte array!

Solution:

  • If you have a byte array, do a base64 encoding, and then you can store it in a string.
  • Getting back the original byte array: take the base64 string and decode it.

Further readings:


My Solution

Here is a concrete solution that worked for me:

import java.security.InvalidKeyException;
import java.security.Key;
import java.security.NoSuchAlgorithmException;

import javax.crypto.BadPaddingException;
import javax.crypto.Cipher;
import javax.crypto.IllegalBlockSizeException;
import javax.crypto.NoSuchPaddingException;
import javax.crypto.spec.SecretKeySpec;

import org.bouncycastle.util.encoders.Base64;

/**
 * encryption/decryption
 * 
 * @author Jabba Laci (jabba.laci@gmail.com)
 */
public class EncryptDecrypt 
{
	/**
	 * Which algorithm to use.
	 */
	private String algorithm = "AES";

	private Key key;

	private Cipher cipher;

	/**
	 * Constructor. 
	 */
	public EncryptDecrypt() 
	{
	    // must be 16 bytes long
	    // the lines below were used for test purposes only
	    byte[] keyBytes = { 0x01, 0x02, 0x03, 0x04,
	                        0x05, 0x06, 0x07, 0x08,
	                        0x09, 0x10, 0x11, 0x12,
	                        0x13, 0x14, 0x15, 0x16 };

    	    try {
	        key = new SecretKeySpec(keyBytes, algorithm);
		cipher = Cipher.getInstance(algorithm);
	    } 
	    catch (NoSuchAlgorithmException e) {
		e.printStackTrace();
	    }
	    catch (NoSuchPaddingException e) {
	        e.printStackTrace();
	    }
	}

	/*
	 * The two functions that do the real job are below.
	 */

	/**
	 * Get a plain string, encode it with AES, then apply a base64 encoding on the
	 * raw byte stream. This way the result can be safely stored in a String.
	 * 
	 * WARNING! If you get the raw byte stream (call it A), convert it to String (B),
	 * then convert it back to byte stream, you won't get back the original A stream.
	 * The AES algorithm uses padding, which leads to problem. However, if you
	 * convert it to base64, you can store that in a String.
	 * 
	 * @param input A string that we want to encode.
	 * @return
	 * @throws InvalidKeyException
	 * @throws BadPaddingException
	 * @throws IllegalBlockSizeException
	 */
	public String encrypt(String input) 
	throws InvalidKeyException, BadPaddingException, IllegalBlockSizeException 
	{
	    cipher.init(Cipher.ENCRYPT_MODE, key);
	    byte[] inputBytes = input.getBytes();

	    byte[] rawResult = cipher.doFinal(inputBytes);
	    byte[] base64 = Base64.encode(rawResult); 
	    return (new String(base64));
	}

	/**
	 * Get a base64-encoded String, convert it safely to a base64 byte stream,
	 * then decode the base64 stream to a raw byte stream.
	 * Then decode this byte stream with AES to get back the originally
	 * encoded input String.
	 * 
	 * @param base64str
	 * @return
	 * @throws InvalidKeyException
	 * @throws BadPaddingException
	 * @throws IllegalBlockSizeException
	 */
	public String decrypt(String base64str) 
	throws InvalidKeyException, BadPaddingException, IllegalBlockSizeException 
	{
	    byte[] base64 = base64str.getBytes();
	    byte[] encryptionBytes = Base64.decode(base64); 
	    //
	    cipher.init(Cipher.DECRYPT_MODE, key);
	    byte[] recoveredBytes = cipher.doFinal(encryptionBytes);
	    String recovered = new String(recoveredBytes);
	    return recovered;
	}

} // class EncryptDecrypt

Usage:

EncryptDecrypt ed = new EncryptDecrypt();

String input = "text to be encoded";
System.out.println("input : " + "'" + input + "'");

String base64EncodedStr = ed.encrypt(input);
System.out.println("cipher: " + "'" + base64EncodedStr + "'");
System.out.println("plain : " + "'" + ed.decrypt(base64EncodedStr) + "'");

Output:

input : 'text to be encoded'
cipher: 'frl8Sx0DWiIu+c2j+er/+VjakPDyLOl504+jT+YVnLs='
plain : 'text to be encoded'
Cloud City


anime | bash | blogs | bsd | c/c++ | c64 | calc | comics | convert | cube | del.icio.us | digg | east | eBooks | egeszseg | elite | firefox | flash | fun | games | gimp | google | groovy | hardware | hit&run | howto | java | javascript | knife | lang | latex | liferay | linux | lovecraft | magyar | maths | movies | music | p2p | perl | pdf | photoshop | php | pmwiki | prog | python | radio | recept | rts | scala | scene | sci-fi | scripting | security | shell | space | súlyos | telephone | torrente | translate | ubuntu | vim | wallpapers | webutils | wikis | windows


Blogs and Dev.

* Ubuntu Incident
* Python Adventures
* me @ GitHub


Places

Debrecen | France | Hungary | Montreal | Nancy


Notes

full circle | km


Hobby Projects

* Jabba's Codes
* PmWiki
* Firefox
* PHP
* JavaScript
* Scriptorium
* Tutorials
* me @ GitHub


Quick Links


[ edit ]

View - Edit - History - Attach - Print *** Report - Recent Changes - Search
Page last modified on 2010 February 17, 21:55