如何使用Rijndael在iOS中加密c#中的解密字符串

我正在尝试使用目标c和C#加密和解密字符串。 两者在本机代码中工作正常,但当我尝试解密c#中的字符串时,在iOS中加密。 我收到一些错误。

这是我在目标c中使用的代码

- (NSData *)AES256EncryptWithKey:(NSString *)key Data: (NSData *) data { char keyPtr[kCCKeySizeAES256+1]; // room for terminator (unused) bzero(keyPtr, sizeof(keyPtr)); // fill with zeroes (for padding) [key getCString:keyPtr maxLength:sizeof(keyPtr) encoding:NSUTF8StringEncoding]; NSUInteger dataLength = [data length]; NSData *iv = [@"abcdefghijklmnopqrstuvwxyz123456" dataUsingEncoding:NSUTF8StringEncoding]; size_t bufferSize = dataLength + kCCBlockSizeAES128; void *buffer = malloc(bufferSize); size_t numBytesEncrypted = 0; CCCryptorStatus cryptStatus = CCCrypt(kCCEncrypt, kCCAlgorithmAES128, kCCOptionPKCS7Padding, keyPtr, kCCKeySizeAES256, [iv bytes] /* initialization vector (optional) */, [data bytes], dataLength, /* input */ buffer, bufferSize, /* output */ &numBytesEncrypted); if (cryptStatus == kCCSuccess) { return [NSData dataWithBytesNoCopy:buffer length:numBytesEncrypted]; } free(buffer); //free the buffer; return nil; } 

在想知道如何在C#中解密时,我给出的blockize是256,ivsize为32并使用了“RijndaelManaged()”。 我没有使用salt和密码。 错误:类似“填充无效且无法删除”。 我试图设置padding也像PKCS7,none,zero但没有任何帮助解密。

任何人都可以帮忙吗?

编辑:我的C#代码在这里

 public string DecryptString(string encrypted) { string result = null; _encoder = new UTF8Encoding(); if (!string.IsNullOrWhiteSpace(encrypted) && (encrypted.Length >= 32)) { var messageBytes = Convert.FromBase64String(encrypted); using (var rm = new RijndaelManaged()) { rm.BlockSize = _blockSize; rm.Key = _encoder.GetBytes("mykey_here"); rm.IV = _encoder.GetBytes("abcdefghijklmnopqrstuvwxyz123456"); ; rm.Padding = PaddingMode.Zeros; var decryptor = rm.CreateDecryptor(rm.Key, messageBytes.Take(_ivSize).ToArray()); result = _encoder.GetString(Transform(messageBytes.Skip(_ivSize).ToArray(), decryptor)); } } return result; } protected byte[] Transform(byte[] buffer, ICryptoTransform transform) { byte[] result; using (var stream = new MemoryStream()) using (var cs = new CryptoStream(stream, transform, CryptoStreamMode.Write)) { cs.Write(buffer, 0, buffer.Length); cs.FlushFinalBlock(); result = stream.ToArray(); } return result; } 

iOS(Common Crypto)明确指定所有加密参数,C#代码隐式确定许多参数。 在尝试实现互操作性时,这些隐式参数在简化使用时会出现问题。

C#类RijndaelManaged允许显式指定参数,更改代码以使用它们,特别是BlockSize128 ), KeySize128 ), ModeCipherMode.CBC )和PaddingPaddingMode.PKCS7 )。 modePadding的默认值都可以。 请参阅RijndaelManaged Documentation

AES和Rijndael不相同,特别是AES仅使用128位(16字节)的块大小,而Rijndael允许多个块大小。 因此,需要为Rijndael指定128位的块大小。 因此,iv也是128位(16字节)。 两者都支持128,192和256字节的加密密钥。

使用AESManaged类可能比RijndaelManaged类更好。 请参阅AesManaged Documentation

C#端希望数据为Base64编码,iOS端不显示编码操作,确保在iOS端完成。

由于您使用的是iv,请确保您在两侧都使用CBC模式。 在Common Crypto中,CBC模式是默认模式,请确保在C#端使用CBC模式。

确保C#端使用PKCS#7或PKCS#5填充,它们是等效的。 似乎PKCS#7是C#端的默认值,所以这应该没问题。

最好使用完全符合指定大小的密钥,而不是依赖于默认填充。 在Common Crypto中,显式指定密钥大小,如果提供的密钥为short,则填充空值。 C#看起来像是通过提供的密钥确定密钥大小,在这种情况下密钥是10个字节,因此解密密钥可能默认为128位,密钥在内部用空值填充。 在iOS上,您明确指定密钥大小为256位。 这是一个需要修复的不匹配。 提供一个在iOS端指定的确切大小的密钥。

最后是iv,C#代码期望iv加在加密数据之前,但iOS代码没有提供。 解决方案是更改iOS代码以将iv添加到加密代码之前。 将iv更改为16字节,即AES块大小。

如果您需要更多帮助,最后在加密调用之前和之后提供测试数据的hex转储,数据输出,iv和密钥。

Interesting Posts