Sunday, September 22, 2013

Amazon AWS Useful Links

The following are useful links while working with Amazon AWS services (not in any particular order):
  • http://awsnow.info
    • A summary of Amazon Services, Costs, Limitations
  • http://cloudping.info
    • Used to estimate the latency from your browser to each AWS region
  • Amazon AWS direct links
    • http://aws.amazon.com/architecture/
    • http://aws.amazon.com/whitepapers/
    • http://aws.amazon.com/solutions/case-studies/
    • http://aws.amazon.com/training/self-paced-labs/
    • https://aws.amazon.com/marketplace
    • http://aws.amazon.com/cloudformation/aws-cloudformation-templates/
    • Amazon AWS Calculator  (google: aws simple monthly calculator)
      • http://calculator.s3.amazonaws.com/calc5.html
  • Presentation: AWS Regions and Availability Zones
    • http://bit.ly/aws-arch-prezi
  • Miscellaneous Google searches
    • spot instance strategies
      • https://www.youtube.com/watch?v=WD9N73F3Fao
    • cloud formation templates
    • aws case studies
  • Netflix Ice Project
    • Ice communicates with AWS Programmatic Billing Access and maintains knowledge of the following key AWS entity categories: Accounts, Regions, Services (e.g. EC2, S3, EBS), Usage types (e.g. EC2 - m1.xlarge), Cost and Usage Categories.
    •  https://github.com/Netflix/ice

Sunday, September 8, 2013

Symmetric key encryption in Java using AES

Per Wikipedia, symmetric key encryption is defined as:  Symmetric-key algorithms are a class of algorithms for cryptography that use the same cryptographic keys for both encryption of plaintext and decryption of ciphertext.

As with most things, everything you need to know about AES in Java can be found on Google, but scattered across a number of partial code snippets.  Below is a my attempt to consolidate that information into a single example application (JDK7) which takes a sentence and runs it back and forth through the encryption process.  In reality, you would be best served by not using "password" as a password, avoiding sequential byte sequences as your keys and/or initialization vectors, and removing passwords from your code. :)

   
 package chris;  
   
 import java.io.FileInputStream;  
 import java.security.Key;  
 import java.security.KeyStore;  
 import javax.crypto.Cipher;  
 import javax.crypto.spec.IvParameterSpec;  
 import javax.crypto.spec.SecretKeySpec;  
   
 /**  
  * JAVA AES EXAMPLE APPLICATION  
  *   
  * java cipher documentation:  
  * http://docs.oracle.com/javase/7/docs/technotes/guides/security/SunProviders.html#SunJSSEProvider  
  * http://docs.oracle.com/javase/7/docs/technotes/guides/security/StandardNames.html#impl  
  *   
  * @author Chris  
  */  
 public class Application  
 {  
      public void aes(boolean useHardcodedKey) throws Exception  
      {  
           System.out.println("---- AES EXAMPLE ----");  
   
           System.out.println("original string: " + CLEARTEXT);  
           System.out.println("original length: " + CLEARTEXT.length());  
   
           // SELECT ALGORITHM  
             
           String algorithm = "AES/CBC/PKCS5Padding";  
                        // or "AES/CBC/ISO10126PADDING";  
             
           SecretKeySpec secretKey = null;  
             
           if(useHardcodedKey)  
           {  
                secretKey = new SecretKeySpec(RAW_KEY, "AES");  
           }  
           else  
           {  
                FileInputStream in = new FileInputStream(AES_KEYSTORE);  
                KeyStore keystore = KeyStore.getInstance("JCEKS");  
                keystore.load(in, PASSWORD);  
                Key key = keystore.getKey("mykey", PASSWORD);  
                secretKey = new SecretKeySpec(key.getEncoded(), "AES");  
           }  
             
           // INITIALIZATION VECTOR  
          
           byte[] ivBytes = new byte[]  
                     {0x00, 0x01, 0x02, 0x03,0x04, 0x05, 0x06, 0x07,   
                      0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F};  
          
           IvParameterSpec ivSpec = new IvParameterSpec(ivBytes);  
   
           // ENCRYPT  
          
           Cipher cipherENCRYPT = Cipher.getInstance(algorithm);  
           cipherENCRYPT.init(Cipher.ENCRYPT_MODE, secretKey, ivSpec);  
           byte[] crypted = cipherENCRYPT.doFinal(CLEARTEXT.getBytes());  
   
           // DECRYPT  
          
           Cipher cipherDECRYPT = Cipher.getInstance(algorithm);  
           cipherDECRYPT.init(Cipher.DECRYPT_MODE, secretKey, ivSpec);  
           byte[] decrypted = cipherDECRYPT.doFinal(crypted);  
          
           // VERIFY  
          
           String compare = new String(decrypted, "UTF8");  
           System.out.println("decrypted string: " + compare);  
           System.out.println("decrypted length: " + compare.length());  
      }  
        
      public static void main(String[] args)  
      {  
           Application app = new Application();  
             
           try  
           {  
                app.aes(true);  
           }  
           catch(Exception e)  
           {  
                e.printStackTrace();  
           }  
      }  
        
      private static final String CLEARTEXT = "Here is a proprietary sentence to protect.";  
        
      // HARD-CODED AES SECRET KEY  
        
      private static final byte[] RAW_KEY = new byte[]  
                {0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,  
                 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F};  
   
      // KEYTOOL commands for generating an AES keystore  
      //  
      // keytool -genseckey -alias mykey -keyalg AES -keysize 128   
      //     -storepass password -storetype JCEKS -keystore aes.jks  
      // keytool -list -v -keystore keystore.jks -storetype JCEKS  
   
      private static final String AES_KEYSTORE = "c:\\temp\\aes.jks";  
      private static final char[] PASSWORD = "password".toCharArray();  
 }  
   

Thanks to codeformatter for providing the easy-to-use code formatting tool for use with blogger.