Saturday, October 10, 2015

First Flexbox Taste

The main feature of my CAMP project for monitoring performance of charging system, I should show multiple charts of different data sources and statistics in a a page view-port (it supposed to be used in NOC center on TV). So I decided to  try flexbox to learn something new and use new technology in my project. Dashboards can be defined to have different rows and columns, but my default dashboard is 3x3, so don't want to waste time more, it is the final

See the Pen epRoQw by Omid Mehdizadeh (@omidmt) on CodePen.

The first level of flex(1 column of 3 rows) is applied by second-content class and next level 3 columns inside each row is applied by frow class.

Challenges:

  • Heights as visible part, not more:
    • It is fixed by height: 97vh to body and max-height: 100% and min-height: 100% to main content div.

  • IE support of flex-basis:
    • It is solved by browser specific flex attribute as -ms-flex: 1 1 30vh and -ms-flex: 1 1 30%

Expiring AES Encrypted Message

As told in previous post I implemented some kind of PGP for encrypting sensitive information like login username and password. So first use openssl friendly AES to encode login information, then encrypt AES random key and salt with RSA public key, in page side, then reverse it on server. So they can ensure the information cannot be decrypted easily by man in middle (I know using https may help a lot for such things, but I liked to add my security layer there to have full control on what happened).

But another challenge appeared that was what happen if a man in middle get the ciphered information including the encrypted message and encrypted key and use them to submit, server validate and it works, while user hasn't changed its password. Another thing that got on my nerve was the hard-coded string of openssl on AES message (Salted__). So combination of these two led me to replace the fixed string by the timestamp.

Now I have the the time AES key is generated and I can compare it with the server time and if it pass a threshold, assume message as expired and leave it. It is still not a certain way to prevent man in middle completely, but with a good threshold can mitigate the risk. I chose 3610 second, 1 hour because of day light saving and 10 seconds for network and computing latency.

So the timestamp is added as part of the salt and 'Salted__' prefix is replaced by that time in encoded format. The format of message will be as:

8 bytes encoded timestamp + 8 bytes random salt + encrypted message

In this case even if the message prefix time is changed to show not expiry, the decryptor can detect it and not decrypt it, since that timestamp is used as part of encryption salt and make key faulty. That's my PGP implementation that I called OPGP or Omid PGP.

Cons:
As mention it depends on client system time, so if it is wrong, it never can get through, or I put 1 hour in my threshold to support daylight saving mismatch between client and server that increase the risk of hijacking information. For this one I'm going to test existence of a time variable that supposed to be set by server on page and compare with local time, then use up to dater one.

Grails-JavaScript Encrypted Communication - Part II

In previous post told about setting up grails environment to use bouncycastle lib. Now move to the page side and javascript. After searching around for having a comprehensive, well-documented and simple to use js lib for RSA and AES, I found pidCrypt interesting (because of the live demo page and simple instruction to use and mainly PEM support, that after going to implement, I found out that is not supported, but I copied the following function from demo page to use it).

function certParser(cert){
    var lines = cert.split('\n');
    var read = false;
    var b64 = false;
    var end = false;
    var flag = '';
    var retObj = {};
    retObj.info = '';
    retObj.salt = '';
    retObj.iv;
    retObj.b64 = '';
    retObj.aes = false;
    retObj.mode = '';
    retObj.bits = 0;
    for(var i=0; i< lines.length; i++){
        flag = lines[i].substr(0,9);
        if(i==1 && flag != 'Proc-Type' && flag.indexOf('M') == 0)//unencrypted cert?
            b64 = true;
        switch(flag){
            case '-----BEGI':
                read = true;
                break;
            case 'Proc-Type':
                if(read)
                    retObj.info = lines[i];
                break;
            case 'DEK-Info:':
                if(read){
                    var tmp = lines[i].split(',');
                    var dek = tmp[0].split(': ');
                    var aes = dek[1].split('-');
                    retObj.aes = (aes[0] == 'AES')?true:false;
                    retObj.mode = aes[2];
                    retObj.bits = parseInt(aes[1]);
                    retObj.salt = tmp[1].substr(0,16);
                    retObj.iv = tmp[1];
                }
                break;
            case '':
                if(read)
                    b64 = true;
                break;
            case '-----END ':
                if(read){
                    b64 = false;
                    read = false;
                }
                break;
            default:
                if(read && b64)
                    retObj.b64 += pidCryptUtil.stripLineFeeds(lines[i]);
        }
    }
    return retObj;
}

On server side, when I tried to decrypt the message I found 2 level bas64 encoding on the message. So first decode as base64 the hash and pass it to doFinal and again decode result as base 64 to have byte [] of the message, then convert to string.

Cipher decryptRSACipher = Cipher.getInstance("RSA/ECB/PKCS1Padding", "BC")
decryptRSACipher.init(Cipher.DECRYPT_MODE, privateKey)
new String(decryptRSACipher.doFinal(hash.decodeBase64()).decodeBase64(), StandardCharsets.UTF_8)

It supposed to be good thing for form submission from javascript side.

The next challenge was decrypting the actual data that encrypted by AES, but the decrypted key in previous by RSA didn't work, so after some research on source and net, another door of knowledge is opened to my eyes. As you may know, it is recommended to use a salt as part of AES key (password), that is fine, but in openssl implementation (that pidCrypt AES follow), the salt is send as part of prefix to the encrypted message (byte 8 to 16), and interesting thing is first 8 bytes are assigned for a "Salted__" string, yes a fixed string. So the message that supposed to be decrypted should be extracted according to the following format.

"Salted__" + 8 Bytes Random Salt + EncryptedMessage

I did some changes to this format to support one time password or expiring the key that will be explained in next post.

This link may describe openssl AES format better than me.

Sunday, October 4, 2015

Grails-JavaScript Encrypted Communication - Part I

For adding new feature to my framework RIRA I should have encrypted communication between client (page) and server(controller) for sensitive information and actions like username and password on login or setting new password. So the basic plan was having RSA (private/public key) encryption of form data in page by javascript and decrypt and use them in controller side.

On testing, troubleshooting and studying best practices for this purpose I found that RSA supposed to be used for encrypting short length data, something like a password or key and not the whole form data. So the best practice was encrypting data by AES with a random key, then encrypt that random key with RSA public, and do vice versa on server side.

For the server side I chose the bouncycastle java lib as provider since it is supporting PEM key reading (parsing), because I want to make it easy for the admin of the application to generate and change the key simply, by something like openssl command line in this case. Here is the method to read PEM file:

static KeyPair getKeyPair(String pk, char [] password) {
 PEMParser pemParser = new PEMParser(new CharArrayReader(pk.toCharArray()))
 Object object = pemParser.readObject()

 PEMDecryptorProvider decProv = new JcePEMDecryptorProviderBuilder().build(password)
 JcaPEMKeyConverter converter = new JcaPEMKeyConverter().setProvider("BC")

 KeyPair kp
 if (object instanceof PEMEncryptedKeyPair) {
  kp = converter.getKeyPair(((PEMEncryptedKeyPair) object).decryptKeyPair(decProv))
 } else {
  kp = converter.getKeyPair((org.bouncycastle.openssl.PEMKeyPair) object)
 }
 kp
}

For security the password must be passed and processed as char [] instead of String object, since String is seen as one object and may be accessed before garbage collection.

The first challenge appear here that PEMParser (Thhe deprecated and removed class was PEMReader) class that is used in most of examples was not resolvable and accessible that was because of existence of old version in global grails lib through some dependency to garils-doc and itext (The dependencies can be checked by grails dependency-report command). So first solution was to exclude the bouncycastle lib in BuildConfig.groovy of my plugin by something like the following code:

dependencies {
 compile("com.lowagie:itext:2.0.8") {
  excludes "bouncycastle:bcprov-jdk14:138", "org.bouncycastle:bcprov-jdk14:1.38"
 }
}

It was OK for compiling source code in plugin project but same error of not founding some classes repeated on application project that use the plugin. So I added same to build config of application and it resolved. So now I can encrypt and decrypt strings by RSA keys in grails side.

I added syntax highlighter to blog template for this post.