Điều đầu tiên trước tiên. Một số thời gian trước, tôi cần một mã hóa AES đơn giản trong Android để mã hóa mật khẩu và gửi nó như một tham số cho dịch vụ web .net nơi mật khẩu được giải mã.Mã hóa AES trong iOS và Android và giải mã trong C# .NET
Sau đây là mã hóa Android của tôi:
private static String Encrypt(String text, String key)
throws Exception {
Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
byte[] keyBytes= new byte[16];
byte[] b= key.getBytes("UTF-8");
int len= b.length;
if (len > keyBytes.length) len = keyBytes.length;
System.arraycopy(b, 0, keyBytes, 0, len);
SecretKeySpec keySpec = new SecretKeySpec(keyBytes, "AES");
IvParameterSpec ivSpec = new IvParameterSpec(keyBytes);
cipher.init(Cipher.ENCRYPT_MODE,keySpec,ivSpec);
byte[] results = cipher.doFinal(text.getBytes("UTF-8"));
String result = Base64.encodeBytes(results);
return result;
}
Và sau đó tôi đã giải mã nó trong C# với:
public static string Decrypt(string textToDecrypt, string key)
{
System.Text.UTF8Encoding encoding = new System.Text.UTF8Encoding();
RijndaelManaged rijndaelCipher = new RijndaelManaged();
rijndaelCipher.Mode = CipherMode.CBC;
rijndaelCipher.Padding = PaddingMode.PKCS7;
rijndaelCipher.KeySize = 0x80;
rijndaelCipher.BlockSize = 0x80;
string decodedUrl = HttpUtility.UrlDecode(textToDecrypt);
byte[] encryptedData = Convert.FromBase64String(decodedUrl);
byte[] pwdBytes = Encoding.UTF8.GetBytes(key);
byte[] keyBytes = new byte[0x10];
int len = pwdBytes.Length;
if (len > keyBytes.Length)
{
len = keyBytes.Length;
}
Array.Copy(pwdBytes, keyBytes, len);
rijndaelCipher.Key = keyBytes;
rijndaelCipher.IV = keyBytes;
byte[] plainText = rijndaelCipher.CreateDecryptor().TransformFinalBlock(encryptedData, 0, encryptedData.Length);
return encoding.GetString(plainText);
}
này làm việc như một nét duyên dáng, nhưng những vấn đề đến khi tôi đã cố gắng để làm tương tự trong iOS. Tôi ứng dụng phát triển khá mới cho iphone/ipad, vì vậy ofcause Tôi googled nó, và hầu hết các mẫu mã được cung cấp là như sau:
- (NSData *)AESEncryptionWithKey:(NSString *)key {
char keyPtr[kCCKeySizeAES128]; // room for terminator (unused)
bzero(keyPtr, sizeof(keyPtr)); // fill with zeroes (for padding)
// fetch key data
[key getCString:keyPtr maxLength:sizeof(keyPtr) encoding:NSUTF8StringEncoding];
NSUInteger dataLength = [self length];
size_t bufferSize = dataLength + kCCBlockSizeAES128;
void *buffer = malloc(bufferSize);
size_t numBytesEncrypted = 0;
CCCryptorStatus cryptStatus = CCCrypt(kCCEncrypt, kCCAlgorithmAES128, kCCOptionPKCS7Padding,
keyPtr, kCCKeySizeAES128,
NULL /* initialization vector (optional) */,
[self bytes], [self length], /* input */
buffer, bufferSize, /* output */
&numBytesEncrypted);
if (cryptStatus == kCCSuccess) {
//the returned NSData takes ownership of the buffer and will free it on deallocation
return [NSData dataWithBytesNoCopy:buffer length:numBytesEncrypted];
}
free(buffer); //free the buffer;
return nil;
}
Có lẽ tôi là một chút quá lạc quan, khi tôi đã hy vọng cho một chuyển đổi suôn sẻ ở đây, bởi vì khi Android là ném cho tôi một cái gì đó như:
"EgQVKvCLS4VKLoR0xEGexA=="
thì iOS mang lại cho tôi:
"yP42c9gajUra7n0zSEuVJQ=="
Hy vọng đó chỉ là điều tôi quên hoặc một số cài đặt sai?
[CẬP NHẬT] Kết quả hiện được hiển thị sau khi mã hóa base64.
Phiên bản Android là chuỗi base64 được mã hóa URL bằng "YHH + gTxyIxvAx1cPFLcP0IEW2HcVHQVi9X11656CFsk =" '' (60 71 fe 81 3c 72 23 1b c0 c7 57 0f 14 b7 0f d0 81 16 d8 77 15 1d 05 62 f5 7d 75 eb 9e 82 16 c9) '. – Joe
Woops, xin lỗi tôi quên đề cập đến điều đó. Tôi cũng đang mã hóa kết quả từ phiên bản iOS, chỉ trong một phương pháp khác, nhưng kết quả khác nhau trước khi mã hóa. – Morten
Cập nhật câu hỏi để hiển thị kết quả sau khi mã hóa base64. Cùng một mật khẩu và cùng một khóa được sử dụng. – Morten