Raj*_*esh 4 c# encryption cryptography ios
我正在尝试使用目标 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;
}
Run Code Online (Sandbox Code Playgroud)
想知道如何在 C# 中解密,我给块大小为 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;
}
Run Code Online (Sandbox Code Playgroud)
iOS(Common Crypto)显式指定了所有加密参数,C# 代码隐式确定了许多参数。当试图实现互操作性时,这些隐式参数在简化使用的同时是有问题的。
C# 类RijndaelManaged
允许显式指定参数,更改您的代码以使用这些参数,特别是BlockSize
( 128
)、KeySize
( 128
)、Mode
( CipherMode.CBC
) 和Padding
( PaddingMode.PKCS7
)。为默认值mode
和Padding
正常。请参阅RijndaelManaged 文档
AES 和 Rijndael 不一样,特别是 AES 仅使用 128 位(16 字节)的块大小,而 Rijndael 允许多种块大小。因此需要为 Rijndael 指定 128 位的块大小。因此 iv 也是 128 位(16 字节)。两者都支持 128、192 和 256 字节的加密密钥。
使用AESManaged
类可能比使用类更好RijndaelManaged
。请参阅AesManaged 文档
C# 端希望数据是 Base64 编码的,iOS 端不显示该编码操作,请确保在 iOS 端完成。
由于您使用的是 iv,请确保两侧都使用 CBC 模式。在 Common Crypto CBC 模式是默认的,请确保在 C# 端使用 CBC 模式。
确保 C# 端使用 PKCS#7 或 PKCS#5 填充,它们是等效的。看起来 PKCS#7 是 C# 端的默认值,所以这应该没问题。
最好使用与指定大小完全相同的键,而不是依赖默认填充。在 Common Crypto 中,如果提供的密钥很短,则明确指定密钥大小并填充空值。C# 看起来像是通过提供的密钥来确定密钥大小,在这种情况下,密钥是 10 字节,因此解密密钥可能默认为 128 位,并且密钥在内部用空值填充。在 iOS 上,您明确指定了 256 位的密钥大小。这是一个需要修复的不匹配。提供一个在 iOS 端指定的确切大小的密钥。
最后是 iv,C# 代码希望将 iv 附加到加密数据,但 iOS 代码没有提供。解决方案是更改 iOS 代码以在加密代码前添加 iv。将 iv 更改为 16 字节,即 AES 块大小。
最后,如果您需要更多帮助,请在加密调用之前和之后提供测试数据输入、数据输出、iv 和密钥的十六进制转储。
归档时间: |
|
查看次数: |
1601 次 |
最近记录: |