Main Page | Class Hierarchy | Alphabetical List | Class List | File List | Class Members

JCOSecretKeyAES.java

00001 package edu.virtualschool.jco;
00002 
00003 import java.security.SecureRandom;
00004 
00005 import org.bouncycastle.crypto.StreamBlockCipher;
00006 import org.bouncycastle.crypto.StreamCipher;
00007 import org.bouncycastle.crypto.engines.AESLightEngine;
00008 import org.bouncycastle.crypto.modes.CFBBlockCipher;
00009 import org.bouncycastle.crypto.params.KeyParameter;
00010 
00011 import edu.virtualschool.jwaa.RuntimeFault;
00012 
00021 public class JCOSecretKeyAES extends JCOSymmetricKey
00022 {
00023   final static int DEFAULT_KEY_LENGTH = 32;
00024 
00031   public JCOSecretKeyAES(int length)
00032   {
00033     this(createRandomBytes(length));
00034   }
00039   public JCOSecretKeyAES()
00040   {
00041     this(createRandomBytes(DEFAULT_KEY_LENGTH));
00042   }
00043   private static byte[] createRandomBytes(int length)
00044   {
00045     byte[] bytes = new byte[length];
00046     SecureRandom random = new SecureRandom();
00047     random.nextBytes(bytes);
00048     return bytes;
00049   }
00055   public JCOSecretKeyAES(String string)
00056   {
00057     this(JCOBase64.decode(string));
00058   }
00064   public JCOSecretKeyAES(byte[] bytes)
00065   {
00066     super(new KeyParameter(bytes));
00067     int length = bytes.length;
00068     if (length != 16 && length != 24 && length != 32)
00069       throw new RuntimeFault("key length not 16 or 24 or 32 bytes");
00070   }
00080   public byte[] encryptBytes(byte[] cleartext)
00081   {
00082     AESLightEngine blockCipher = new AESLightEngine();
00083     CFBBlockCipher cfbCipher = new CFBBlockCipher(blockCipher, 8);
00084     StreamCipher streamCipher = new StreamBlockCipher(cfbCipher);
00085     SecureRandom random = new SecureRandom();
00086 
00087     int blockSize = blockCipher.getBlockSize();
00088     byte[] iv = new byte[blockSize];
00089     random.nextBytes(iv);
00090 
00091     int length = cleartext.length + blockSize;
00092     byte[] plaintext = new byte[length];
00093     System.arraycopy(iv, 0, plaintext, 0, iv.length);
00094     System.arraycopy(cleartext, 0, plaintext, iv.length, cleartext.length);
00095 
00096     byte[] ciphertext = new byte[plaintext.length];
00097     streamCipher.init(true, key);
00098     streamCipher.processBytes(plaintext, 0, plaintext.length, ciphertext, 0);
00099     return ciphertext;
00100   }
00104   public byte[] decryptBytes(byte[] ciphertext) 
00105   {
00106     AESLightEngine blockCipher = new AESLightEngine();
00107     CFBBlockCipher cfbCipher = new CFBBlockCipher(blockCipher, 8);
00108     StreamCipher streamCipher = new StreamBlockCipher(cfbCipher);
00109 
00110     byte[] plaintext = new byte[ciphertext.length];
00111     streamCipher.init(false, key);
00112     streamCipher.processBytes(ciphertext, 0, ciphertext.length, plaintext, 0);
00113     
00114     int ivlength = blockCipher.getBlockSize();
00115     int messageLength = plaintext.length - ivlength;
00116     byte[] cleartext = new byte[messageLength];
00117     System.arraycopy(plaintext, ivlength, cleartext, 0, messageLength);
00118     return cleartext;
00119   }
00123   public final String getAlgorithm()
00124   {
00125     return "AES"; 
00126   }
00130   public final String getFormat()
00131   {
00132     return "RAW";
00133   }
00139   public final byte[] getEncoded()
00140   {
00141     return key.getKey();
00142   }
00143 }