.Net 和 iPhone 之間的 AES 互操作性?
我需要在 iPhone 上加密一個字元串並將其發送到 .Net Web 服務進行解密。我可以在 iPhone 和 .Net 上加密/解密,但來自 iPhone 的加密字元串不能被 .Net 解密。我得到的錯誤是“填充無效,無法刪除。”
.Net 程式碼來自: http ://blog.realcoderscoding.com/index.php/2008/07/dot-net-encryption-simple-aes-wrapper/
iPhone 程式碼使用的範常式式碼來自: http: //nootech.wordpress.com/2009/01/17/symmetric-encryption-with-the-iphone-sdk/
AFAIK 我的關鍵設置是一樣的:
result.BlockSize = 128; // iPhone: kCCBlockSizeAES128 result.KeySize = 128; // kCCBlockSizeAES128 result.Mode = CipherMode.CBC; result.Padding = PaddingMode.PKCS7; // kCCOptionPKCS7Padding我嘗試了不同的生成密文的方法。你好/你好是:
e0PnmbTg/3cT3W+92CDw1Q== 在.Net
yrKe5Z7p7MNqx9+CbBvNqQ== 在 iPhone 上
並且“openssl enc -aes-128-cbc -nosalt -a -in hello.txt -pass pass:hello”生成:QA+Ul+r6Zmr7yHipMcHSbQ==
更新:我已經在這裡發布了這個工作程式碼。
至少,您正在使用不同的初始化向量 (IV)。
- .Net 程式碼使用 IV 的密鑰。
private static AesCryptoServiceProvider GetProvider(byte[] key) { //Set up the encryption objects AesCryptoServiceProvider result = new AesCryptoServiceProvider(); byte[] RealKey = Encryptor.GetKey(key, result); result.Key = RealKey; result.IV = RealKey; return result; }和
private static byte[] GetKey(byte[] suggestedKey, AesCryptoServiceProvider p) { byte[] kRaw = suggestedKey; List kList = new List(); for (int i = 0; i < p.LegalKeySizes[0].MinSize; i += 8 ) { kList.Add(kRaw[i % kRaw.Length]); } byte[] k = kList.ToArray(); return k; }這可能應該是:
kList.Add(kRaw[(i / 8) % kRaw.Length]);。否則長度 % 8 == 0 的鍵會重複使用同一個字母,呵呵!因此,.Net 使用的 IV(和密鑰)是:
hleolhleolhleolh. 這不是 API 的一部分,而是由於您指向的包裝器程式碼(其中有一個嚴重的錯誤……)。
- iPhone 程式碼使用 0 表示 IV。
// Initialization vector; dummy in this case 0's. uint8_t iv[kChosenCipherBlockSize]; memset((void *) iv, 0x0, (size_t) sizeof(iv));
- 預設情況下,openssl 會預先添加一個隨機生成的鹽(這就是輸出更長的原因!)。
openssl 輸出更安全,因為它預先添加了一個隨機初始化向量。看起來base64解碼字元串的前幾個字節是“Salted__”。您還可以要求 openssl 不使用鹽 (-nosalt) 和/或提供 IV (-iv)。
本質上,openssl、.Net 和 iPhone 使用相同的加密,您只需要注意如何使用加密密鑰和初始化向量初始化 API。