我正在尝试解密AES加密数据(在.NET中加密),但我的解密结果字符串似乎不可读,我没有收到任何错误。
使用以下方法加密数据
我有InItVector,PassCode,salt和NumberOfPassword(3)迭代。
这是我的代码:
//I am retrieving my encrypted data from sqlite database:
NSString *strEncryptedData = [NSString stringWithUTF8String:(char *)sqlite3_column_blob(mysqlStatement, 0)];
NSData *dataToDecrypt = [[NSData alloc] initWithBase64EncodedString:strEncryptedData options:0];
NSString *password = @"somesecurepassword";
NSData *saltData = [@"mysalt" dataUsingEncoding:NSUTF8StringEncoding];
NSData *ivData = [@"myIV16charvalue1" dataUsingEncoding:NSUTF8StringEncoding];
NSError *error;
NSData *decryptedData = [RNCryptManager decryptedDataForData:encoded password:password iv:ivData salt:saltData HMACSalt:NULL HMAC:NULL error:&error];
NSString *str = [[NSString alloc] initWithData:decryptedData encoding:NSASCIIStringEncoding];
NSLog(@"decrypted string: %@", str);
//这是加密.NET端数据的代码:
static string hashAlgorithm = "SHA1";
static int passwordIterations = 3;
static string initVector = "myIV16charvalue1";
static int keySize = 128;
static string passPhrase = "somesecurepassword";
static string saltValue = "mysalt";
public static string EncryptData(string plainText)
{
byte[] initVectorBytes = Encoding.ASCII.GetBytes(initVector);
byte[] saltValueBytes = Encoding.ASCII.GetBytes(saltValue);
byte[] plainTextBytes = Encoding.UTF8.GetBytes(plainText);
PasswordDeriveBytes password = new PasswordDeriveBytes(
passPhrase,
saltValueBytes,
hashAlgorithm,
passwordIterations);
byte[] keyBytes = password.GetBytes(keySize / 8);
RijndaelManaged symmetricKey = new RijndaelManaged();
// It is reasonable to set encryption mode to Cipher Block Chaining
// (CBC). Use default options for other symmetric key parameters.
symmetricKey.Mode = CipherMode.CBC;
symmetricKey.BlockSize = 128;
symmetricKey.Padding = PaddingMode.PKCS7;
ICryptoTransform encryptor = symmetricKey.CreateEncryptor(
keyBytes,
initVectorBytes);
MemoryStream memoryStream = new MemoryStream();
CryptoStream cryptoStream = new CryptoStream(memoryStream,
encryptor,
CryptoStreamMode.Write);
// Start encrypting.
cryptoStream.Write(plainTextBytes, 0, plainTextBytes.Length);
// Finish encrypting.
cryptoStream.FlushFinalBlock();
byte[] cipherTextBytes = memoryStream.ToArray();
memoryStream.Close();
cryptoStream.Close();
string cipherText = Convert.ToBase64String(cipherTextBytes);
return cipherText;
}
答案 0 :(得分:2)
这里有几个错误。看起来decryptedDataForData:...
是RNCryptManager的修改版本,但是注入了几个错误。特别是,看起来作者复制了加密方法(encryptedDataForData:...
),然后才改变了操作。你不能这样做。解密方法与加密方法不同。在上面的代码中,解密器忽略传递给它的salt和IV,并创建随机的(这是加密器的工作方式,而不是解密器)。
其他一些问题:
在您的加密器中,您将PBKDF2迭代设置为3.在解密器中,您将它们设置为2.此值非常非常低BTW。它通常至少为1000,更经常至少为10,000。
你的IV是错误的长度。它必须是16个字节。理想情况下,每个消息的IV应该是不同的,并且应该被发送到解密器。如果您有静态IV,则会降低加密的安全性。
虽然不是您的问题的原因,但盐也应该随机发送每条消息并发送给解密器。静态盐可以更容易地执行密码攻击。
编辑:(请注意,您仍然使用已被黑客攻击的encryptedDataWithData:
版本进行解密。我建议使用上面链接的decryptedDataWithData:
方法。您的攻击方式{ {1}}可能会起作用,但仅仅因为它创建的缓冲区太长了。)
更深层次的问题是您在C#中使用了错误的KDF。您正在使用实现PBKDF1的encryptedDataWithData:
。您应该使用Rfc2898DeriveBytes
,它实现了PBKDF2。
请注意,您正在使用的RNCryptManager版本中存在错误。在PasswordDeriveBytes
中,此行:
AESKeyForPassword:salt:
应该是:
password.length, // passwordLength