【发布时间】:2016-04-20 08:02:56
【问题描述】:
使用CCCrypt()方法加密,然后在C#中解密。但输出与原始纯文本不同。
密钥长度为 256 位,IV 为默认值。
主要代码如下:
// Encrypt
{
// the key is 32 bytes (256 bits).
Byte iv[] = { 0x12, 0x34, 0x56, 0x78, 0x90, 0xAB, 0xCD, 0xEF, 0x12, 0x34, 0x56, 0x78, 0x90, 0xAB, 0xCD, 0xEF };
size_t numBytesEncrypted = 0;
CCCryptorStatus cryptStatus = CCCrypt(kCCEncrypt, // Operation
kCCAlgorithmAES128, // Algorithm
kCCOptionPKCS7Padding, // Option
keyPtr, // key
kCCKeySizeAES256, // key length
iv, /* initialization vector (optional) */
[self bytes], // plain text
dataLength, /* input */
buffer,
bufferSize, /* output */
&numBytesEncrypted); //dataOutMove
if (cryptStatus == kCCSuccess) {
NSData *encryptedData = [NSData dataWithBytesNoCopy:buffer length:numBytesEncrypted];
NSString *encryptedString = [encryptedData base64Encoding];
}
// Decrypted
{
byte[] _key1 = { 0x12, 0x34, 0x56, 0x78, 0x90, 0xAB, 0xCD, 0xEF, 0x12, 0x34, 0x56, 0x78, 0x90, 0xAB, 0xCD, 0xEF };
public static string AESDecrypt(string encryptedString, string key)
{
AesCryptoServiceProvider aes = new AesCryptoServiceProvider();
aes.BlockSize = 128;
aes.KeySize = 256;
aes.IV = _key1;
aes.Key = Encoding.UTF8.GetBytes(key);
aes.Mode = CipherMode.CBC;
aes.Padding = PaddingMode.PKCS7;
// Convert Base64 strings to byte array
byte[] src = System.Convert.FromBase64String(encryptedString);
// decryption
using (ICryptoTransform decrypt = aes.CreateDecryptor())
{
byte[] dest = decrypt.TransformFinalBlock(src, 0, src.Length);
return Encoding.UTF8.GetString(dest);
}
}
}
编辑:
我发现原因是keyPtr。在加密过程中,我会像这样提前处理密钥:
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];
现在,我像这样修改这些代码:
NSData *keyData = [key dataUsingEncoding:NSUTF8StringEncoding];
NSUInteger keyLength = [keyData length];
Byte *keyPtr= (Byte *)malloc(keyLength);
memcpy(keyPtr, [keyData bytes], keyLength);
然后我得到了正确的输出。 虽然问题没有了,但我真的不知道以前的版本有什么问题。
【问题讨论】:
-
C# 中的 _key1 与 OSX 中的 IV 是否相同?
-
是的,IV 是同一个常数。
-
keyPtr 怎么样,在 OSX 中也是一个 UTF8 字符串作为字节数组吗?
-
@nvoigt,我已经编辑了我的问题。
-
@GateLuma 您出错的部分是您将密钥作为字符串处理。密码是字符串,密钥不是,它们是字节数组(或您的环境中的
NSData)。它们可能包含任何字节值,包括零。当涉及到无效编码和不可打印的字符时,将它们作为字符串处理会给您带来麻烦。另一方面,如果您的密钥看起来不像具有随机值的字节,那么您做错了。查找 PBKDF2 或生成真正的随机密钥。
标签: c# macos encryption aes