title: Encryption using AES-128 in Android and IPhone (Different result)
body: <p>I am trying to encrypt some text using the AES algorithm on both the Android and IPhone platforms. My problem is, even using the same encryption/decryption algorithm (AES-128) and same fixed variables (key, IV, mode), I get different result on both platforms. I am including code samples from both platforms, that I am using to test the encryption/decryption. I would appreciate some help in determining what I am doing wrong.</p>
  
  <ul>
  <li>Key: “123456789abcdefg”</li>
  <li>IV: “1111111111111111”</li>
  <li>Plain Text: “HelloThere”</li>
  <li>Mode: “AES/CBC/NoPadding”</li>
  </ul>
  
  <p><strong>Android Code:</strong></p>
  
  <pre><code>public class Crypto {
      private final static String HEX = "0123456789ABCDEF";
  
      public static String encrypt(String seed, String cleartext)
              throws Exception {
          byte[] rawKey = getRawKey(seed.getBytes());
          byte[] result = encrypt(rawKey, cleartext.getBytes());
          return toHex(result);
      }
  
      public static String decrypt(String seed, String encrypted)
              throws Exception {
          byte[] rawKey = getRawKey(seed.getBytes());
          byte[] enc = toByte(encrypted);
          byte[] result = decrypt(rawKey, enc);
          return new String(result);
      }
  
      private static byte[] getRawKey(byte[] seed) throws Exception {
          KeyGenerator kgen = KeyGenerator.getInstance("CBC");
          SecureRandom sr = SecureRandom.getInstance("SHA1PRNG");
          sr.setSeed(seed);
          kgen.init(128, sr); // 192 and 256 bits may not be available
          SecretKey skey = kgen.generateKey();
          byte[] raw = skey.getEncoded();
          return raw;
      }
  
      private static byte[] encrypt(byte[] raw, byte[] clear) throws Exception {
          SecretKeySpec skeySpec = new SecretKeySpec(raw, "AES");
          Cipher cipher = Cipher.getInstance("AES");
          cipher.init(Cipher.ENCRYPT_MODE, skeySpec);
          byte[] encrypted = cipher.doFinal(clear);
          return encrypted;
      }
  
      private static byte[] decrypt(byte[] raw, byte[] encrypted)
              throws Exception {
          SecretKeySpec skeySpec = new SecretKeySpec(raw, "AES");
          Cipher cipher = Cipher.getInstance("AES");
          cipher.init(Cipher.DECRYPT_MODE, skeySpec);
          byte[] decrypted = cipher.doFinal(encrypted);
          return decrypted;
      }
  
      public static String toHex(String txt) {
          return toHex(txt.getBytes());
      }
  
      public static String fromHex(String hex) {
          return new String(toByte(hex));
      }
  
      public static byte[] toByte(String hexString) {
          int len = hexString.length() / 2;
          byte[] result = new byte[len];
          for (int i = 0; i &lt; len; i++)
              result[i] = Integer.valueOf(hexString.substring(2 * i, 2 * i + 2),
                      16).byteValue();
          return result;
      }
  
      public static String toHex(byte[] buf) {
          if (buf == null)
              return "";
  
          StringBuffer result = new StringBuffer(2 * buf.length);
          for (int i = 0; i &lt; buf.length; i++) {
              appendHex(result, buf[i]);
          }
  
          return result.toString();
      }
  
      private static void appendHex(StringBuffer sb, byte b) {
          sb.append(HEX.charAt((b &gt;&gt; 4) &amp; 0x0f)).append(HEX.charAt(b &amp; 0x0f));
      }
  }
  </code></pre>
  
  <p><strong>IPhone (Objective-C) Code:</strong></p>
  
  <pre><code>- (NSData *) transform:(CCOperation) encryptOrDecrypt data:(NSData *) inputData { 
  
      NSData* secretKey = [Cipher md5:cipherKey];
  
      CCCryptorRef cryptor = NULL;
      CCCryptorStatus status = kCCSuccess;
  
      uint8_t iv[kCCBlockSizeAES128];
      memset((void *) iv, 0x0, (size_t) sizeof(iv));
  
      status = CCCryptorCreate(encryptOrDecrypt, kCCAlgorithmAES128, kCCOptionPKCS7Padding,
                           [secretKey bytes], kCCKeySizeAES128, iv, &amp;cryptor);
  
      if (status != kCCSuccess) {
          return nil;
      }
  
      size_t bufsize = CCCryptorGetOutputLength(cryptor, (size_t)[inputData length], true);
  
      void * buf = malloc(bufsize * sizeof(uint8_t));
      memset(buf, 0x0, bufsize);
  
      size_t bufused = 0;
      size_t bytesTotal = 0;
  
      status = CCCryptorUpdate(cryptor, [inputData bytes], (size_t)[inputData length],
                           buf, bufsize, &amp;bufused);
  
      if (status != kCCSuccess) {
          free(buf);
          CCCryptorRelease(cryptor);
          return nil;
      }
  
      bytesTotal += bufused;
  
      status = CCCryptorFinal(cryptor, buf + bufused, bufsize - bufused, &amp;bufused);
  
      if (status != kCCSuccess) {
          free(buf);
          CCCryptorRelease(cryptor);
          return nil;
      }
  
      bytesTotal += bufused;
  
      CCCryptorRelease(cryptor);
  
      return [NSData dataWithBytesNoCopy:buf length:bytesTotal];
  }
  
  + (NSData *) md5:(NSString *) stringToHash {
  
      const char *src = [stringToHash UTF8String];
  
      unsigned char result[CC_MD5_DIGEST_LENGTH];
  
      CC_MD5(src, strlen(src), result);
  
      return [NSData dataWithBytes:result length:CC_MD5_DIGEST_LENGTH];
  }
  </code></pre>
  
  <p>Some of my references :</p>
  
  <ul>
  <li><a href="http://code.google.com/p/aes-encryption-samples/wiki/HowToEncryptWithJava" rel="noreferrer">http://code.google.com/p/aes-encryption-samples/wiki/HowToEncryptWithJava</a></li>
  <li><a href="http://automagical.rationalmind.net/2009/02/12/aes-interoperability-between-net-and-iphone/" rel="noreferrer">http://automagical.rationalmind.net/2009/02/12/aes-interoperability-between-net-and-iphone/</a></li>
  <li><a href="https://stackoverflow.com/questions/538435/aes-interoperability-between-net-and-iphone/">AES interoperability between .Net and iPhone?</a></li>
  </ul>