Tuesday, November 11, 2008

RSA algorithm

In a classic cryptosystem in order to make sure that nobody, except the intended recipient, deciphers the message, the people involved had to strive to keep the key secret. In a public-key cryptosystem. The public key cryptography solves one of the most vexing problems of all prior cryptography: the necessity of establishing a secure channel for the exchange of the key.

RSA algorithm is a public-key cryptosystem defined by Rivest, Shamir, and Adleman. The scheme is as follows:

Let p and q be distinct large primes and let n be their product. Assume that we also computed two integers, d (for decryption) and e (for encryption) such that

d * e 1 (mod ø(n))

where ø(n) is the number of positive integers smaller than n that have no factor except 1 in common with n

The integers n and e are made public, while p, q, and d are kept secret.

Let m be the message to be sent, where m is a positive integer less than and relatively prime to n. A plaintext message is easily converted to a number by using either the alphabet position of each letter (a=01, b=02, ..., z=26) or using the standard ASCII table. If necessary (so that m
The encoder computes and sends the number

m' = m^e mod n

To decode, we simply compute

e^d mod n

Now, since both n and e are public, the question arises: can we compute from them d? The answer: it is possible, if n is factored into prime numbers.

The security of RSA depends on the fact that it takes an impractical amount of time to factor large numbers.

Triple DES Algorithm

Triple DES is simply another mode of DES operation. It takes three 64-bit keys, for an overall key length of 192 bits. In Private Encryptor, you simply type in the entire 192-bit (24 character) key rather than entering each of the three keys individually. The Triple DES DLL then breaks the user provided key into three subkeys, padding the keys if necessary so they are each 64 bits long. The procedure for encryption is exactly the same as regular DES, but it is repeated three times. Hence the name Triple DES. The data is encrypted with the first key, decrypted with the second key, and finally encrypted again with the third key.

Consequently, Triple DES runs three times slower than standard DES, but is much more secure if used properly. The procedure for decrypting something is the same as the procedure for encryption, except it is executed in reverse. Like DES, data is encrypted and decrypted in 64-bit chunks. Unfortunately, there are some weak keys that one should be aware of: if all three keys, the first and second keys, or the second and third keys are the same, then the encryption procedure is essentially the same as standard DES. This situation is to be avoided because it is the same as using a really slow version of regular DES.

Note that although the input key for DES is 64 bits long, the actual key used by DES is only 56 bits in length. The least significant (right-most) bit in each byte is a parity bit, and should be set so that there are always an odd number of 1s in every byte. These parity bits are ignored, so only the seven most significant bits of each byte are used, resulting in a key length of 56 bits. This means that the effective key strength for Triple DES is actually 168 bits because each of the three keys contains 8 parity bits that are not used during the encryption process.

Monday, November 10, 2008

Java code for Triple DES Algorithm

package com.davidflanagan.examples.security;
import javax.crypto.*;
import javax.crypto.spec.*;
import java.security.*;
import java.security.spec.*;
import java.io.*;

/**
* This class defines methods for encrypting and decrypting using the Triple
* DES algorithm and for generating, reading and writing Triple DES keys.
* It also defines a main() method that allows these methods to be used
* from the command line.
**/
public class TripleDES {
/**
* The program. The first argument must be -e, -d, or -g to encrypt,
* decrypt, or generate a key. The second argument is the name of a file
* from which the key is read or to which it is written for -g. The
* -e and -d arguments cause the program to read from standard input and
* encrypt or decrypt to standard output.
**/
public static void main(String[] args) {
try {
// Check to see whether there is a provider that can do TripleDES
// encryption. If not, explicitly install the SunJCE provider.
try { Cipher c = Cipher.getInstance("DESede"); }
catch(Exception e) {
// An exception here probably means the JCE provider hasn't
// been permanently installed on this system by listing it
// in the $JAVA_HOME/jre/lib/security/java.security file.
// Therefore, we have to install the JCE provider explicitly.
System.err.println("Installing SunJCE provider.");
Provider sunjce = new com.sun.crypto.provider.SunJCE();
Security.addProvider(sunjce);
}

// This is where we'll read the key from or write it to
File keyfile = new File(args[1]);

// Now check the first arg to see what we're going to do
if (args[0].equals("-g")) { // Generate a key
System.out.print("Generating key. This may take some time...");
System.out.flush();
SecretKey key = generateKey();
writeKey(key, keyfile);
System.out.println("done.");
System.out.println("Secret key written to " + args[1] +
". Protect that file carefully!");
}
else if (args[0].equals("-e")) { // Encrypt stdin to stdout
SecretKey key = readKey(keyfile);
encrypt(key, System.in, System.out);
}
else if (args[0].equals("-d")) { // Decrypt stdin to stdout
SecretKey key = readKey(keyfile);
decrypt(key, System.in, System.out);
}
}
catch(Exception e) {
System.err.println(e);
System.err.println("Usage: java " + TripleDES.class.getName() +
" -d|-e|-g ");
}
}

/** Generate a secret TripleDES encryption/decryption key */
public static SecretKey generateKey() throws NoSuchAlgorithmException {
// Get a key generator for Triple DES (a.k.a DESede)
KeyGenerator keygen = KeyGenerator.getInstance("DESede");
// Use it to generate a key
return keygen.generateKey();
}

/** Save the specified TripleDES SecretKey to the specified file */
public static void writeKey(SecretKey key, File f)
throws IOException, NoSuchAlgorithmException, InvalidKeySpecException
{
// Convert the secret key to an array of bytes like this
SecretKeyFactory keyfactory = SecretKeyFactory.getInstance("DESede");
DESedeKeySpec keyspec =
(DESedeKeySpec)keyfactory.getKeySpec(key, DESedeKeySpec.class);
byte[] rawkey = keyspec.getKey();

// Write the raw key to the file
FileOutputStream out = new FileOutputStream(f);
out.write(rawkey);
out.close();
}

/** Read a TripleDES secret key from the specified file */
public static SecretKey readKey(File f)
throws IOException, NoSuchAlgorithmException,
InvalidKeyException, InvalidKeySpecException
{
// Read the raw bytes from the keyfile
DataInputStream in = new DataInputStream(new FileInputStream(f));
byte[] rawkey = new byte[(int)f.length()];
in.readFully(rawkey);
in.close();

// Convert the raw bytes to a secret key like this
DESedeKeySpec keyspec = new DESedeKeySpec(rawkey);
SecretKeyFactory keyfactory = SecretKeyFactory.getInstance("DESede");
SecretKey key = keyfactory.generateSecret(keyspec);
return key;
}

/**
* Use the specified TripleDES key to encrypt bytes from the input stream
* and write them to the output stream. This method uses
* CipherOutputStream to perform the encryption and write bytes at the
* same time.
**/
public static void encrypt(SecretKey key, InputStream in, OutputStream out)
throws NoSuchAlgorithmException, InvalidKeyException,
NoSuchPaddingException, IOException
{
// Create and initialize the encryption engine
Cipher cipher = Cipher.getInstance("DESede");
cipher.init(Cipher.ENCRYPT_MODE, key);

// Create a special output stream to do the work for us
CipherOutputStream cos = new CipherOutputStream(out, cipher);

// Read from the input and write to the encrypting output stream
byte[] buffer = new byte[2048];
int bytesRead;
while((bytesRead = in.read(buffer)) != -1) {
cos.write(buffer, 0, bytesRead);
}
cos.close();

// For extra security, don't leave any plaintext hanging around memory.
java.util.Arrays.fill(buffer, (byte) 0);
}

/**
* Use the specified TripleDES key to decrypt bytes ready from the input
* stream and write them to the output stream. This method uses
* uses Cipher directly to show how it can be done without
* CipherInputStream and CipherOutputStream.
**/
public static void decrypt(SecretKey key, InputStream in, OutputStream out)
throws NoSuchAlgorithmException, InvalidKeyException, IOException,
IllegalBlockSizeException, NoSuchPaddingException,
BadPaddingException
{
// Create and initialize the decryption engine
Cipher cipher = Cipher.getInstance("DESede");
cipher.init(Cipher.DECRYPT_MODE, key);

// Read bytes, decrypt, and write them out.
byte[] buffer = new byte[2048];
int bytesRead;
while((bytesRead = in.read(buffer)) != -1) {
out.write(cipher.update(buffer, 0, bytesRead));
}

// Write out the final bunch of decrypted bytes
out.write(cipher.doFinal());
out.flush();
}
}

AES (Advanced Encription Algorithm )

The Advanced Encryption Standard (AES Algorithm) is a computer security standard that became effective on May 26, 2002 by NIST to replace DES. The cryptography scheme is a symmetric block cipher that encrypts and decrypts 128-bit blocks of data. Lengths of 128, 192, and 256 bits are standard key lengths used by AES Algorithm.

The algorithm consists of four stages that make up a round which is iterated 10 times for a 128-bit length key, 12 times for a 192-bit key, and 14 times for a 256-bit key. The first stage "SubBytes" transformation is a non-linear byte substitution for each byte of the block. The second stage "ShiftRows" transformation cyclically shifts (permutes) the bytes within the block. The third stage "MixColumns" transformation groups 4-bytes together forming 4-term polynomials and multiplies the polynomials with a fixed polynomial mod (x^4+1). The fourth stage "AddRoundKey" transformation adds the round key with the block of data.

In most ciphers, the iterated transform (or round) usually has a Feistel Structure. Typically in this structure, some of the bits of the intermediate state are transposed unchanged to another position (permutation). AES Algorithm does not have a Feistel structure but is composed of three distinct invertible transforms based on the Wide Trial Strategy design method.

Tuesday, June 10, 2008

Simple java code for AES Encryption

import java.io.*;
import java.security.*;
import javax.crypto.*;

public class MakeEncrypt {

public static void main(String args[]) {
if(args.length<2) {
System.out.println("Usage: MakeEncrypt plaintext ciphertext");
return;
}

try {
//Generate a key
Cipher cipher = Cipher.getInstance("AES/CBC/PKCS7Padding", "BC");
KeyGenerator generator = KeyGenerator.getInstance("AES", "BC");
generator.init(192);
Key encryptionKey = generator.generateKey();
System.out.println("key : " + Utils.toHex(encryptionKey.getEncoded()));

// Open input and out fileencryption pass
FileInputStream fis = new FileInputStream(args[0]);
DataInputStream fdata=new DataInputStream(fis);
FileOutputStream fos = new FileOutputStream(args[1]);

// init encryption
cipher.init(Cipher.ENCRYPT_MODE,encryptionKey);
CipherOutputStream cOut = new CipherOutputStream(fos,cipher);
DataOutputStream dout = new DataOutputStream(cOut);

String s;
while ((s=fdata.readLine())!=null) {
dout.writeBytes(s);
}

// Save keys and IV
FileOutputStream keyfile = new FileOutputStream("keys");
ObjectOutputStream keyout = new ObjectOutputStream(keyfile);
keyout.writeObject(new String(cipher.getIV()));
keyout.writeObject(new String(encryptionKey.getEncoded()));
System.out.println("Encrypted!");

} catch (Exception e) {
System.out.println(e);
}
}
}