Tôi đang cố gắng mã hóa một số văn bản bằng thuật toán AES trên cả nền tảng Android và IPhone. Vấn đề của tôi là, thậm chí sử dụng cùng một thuật toán mã hóa/giải mã (AES-128) và các biến cố định tương tự (khóa, IV, chế độ), tôi nhận được kết quả khác nhau trên cả hai nền tảng. Tôi bao gồm các mẫu mã từ cả hai nền tảng, mà tôi đang sử dụng để kiểm tra mã hóa/giải mã. Tôi sẽ đánh giá cao một số trợ giúp trong việc xác định những gì tôi đang làm sai.Mã hóa bằng AES-128 trong Android và IPhone (Kết quả khác nhau)
- chính: “123456789abcdefg”
- IV: “1111111111111111”
- Plain Text: “HelloThere”
- Mode: “AES/CBC/NoPadding”
Mã Android:
public class Crypto {
private final static String HEX = "ABCDEF";
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 < 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 < buf.length; i++) {
appendHex(result, buf[i]);
}
return result.toString();
}
private static void appendHex(StringBuffer sb, byte b) {
sb.append(HEX.charAt((b >> 4) & 0x0f)).append(HEX.charAt(b & 0x0f));
}
}
IPhone (Objective-C) Mã số:
- (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];
}
Một số tài liệu tham khảo của tôi:
- http://code.google.com/p/aes-encryption-samples/wiki/HowToEncryptWithJava
- http://automagical.rationalmind.net/2009/02/12/aes-interoperability-between-net-and-iphone/
- AES interoperability between .Net and iPhone?
Những 'mã hóa() 'phương pháp bạn đang sử dụng? Câu hỏi của bạn là một mớ hỗn độn. Chỉ cung cấp mã cần thiết. – erickson
bạn có thể sử dụng giải pháp này, nó làm việc cho tôi: [nhập liên kết mô tả ở đây] [1] [1]: http://stackoverflow.com/questions/17535918/aes-gets-different-results -in-ios-and-java? answerertab = active # tab-top – salimido
Tại sao bạn cần dữ liệu được mã hóa bằng nhau? Có lẽ bạn sẽ làm cho mã của bạn kém an toàn hơn mà không có lý do. Trong hầu hết các trường hợp sử dụng, chỉ dữ liệu được giải mã phải bằng nhau. Xem crypto.stackexchange.com/q/5094 –