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.
- Key: “123456789abcdefg”
- IV: “1111111111111111”
- Plain Text: “HelloThere”
- Mode: “AES/CBC/NoPadding”
Android 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 > 4) & 0x0f)).append(HEX.charAt(b & 0x0f)); } }
IPhone (Objective-C) 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, &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, &bufused); if (status != kCCSuccess) { free(buf); CCCryptorRelease(cryptor); return nil; } bytesTotal += bufused; status = CCCryptorFinal(cryptor, buf + bufused, bufsize - bufused, &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]; }
Some of my references :