当前位置: 首页 > 知识库问答 >
问题:

IOS中的AES解密不能给出准确的结果

韶镜
2023-03-14
- (NSData *)AES128Operation:(CCOperation)operation key:(NSString *)key iv:(NSString *)iv
{
    NSLog(@"inside AES128Operation");
    char keyPtr[kCCKeySizeAES128 + 1];
    bzero(keyPtr, sizeof(keyPtr));
    [key getCString:keyPtr maxLength:sizeof(keyPtr) encoding:NSUTF8StringEncoding];

    char ivPtr[kCCBlockSizeAES128 + 1];
    bzero(ivPtr, sizeof(ivPtr));
    if (iv) {
        [iv getCString:ivPtr maxLength:sizeof(ivPtr) encoding:NSUTF8StringEncoding];
    }

    NSUInteger dataLength = [self length];
    size_t bufferSize = dataLength + kCCBlockSizeAES128;
    void *buffer = malloc(bufferSize);

    size_t numBytesEncrypted = 0;
    CCCryptorStatus cryptStatus = CCCrypt(operation,
                                          kCCAlgorithmAES128,
                                          kCCOptionPKCS7Padding | kCCOptionECBMode,
                                          keyPtr,
                                          kCCBlockSizeAES128,
                                          ivPtr,
                                          [self bytes],
                                          dataLength,
                                          buffer,
                                          bufferSize,
                                          &numBytesEncrypted);

    if (cryptStatus == kCCSuccess) {
         return [NSData dataWithBytes:buffer length:numBytesEncrypted];
    }
    free(buffer);
    return nil;
}
NSString *strKey = MyKey;
NSString *strIv = MyIV;
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory , NSUserDomainMask, YES);
NSString *documentsDir = [paths objectAtIndex:0];
NSString *pathLocal_encrypted = [documentsDir stringByAppendingPathComponent:@"encrypted.file"];

NSData *data_encrpted = [[NSFileManager defaultManager] contentsAtPath:pathLocal_encrypted];

NSData *decryptedData = [data_encrpted AES128DecryptedDataWithKey:strKey iv:strIv];
    static byte[] GetBytes(string str)
    {
        byte[] bytes = new byte[str.Length * sizeof(char)];
        System.Buffer.BlockCopy(str.ToCharArray(), 0, bytes, 0, bytes.Length);
        return bytes;
    }

    private static byte[] DecryptBytes(SymmetricAlgorithm alg, byte[] message)
    {
        if ((message == null) || (message.Length == 0))
        {
            return message;
        }
        using (var stream = new MemoryStream())
        {
            using (var decryptor = alg.CreateDecryptor())
            using (var encrypt = new CryptoStream(stream, decryptor, CryptoStreamMode.Write))
            {
                encrypt.Write(message, 0, message.Length);
                encrypt.FlushFinalBlock();
            }
            return stream.ToArray();
        }
    }
                path = openFileDialog1.FileName;
                byte[] encMessage = StreamFile(path);
                byte[] decMessage; 

                byte[] rkey = GetBytes(Mykey);
                byte[] riv = GetBytes(MyIv);
                using (var rijndael = new RijndaelManaged())
                {
                    rijndael.Key = rkey;
                    rijndael.IV = riv;
                    decMessage = DecryptBytes(rijndael, encMessage);
                }
    NSData *key = [NSData dataWithData:[strKey dataUsingEncoding:NSUTF8StringEncoding]];
    NSData *iv = [NSData dataWithData:[strIv dataUsingEncoding:NSUTF8StringEncoding]];
    NSData *decryptedData = [self doCipher:data_encrpted iv:iv key:key context:kCCDecrypt];
- (NSData *)doCipher:(NSData *)dataIn
                  iv:(NSData *)iv
                 key:(NSData *)symmetricKey
             context:(CCOperation)encryptOrDecrypt
{

    CCCryptorStatus ccStatus   = kCCSuccess;
    size_t          cryptBytes = 0;    // Number of bytes moved to buffer.
    NSMutableData  *dataOut    = [NSMutableData dataWithLength:dataIn.length + kCCBlockSizeAES128];

    ccStatus = CCCrypt( encryptOrDecrypt,
                       kCCAlgorithmAES128,
                       kCCOptionPKCS7Padding,
                       symmetricKey.bytes,
                       kCCKeySizeAES128,
                       iv.bytes,
                       dataIn.bytes,
                       dataIn.length,
                       dataOut.mutableBytes,
                       dataOut.length,
                       &cryptBytes);


        NSLog(@"CCCrypt status: %d", ccStatus);


    dataOut.length = cryptBytes;
    NSLog(@"CCCrypt ataOut.length: %d", dataOut.length);
    return dataOut;
}
   public RijndaelManaged GetRijndaelManaged(string secretKey, string iv)
    {
        var keyBytes = new byte[16];
        var secretKeyBytes = Encoding.UTF8.GetBytes(secretKey);
        Array.Copy(secretKeyBytes, keyBytes, Math.Min(keyBytes.Length, secretKeyBytes.Length));

        var ivBytes = new byte[16];
        var secretIvBytes = Encoding.UTF8.GetBytes(iv);
        Array.Copy(secretIvBytes, ivBytes, Math.Min(ivBytes.Length, secretIvBytes.Length));

        return new RijndaelManaged
        {
            Mode = CipherMode.CBC,
            Padding = PaddingMode.PKCS7,
            KeySize = 128,
            BlockSize = 128,
            Key = keyBytes,
            IV = ivBytes
        };
    }

    public byte[] Encrypt(byte[] plainBytes, RijndaelManaged rijndaelManaged)
    {
        return rijndaelManaged.CreateEncryptor()
            .TransformFinalBlock(plainBytes, 0, plainBytes.Length);
    }

    public byte[] Decrypt(byte[] encryptedData, RijndaelManaged rijndaelManaged)
    {
        return rijndaelManaged.CreateDecryptor()
            .TransformFinalBlock(encryptedData, 0, encryptedData.Length);
    }

共有1个答案

张浩阔
2023-03-14

AES的iv与块大小相同:128位(16字节),问题说明:“iv是一个8字节向量”,这是不正确的。

因为您使用的是iv,所以模式应该是CBC,但是代码指定kccoptionecbmode,请删除此操作,iOS(通用加密)的默认模式是CBC模式。

请注意,RijndaelManaged默认为CBC模式和PKCS#7填充。但是,如果未显式设置,则密钥大小由所提供的密钥的长度确定,并且为null填充为支持的密钥长度。最好显式地设置它,在RijndaelManaged中使用keysize参数(以位为单位)。

 类似资料:
  • 我尝试像这样查询api: http://api.openweathermap.org/data/2.5/weather?q=kuwait 但是,它给了我与国家“PE”相关的结果。我下载了网站上引用的国家代码json文件,并用“科威特”这个词搜索了所有城市,只有1个城市是:“科威特城”,一个是“科威特”。为什么API在搜索“科威特”时会返回国家“PE”? 我也用了

  • 我有这个代码: 它产生这样的结果: (在新选项卡中打开图像以查看完整尺寸。) 现在,这些值加起来甚至为。即使这个值也比实际值高。

  • 问题内容: 我一直在寻找一个解决方案,并在Node.js服务器和Objective-C客户端上进行加密,反之亦然,使用AES(或其他合适的方法)进行搜索 我对密码学还比较陌生,因此我无法理解为什么每种语言的加密文本都不同。 这是我到目前为止的内容: 使用此CryptoJS库的 Node.js加密方法 -node-cryptojs-aes 使用AESCrypt库的 Objective-C加密方法 多

  • 我正在尝试编写方法来加密或解密字符串(大部分是数字)。它适用于某些文本(例如-'1010000011'、'1010000012'、'1010000013'),但也适用于其他文本(例如-'1010000014'、'1010000018'): javax.crypto.BadPadding异常:给定最后一个块没有正确填充 这是我的代码: 要加密的字符串从文件中读取,并在加密后写入其他文件。这些加密的文

  • 我正在尝试用AES解密来解密一个Base64Encoded字符串消息。 从输入中提取IV和加密文本 使用IV和相同的密码短语生成用于加密文本的密钥。密钥生成应遵循以下相同的步骤。 生成PBE密钥(256位) 用法: 任何线索将非常感谢,我想知道我是否错过了一些配置或数据转换时,试图转换在SWIFT。

  • 我正在开发一个应用程序,其中包括播放声音文件。我的问题是声音文件是用一个命令行工具加密的,这个工具可以在Aescrypt.com上找到,只是提供文件和密码。我用Aescrypt.com上的Java代码成功解密了android应用程序中的文件,但我无论如何也不能让它在iOS上不起作用。 我已经尝试解密文件的所有字节和不包括文件头的字节。我得到一个字节的结果集,但它不会播放,估计的声音长度大约是实际长