Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/154.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
在iOS上解密AES-128加密数据_Ios_Encryption_Aes - Fatal编程技术网

在iOS上解密AES-128加密数据

在iOS上解密AES-128加密数据,ios,encryption,aes,Ios,Encryption,Aes,我试图解密加密数据(在.NET中加密),但解密后的结果字符串似乎不可读,并且没有收到任何错误 使用以下方法对数据进行加密: 填充:PKCS7Padding 密钥大小:128 模式:CBC 我有InItVector、PassCode、salt和NumberOfPassword(3)迭代 这是我的密码: //I am retrieving my encrypted data from sqlite database: NSString *strEncryptedData = [NSString

我试图解密加密数据(在.NET中加密),但解密后的结果字符串似乎不可读,并且没有收到任何错误

使用以下方法对数据进行加密:

  • 填充:PKCS7Padding
  • 密钥大小:128
  • 模式:CBC
我有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;
}

这里有几个错误。看起来,
decryptedDataForData:…
是的修改版本,但插入了几个错误。特别是,作者复制了加密方法(
encryptedDataForData:…
),然后更改了操作。你不能那样做。解密方法与加密方法不同。在上面的代码中,解密程序忽略传递给它的salt和IV,并创建随机的salt和IV(这是加密程序的工作方式,而不是解密程序)

其他一些问题:

  • 在加密机中,将PBKDF2迭代设置为3。在解密程序中,将它们设置为2。顺便说一句,这个值非常非常低。它通常至少为1000,更常见的是至少为10000

  • 你的静脉注射长度不对。它必须正好是16个字节。理想情况下,每个消息的IV应该不同,并且应该一起发送给解密程序。如果有静态IV,则会降低加密的安全性

  • 虽然不是问题的原因,但salt也应该随机发送给每条消息并发送给解密程序。静态salt使执行密码攻击更容易


编辑:(请注意,您仍在使用黑客版本的
encryptedDataWithData:
进行解密。我建议使用上面链接的
decryptedDataWithData:
方法。黑客攻击
encryptedDataWithData:
的方式可能会起作用,但这只是因为它创建的缓冲区太长。)

更深层次的问题是在C#中使用了错误的KDF。您使用的是实现PBKDF1的
PasswordDeriveBytes
。您应该使用,它实现了PBKDF2

请注意,您正在使用的RNCryptManager版本中存在一个bug。在
AESKeyForPassword:salt:
中,此行:

password.length,  // passwordLength
应该是:

[password lengthOfBytesUsingEncoding:UTF8StringEncoding],

发布在.net中加密的代码在.net中加密数据的添加代码…您最终找到了解决此问题的方法吗?Rob,非常感谢您对我的问题发表评论。是的,“decryptedDataForData”方法是您的文章“使用AES和CommonCrypto正确加密”中RNCryptManager(encryptedDataForData)的修改版本(非常有用的btw)。我已经更新了代码,使用提供的IV/Salt值,而不是生成随机值。另外,我将PBKDF2更改为3以匹配加密。IV值是16字节,我刚刚用一些文本替换了它。但是,在解密后,我仍然得到无法读取的字符串,没有错误:(Rob,谢谢你的评论,我现在使用RNCryptManager的“decryptedDataForData”方法,但是我仍然得到相同的无法读取的解密字符串。我无法控制.net加密,有没有办法修改代码,使其在解密时使用PBKDF1而不是PBKDF2?再次感谢你。CommonCrypto不提供PBKDF1实现你可以使用CytoTopp或BooTANN提供C++实现(虽然它们是一个函数的大的包),或者你可以四处搜索C实现,你可以适应。