class CloudComm {
String baseurl;
- Cipher encryptcipher;
- Cipher decryptcipher;
+ Cipher encryptCipher;
+ Cipher decryptCipher;
Mac mac;
- byte[] salt;
- SecretKeySpec key;
+ String password;
+ SecureRandom random;
static final int SALT_SIZE = 8;
+ static final int IV_SIZE = 16;
/**
* Empty Constructor needed for child class.
* Constructor for actual use. Takes in the url and password.
*/
- CloudComm(String _baseurl, String password) {
+ CloudComm(String _baseurl, String _password) {
this.baseurl=_baseurl;
- initCloud(password);
+ this.password = _password;
+ this.random = new SecureRandom();
}
/**
* Generates Key from password.
*/
- private void initKey(String password) {
+ private SecretKeySpec initKey(byte[] salt) {
try {
- salt=new byte[SALT_SIZE];
PBEKeySpec keyspec = new PBEKeySpec(password.toCharArray(), salt, 65536, 128);
SecretKey tmpkey = SecretKeyFactory.getInstance("PBKDF2WithHmacSHA256").generateSecret(keyspec);
- this.key = new SecretKeySpec(tmpkey.getEncoded(), "AES");
+ return new SecretKeySpec(tmpkey.getEncoded(), "AES");
} catch (Exception e) {
e.printStackTrace();
throw new Error("Failed generating key.");
* Inits the HMAC generator.
*/
- private void initCloud(String password) {
+ private byte[] initCrypt(byte[] salt) {
try {
- initKey(password);
+ SecretKeySpec key=initKey(salt);
mac = Mac.getInstance("HmacSHA256");
mac.init(key);
+ encryptCipher =Cipher.getInstance("AES/CBC/PKCS5Padding");
+ encryptCipher.init(Cipher.ENCRYPT_MODE, key);
+ return encryptCipher.getIV();
+ } catch (Exception e) {
+ e.printStackTrace();
+ throw new Error("Failed To Initialize Ciphers");
+ }
+ }
+
+ private void initDeCrypt(byte[] salt, byte[] iv) {
+ try {
+ SecretKeySpec key=initKey(salt);
+ mac = Mac.getInstance("HmacSHA256");
+ mac.init(key);
+ Cipher decryptCipher =Cipher.getInstance("AES/CBC/PKCS5Padding");
+ decryptCipher.init(Cipher.DECRYPT_MODE, key, new IvParameterSpec(iv));
} catch (Exception e) {
e.printStackTrace();
throw new Error("Failed To Initialize Ciphers");
public Slot[] putSlot(Slot slot, int max) {
try {
long sequencenumber=slot.getSequenceNumber();
+ byte[] salt=new byte[SALT_SIZE];
+ random.nextBytes(salt);
+ byte[] iv=initCrypt(salt);
+
byte[] bytes=slot.encode(mac);
-
URL url=buildRequest(true, sequencenumber, max);
URLConnection con=url.openConnection();
HttpURLConnection http = (HttpURLConnection) con;
http.setFixedLengthStreamingMode(bytes.length);
http.setDoOutput(true);
http.connect();
+
OutputStream os=http.getOutputStream();
+ os.write(salt);
+ os.write(iv);
+ bytes = encryptCipher.doFinal(bytes);
os.write(bytes);
InputStream is=http.getInputStream();
}
}
- /*
- Cipher encryptCipher =
- Cipher.getInstance("AES/CBC/PKCS5Padding");
- encryptCipher.init(Cipher.ENCRYPT_MODE, secret);
- Cipher decryptCipher =
- Cipher.getInstance("AES/CBC/PKCS5Padding");
- decryptCipher.init(Cipher.DECRYPT_MODE, secret);
- */
-
/**
* Request the server to send all slots with the given
* sequencenumber or newer.
InputStream is=http.getInputStream();
DataInputStream dis=new DataInputStream(is);
+
byte[] resptype=new byte[7];
dis.readFully(resptype);
if (!Arrays.equals(resptype, "getslot".getBytes()))
* server response. Shared by both putSlot and getSlots.
*/
- private Slot[] processSlots(DataInputStream dis) throws IOException {
+ private Slot[] processSlots(DataInputStream dis) throws Exception {
int numberofslots=dis.readInt();
int[] sizesofslots=new int[numberofslots];
Slot[] slots=new Slot[numberofslots];
sizesofslots[i]=dis.readInt();
for(int i=0; i<numberofslots; i++) {
+ byte[] salt=new byte[SALT_SIZE];
+ byte[] iv=new byte[IV_SIZE];
+ dis.readFully(salt);
+ dis.readFully(iv);
+ initDeCrypt(salt, iv);
+
byte[] data=new byte[sizesofslots[i]];
dis.readFully(data);
+
+ data = decryptCipher.doFinal(data);
+
slots[i]=Slot.decode(data, mac);
}
dis.close();