Chat LIVE With Programming Experts! There Are 23 Online Right Now...

Welcome to Dream.In.Code
Become a Java Expert!

Join 244,303 Java Programmers for FREE! Get instant access to thousands of Java experts, tutorials, code snippets, and more! There are 765 people online right now. Registration is fast and FREE... Join Now!




AES implementation

 
Reply to this topicStart new topic

AES implementation

jyo06
25 Nov, 2008 - 06:05 AM
Post #1

New D.I.C Head
*

Joined: 25 Nov, 2008
Posts: 6

Background - I have a system wherein the files are moving between two servers. The server1 is encrypting the file before sending out and it is decrypted by the server2 at the receiving end. And while sending it back, file is encrypted and the server1 decrypts the recieved file.

Currently, for this - Triple DES 128 bit algo is being implemented. And now would like to switch to AES 256 bit algo.

Here is the code snippet for both --If you could please have a look at it, and confirm that the new one that is AES 256 bit has been implemented correctly or not.

TRIPLE DES[u]
CODE


import org.apache.log4j.Logger;
import javax.crypto.*;
import javax.crypto.spec.SecretKeySpec;
import java.util.StringTokenizer;
import java.security.Key;
import java.security.NoSuchAlgorithmException;
import java.security.InvalidKeyException;
import java.io.*;

/**
* Utility class for performing cryptography using DESede (Triple DES) 128-bit
* algorithm

*/
public class Crypto {
     private static Logger logger = Logger.getLogger(Crypto.class);
    // DESede = Triple DES encryption
    private static final String ALGORITHM = "DESede";
    private static final String KEY_STRING = "172-29-987-1-58-555-910-747-"
            + "914-654-9-59-478-20-907-846-" + "77-69-650-213-12-73-264-652";
    private Cipher encryptCipher;
    private Cipher decryptCipher;
    private static Crypto instance;
    private Crypto() {
        try {
            // Get our secret key
            Key key = getKey();
            // initialise our ciphers
            // Create and initialize the encryption engine
            encryptCipher = Cipher.getInstance(ALGORITHM);
            logger.debug("Crypto: encryptCipher instance created");
            decryptCipher = Cipher.getInstance(ALGORITHM);
            logger.debug("Crypto: decryptCipher instance created");
            encryptCipher.init(Cipher.ENCRYPT_MODE, key);
            logger.debug("Crypto: encryptCipher initialised");
            decryptCipher.init(Cipher.DECRYPT_MODE, key);
            logger.debug("Crypto: decryptCipher initialised");
        } catch (NoSuchAlgorithmException e) {
            logger.error("<init>", e);
        } catch (NoSuchPaddingException e) {
            logger.error("<init>", e);
        } catch (InvalidKeyException e) {
            logger.error("<init>", e);
        }
    }

    public static Crypto getInstance() {
        if (instance == null) {
            instance = new Crypto();
        }
        return instance;
    }

    public byte[] encrypt(byte[] source) {
        try {
            synchronized (encryptCipher) {
                // Encrypt the source bytes, returning encrypted bytes
                logger.debug("Encrypt the source bytes, returning encrypted bytes");
                logger.debug("encrypted bytes: "+encryptCipher.doFinal(source));
                return encryptCipher.doFinal(source);
            }
        } catch (Exception e) {
            logger.error("encrypt", e);
        }

        return null;
    }

    public byte[] decrypt(byte[] source) {
        try {
            synchronized (decryptCipher) {
                // Decrypt the bytes, returning decrypted bytes
                return decryptCipher.doFinal(source);
            }
        } catch (Exception e) {
            logger.error("decrypt", e);
        }

        return null;
    }

    /**
     *
     * @param source
     * @param dest
     * @return true if the operation was successful, false otherwise
     */
    public boolean encryptFile(File source, File dest) {
        boolean returnVal = false;
        logger.debug("Crypto-encryptFile: source:" + source);
        logger.debug("Crypto-encryptFile: destination:" + dest);
        if (!source.isFile()) {
            logger.debug("encryptFile: Source file does not exist - "+ source.getAbsolutePath());
            returnVal = false;
        } else {
            try {
                synchronized (encryptCipher) {
                    logger.debug("encryptFile: Encrypting file "+ source.getAbsolutePath() + " to " + dest.getAbsolutePath());
                    BufferedInputStream in = new BufferedInputStream(new FileInputStream(source));
                    CipherOutputStream out = new CipherOutputStream(new FileOutputStream(dest), encryptCipher);
                    byte[] buf = new byte[4096];
                    int len = 0;
                    while ((len = in.read(buf)) >= 0) {
                        out.write(buf, 0, len);
                    }

                    in.close();
                    out.close();

                    logger.debug("encryptFile: Encrypting file completed "
                            + source.getAbsolutePath() + " to "
                            + dest.getAbsolutePath());
                }

                returnVal = true;
            } catch (IOException e) {
                logger.warn("decryptFile", e);
            }
        }
        
        return returnVal;
    }

    /**
     *
     * @param source
     * @param dest
     * @return true if the operation was successful, false otherwise
     */
    public synchronized boolean decryptFile(File source, File dest) {
        boolean returnVal = false;

        if (!source.isFile()) {
            logger.debug("decryptFile: Source file does not exist - "
                    + source.getAbsolutePath());
            returnVal = false;
        } else {
            try {
                synchronized (decryptCipher) {
                    logger.debug("decryptFile: Decrypting file "
                            + source.getAbsolutePath() + " to "
                            + dest.getAbsolutePath());

                    CipherInputStream in = new CipherInputStream(
                            new FileInputStream(source), decryptCipher);
                    BufferedOutputStream out = new BufferedOutputStream(
                            new FileOutputStream(dest));

                    byte[] buf = new byte[4096];
                    int len = 0;
                    while ((len = in.read(buf)) >= 0) {
                        out.write(buf, 0, len);
                    }

                    in.close();
                    out.close();

                    logger.debug("decryptFile: Decrypting file completed "
                            + source.getAbsolutePath() + " to "
                            + dest.getAbsolutePath());
                }

                returnVal = true;
            } catch (IOException e) {
                logger.warn("decryptFile", e);
            }
        }

        return returnVal;
    }

    private Key getKey() {
        try {
            byte[] bytes = getBytes(KEY_STRING);
            return new SecretKeySpec(bytes, ALGORITHM);
        } catch (Exception e) {
            logger.error("getKey", e);
        }
        return null;
    }

    private byte[] getBytes(String str) {
        ByteArrayOutputStream bos = new ByteArrayOutputStream();
        StringTokenizer st = new StringTokenizer(str, "-", false);
        while (st.hasMoreTokens()) {
            int i = Integer.parseInt(st.nextToken());
            bos.write((byte) i);
        }
        return bos.toByteArray();
    }

}




AES 256 bit

CODE


import org.apache.log4j.Logger;

import javax.crypto.*;
import javax.crypto.spec.SecretKeySpec;
import java.util.StringTokenizer;
import java.security.Key;
import java.security.NoSuchAlgorithmException;
import java.security.InvalidKeyException;
import java.io.*;



public class Crypto {
     private static Logger logger = Logger.getLogger(Crypto.class);

    private Cipher encryptCipher;
    private Cipher decryptCipher;
    private static final String ALGORITHM = "AES";
    private static Crypto instance;

    public Crypto()
    {
        
        try
        {
            // Get our secret key
            SecretKeySpec skey = getSKeySpec();
            encryptCipher = Cipher.getInstance(ALGORITHM);
            logger.debug("Crypto: encryptCipher instance created");
            decryptCipher = Cipher.getInstance(ALGORITHM);
            logger.debug("Crypto: decryptCipher instance created");
            
            // CBC requires an initialization vector
            encryptCipher.init(Cipher.ENCRYPT_MODE, skey);
            logger.debug("Crypto: encryptCipher initialised");
            decryptCipher.init(Cipher.DECRYPT_MODE, skey);
            logger.debug("Crypto: decryptCipher initialised");
        }
        catch (NoSuchAlgorithmException e) {
            logger.error("<init>", e);
        } catch (NoSuchPaddingException e) {
            logger.error("<init>", e);
        } catch (InvalidKeyException e) {
            logger.error("<init>", e);
        }
    }
    

    public static Crypto getInstance() {
        if (instance == null) {
            instance = new Crypto();
        }

        return instance;
    }


    public byte[] encrypt(byte[] source) {
        try {
            synchronized (encryptCipher) {
                // Encrypt the source bytes, returning encrypted bytes
                logger.debug("Encrypt the source bytes, returning encrypted bytes");
                logger.debug("encrypted bytes: "+encryptCipher.doFinal(source));
                return encryptCipher.doFinal(source);
            }
        } catch (Exception e) {
            logger.error("encrypt", e);
        }

        return null;
    }

    public byte[] decrypt(byte[] source) {
        try {
            synchronized (decryptCipher) {
                // Decrypt the bytes, returning decrypted bytes
                return decryptCipher.doFinal(source);
            }
        } catch (Exception e) {
            logger.error("decrypt", e);
        }

        return null;
    }


    // Buffer used to transport the bytes from one stream to another
//    byte[] buf = new byte[1024];
    
    public boolean encryptFile(File source, File dest)
    {
        boolean returnVal = false;
        if (!source.isFile()) {
            logger.debug("encryptFile: Source file does not exist - "+ source.getAbsolutePath());
            returnVal = false;
        } else {
            try
            {
                synchronized (encryptCipher) {
                    logger.debug("encryptFile: Encrypting file "+ source.getAbsolutePath() + " to " + dest.getAbsolutePath());
                    BufferedInputStream in = new BufferedInputStream(new FileInputStream(source));
                    CipherOutputStream out = new CipherOutputStream(new FileOutputStream(dest), encryptCipher);
                    byte[] buf = new byte[4096];
                    // Read in the cleartext bytes and write to out to encrypt
                    int len = 0;
                    while ((len = in.read(buf)) >= 0) {
                        out.write(buf, 0, len);
                    }

                    in.close();
                    out.close();

                    logger.debug("encryptFile: Encrypting file completed "
                            + source.getAbsolutePath() + " to "
                            + dest.getAbsolutePath());
                }

                returnVal = true;
            } catch (IOException e) {
                logger.warn("decryptFile", e);
            }
        }
        
        return returnVal;
    }
                
    
    public boolean decryptFile(File source, File dest)
    {
        boolean returnVal = false;

        if (!source.isFile()) {
            logger.debug("decryptFile: Source file does not exist - "
                    + source.getAbsolutePath());
            returnVal = false;
        } else {
            try
            {
                synchronized (decryptCipher) {
                logger.debug("decryptFile: Decrypting file "+ source.getAbsolutePath() + " to "+ dest.getAbsolutePath());
                CipherInputStream in = new CipherInputStream(new FileInputStream(source), decryptCipher);
                BufferedOutputStream out = new BufferedOutputStream(new FileOutputStream(dest));
                byte[] buf = new byte[4096];
                int len = 0;
                while ((len = in.read(buf)) >= 0) {
                    out.write(buf, 0, len);
                }
                in.close();
                out.close();
                logger.debug("decryptFile: Decrypting file completed "+ source.getAbsolutePath() + " to "+ dest.getAbsolutePath());
                }
                returnVal = true;
            } catch (IOException e) {
                logger.warn("decryptFile", e);
            }
        }

        return returnVal;
    }

    

    private SecretKeySpec getSKeySpec() {
         byte[] bytes = new byte[16];
        try {
            KeyGenerator kgen = KeyGenerator.getInstance("AES");
           kgen.init(256);
           SecretKey skey = kgen.generateKey();
           bytes = skey.getEncoded();
           SecretKeySpec skeySpec = new SecretKeySpec(bytes,ALGORITHM);
            return skeySpec;
        } catch (Exception e) {
            logger.error("getKey", e);
        }
        return null;
    }
}




I have downloaded the unlimited JCE files for the same.


User is offlineProfile CardPM
+Quote Post


cfoley
RE: AES Implementation
25 Nov, 2008 - 07:48 AM
Post #2

D.I.C Addict
****

Joined: 11 Dec, 2007
Posts: 502



Thanked: 43 times
My Contributions
I don't know what AES or DES are but I would go with an automated test. Write a few methods that provide different inputs, write code to check you get the expected output and Bob's your uncle. JUint is a great framework for that kind of thing.
User is online!Profile CardPM
+Quote Post

jyo06
RE: AES Implementation
25 Nov, 2008 - 08:26 AM
Post #3

New D.I.C Head
*

Joined: 25 Nov, 2008
Posts: 6

QUOTE(cfoley @ 25 Nov, 2008 - 07:48 AM) *

I don't know what AES or DES are but I would go with an automated test. Write a few methods that provide different inputs, write code to check you get the expected output and Bob's your uncle. JUint is a great framework for that kind of thing.



I dont know - How to verify the file is successfully encrypted ??

User is offlineProfile CardPM
+Quote Post

cfoley
RE: AES Implementation
25 Nov, 2008 - 09:00 AM
Post #4

D.I.C Addict
****

Joined: 11 Dec, 2007
Posts: 502



Thanked: 43 times
My Contributions
One way would be to get a handful of files, encrypt them with someone else's software (that you trust) and then check the files are the same. Another way is to encrypt some small files by hand (assuming that's not too impractical) and see if your program produces the same. If there are special cases in the algorithm, make sure you test them too. You can use a code coverage tool to make sure the files you select at least reach every area of your code.

Another quick and dirty test is to encrypt a file then decrypt it and see if you get the original back.

Of course, none of these really ensure your implementation is correct, but neither does getting some guy on an Internet forum to inspect your code. All these methods just give you more confidence in your code.
User is online!Profile CardPM
+Quote Post

jyo06
RE: AES Implementation
25 Nov, 2008 - 09:23 AM
Post #5

New D.I.C Head
*

Joined: 25 Nov, 2008
Posts: 6

QUOTE(cfoley @ 25 Nov, 2008 - 09:00 AM) *

One way would be to get a handful of files, encrypt them with someone else's software (that you trust) and then check the files are the same. Another way is to encrypt some small files by hand (assuming that's not too impractical) and see if your program produces the same. If there are special cases in the algorithm, make sure you test them too. You can use a code coverage tool to make sure the files you select at least reach every area of your code.

Another quick and dirty test is to encrypt a file then decrypt it and see if you get the original back.

Of course, none of these really ensure your implementation is correct, but neither does getting some guy on an Internet forum to inspect your code. All these methods just give you more confidence in your code.



I have already tried all these methods and looks like the encryption/decryption of the files is not done correctly.

So, I need to know what and where the code is wrong?


User is offlineProfile CardPM
+Quote Post

Fast ReplyReply to this topicStart new topic

Time is now: 7/4/09 05:48PM

Live Java Help!

Be Social

Dream.In.Code RSS Feed Dream.In.Code LinkedIn Group Follow Us On Twitter Fan Us On Facebook

Java Tutorials

Reference Sheets

Java Snippets

DIC Chatroom

Bye Bye Ads

Monthly Drawing

Thumb Drive

Top Contributors

Top 10 Kudos This Month