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 }