gpt4 book ai didi

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

转载 作者:塔克拉玛干 更新时间:2023-11-01 21:42:25 25 4
gpt4 key购买 nike

我正在尝试使用 objective-c 和 C# 来加密和解密字符串。两者在 native 代码中都运行良好,但是当我尝试在 c# 中解密字符串时,在 iOS 中已加密。我收到一些错误。

这是我在 objective-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# 中解密,我给出的 block 大小为 256,ivsize 为 32,并使用了“RijndaelManaged()”。我没有使用盐和密码。错误:类似“填充无效且无法删除”之类的内容。我尝试像 PKCS7 一样设置填充,无,零,但对解密没有任何帮助。

有人能帮忙吗?

编辑:我的 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 允许显式指定参数,更改代码以使用这些参数,特别是 BlockSize (128), KeySize (128)、Mode (CipherMode.CBC) 和Padding (PaddingMode .PKCS7). modePadding 的默认值都可以。参见 RijndaelManaged Documentation

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

使用 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 中, key 大小是明确指定的,如果提供的 key 太短,则会填充空值。 C# 看起来像是通过提供的 key 确定 key 大小,在本例中, key 为 10 个字节,因此解密 key 可能默认为 128 位,并且 key 在内部用空值填充。在 iOS 上,您明确指定了 256 位的 key 大小。这是一个需要修复的不匹配。提供与 iOS 端指定的大小完全相同的 key 。

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

如果您需要更多帮助,请在加密调用前后最后提供测试数据输入、数据输出、iv 和 key 的十六进制转储。

关于c# - 如何使用 Rijndael 在 iOS 中加密 c# 中的解密字符串,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31067324/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com