Articles

On securing the persistent data on ‘cloud’

In Architecture, Product Development on April 15, 2010 by petrem66 Tagged:

The application’s foundation has to be build so that it will stand future heavy requirements like security and privacy compliance. One of the most important aspects that need to be well think of is information access outside the running code.
In any cloud based deployment, one can use persistent file system to store block of data like capabilities such as Cloud Files in Rackspace, EC2 in Amazon WS etc. This is especially true when such data must be shared among many server instances that form your application. Three parts are interesting to mention with regards to such block of data:
– encryption
– compaction
– integrity check

Encryption

A very detailed discussion about this topic can be found at Core Security Patterns. Suffice to say is that one can choose from various encryption algorithms at hand for Java developers for that. Since the block of data is not shared outside the application, one should go for a common encryption key. If that is hard-code somewhere in a reusable piece of code, it is safe to assume that it is highly unlikely that a malicious third party would be able to get it from there. Cracking the key of strong encryption algorithms like AES on 192 bit is quite a challenge, but even so one can imaging a strategy of changing such a key on a regular bases (like weekly or monthly) accompanied with a data migration task (re-encryption that is)

Compaction

In order to save on storage space and network bandwidth, one should consider archiving the blocks of data. Java runtime comes with a neat wrapper package of the GZiP compression called java.util.zip. The snippet of code below will do the job of achiving/expanding of your block of data:

public byte[] expand(byte[] buffer) throws Exception {
ByteArrayOutputStream os = null;
try {
os = new ByteArrayOutputStream();
ByteArrayInputStream is = new ByteArrayInputStream(buffer);
GZIPInputStream zin = new GZIPInputStream(is);
byte[] ret = new byte[4098];
for(int i=0; (i = zin.read(ret))>0;)
os.write(ret, 0, i);
return os.toByteArray();
}
finally {
if (os != null)
try {
os.close();
}
catch(Exception e){}
}
}
public byte[] archive(byte[] buffer) throws Exception {
ByteArrayOutputStream os = null;
try {
os = new ByteArrayOutputStream();
GZIPOutputStream zout = new GZIPOutputStream(os);
zout.write(buffer);
zout.finish();
zout.flush();
return os.toByteArray();
}
finally {
if (os != null)
try {
os.close();
}
catch(Exception e){}
}
}

Integrity check

From a consuming application prospective it is important to be assured that the block of data is not tampered. Usually, the producing application accompanies it with an MD5 based sum which it can pass along with the block of data descriptor to the consumer. The md5sum can be obtained with Java API using the java.security.MessageDigester (see the code snippet below)

public boolean match(String md5sum, byte[] buffer) throws Exception {
String s = getMD5sum(buffer);
return s.endsWith(md5sum);
}
public String getMD5sum(byte[] buffer) throws Exception {
byte[] sum = MessageDigest.getInstance(“MD5”).digest(buffer);
StringBuffer sbuf = new StringBuffer();
for (int i = 0; i < sum.length; i++) {
int c = (int) sum[i];
if (c < 0)
c = (Math.abs(c) – 1) ^ 255;
sbuf.append(Integer.toHexString(c >>> 4));
sbuf.append(Integer.toHexString(c & 15));
}
return sbuf.toString();
}

The string that results from calling getMD5sum can be stored along with the block name and passed to the consuming application as such.

Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: