【问题标题】:Objective-C decrypt AES 128 cbc hex stringObjective-C 解密 AES 128 cbc 十六进制字符串
【发布时间】:2012-03-13 10:18:15
【问题描述】:

我正在使用 Xcode 3.1 在 Snow Leopard 上为 iPhone 开发一个应用程序,该应用程序从一个安静的 Web 服务接收一个使用 AES 128 位 (CBC) 算法的十六进制格式的加密文本。该算法使用初始化向量 + 密钥。如何解密此文本?感谢大家提供的提示,我将成功提供。

编辑: 我从 REST 服务器以十六进制和加密格式获得响应,我尝试使用此代码,但我总是收到错误的参数错误。你能帮我找出错误吗? 我可以先将字符串响应转换为二进制格式吗?

      NSString *response = [request responseString];

      NSData *encryptedData = [response dataUsingEncoding: NSASCIIStringEncoding];
      NSString *key  = @"32charlength";
      NSString *iv   = @"16charlength";  
      NSData *unencryptedData = NULL;
      size_t unencryptedLength = [unencryptedData length];
      CCCryptorStatus ccStatus = CCCrypt(kCCDecrypt, kCCAlgorithmAES128, 0, key, kCCKeySizeAES128, iv, [encryptedData bytes], [encryptedData length], unencryptedData, [encryptedData length], &unencryptedLength);     
      NSString *output = [[NSString alloc] initWithBytes:unencryptedData length:unencryptedLength encoding:NSUTF8StringEncoding];

      if (ccStatus == kCCSuccess) risultato.text = @"SUCCESS";
      else if (ccStatus == kCCParamError) risultato.text =  @"BAD PARAM";
      else if (ccStatus == kCCBufferTooSmall) risultato.text =  @"BUFFER TOO SMALL";
      else if (ccStatus == kCCMemoryFailure) risultato.text =  @"MEMORY FAILURE";
      else if (ccStatus == kCCAlignmentError) risultato.text =  @"ALIGNMENT";
      else if (ccStatus == kCCDecodeError) risultato.text =  @"DECODE ERROR";
      else if (ccStatus == kCCUnimplemented)  risultato.text = @"UNIMPLEMENTED";

编辑2: 此函数返回 BAD PARAM,因为分配解密数据的缓冲区大小不正确。我以这种工作方式编辑函数:

      NSData *encryptedData = [response dataUsingEncoding: NSASCIIStringEncoding];
      const void *key  = @"32charlength;
      uint8_t *iv      = @"16charlength";  
      char buffer[4*4096]; 
      memset(buffer, '\0', sizeof(buffer));
              size_t size = sizeof(buffer);
      CCCryptorStatus ccStatus = CCCrypt(kCCDecrypt, 
                                         kCCAlgorithmAES128, 
                                         0, 
                                         key, 
                                         kCCKeySizeAES128, 
                                         iv, 
                                         [encryptedData bytes], 
                                         [encryptedData length], 
                                         buffer, 
                                         sizeof(buffer), 
                                         &size);

这个功能对我有用.. 非常感谢。

编辑 3 月 23 日------

现在系统以 16 字节的密钥大小工作。现在我有一个问题,我能做些什么来实现 32 字节的密钥大小?非常感谢。

【问题讨论】:

    标签: iphone objective-c ios xcode aes


    【解决方案1】:

    这可以使用 <CommonCrypto/CommonCryptor.h> 标头中包含的 CCCryptor 函数来实现。检查man CCCryptor 了解详细信息,在您的情况下,听起来您可以使用对CCCrypt() 的单个调用来解码接收到的数据:

    CCCryptorStatus
    CCCrypt(CCOperation op, CCAlgorithm alg, CCOptions options, const void *key, size_t keyLength,
         const void *iv, const void *dataIn, size_t dataInLength, void *dataOut, size_t dataOutAvailable,
         size_t *dataOutMoved);
    

    假设您有要在 NSData *encryptedData 中解密的数据,您可以尝试以下操作:

    char * key = "shouldbe16chars.";
    NSUInteger dataLength = [encryptedData length];
    uint8_t unencryptedData[dataLength + kCCKeySizeAES128];
    size_t unencryptedLength;
    
    CCCrypt(kCCDecrypt, kCCAlgorithmAES128, 0, key, kCCKeySizeAES128, NULL, [encryptedData bytes], dataLength, unencryptedData, dataLength, &unencryptedLength);
    NSString *output = [[NSString alloc] initWithBytes:unencryptedData length:unencryptedLength encoding:NSUTF8StringEncoding];
    

    这是未经测试的,请确保检查CCCrypt 的返回值是否有错误。详情查看头文件,有据可查。

    【讨论】:

    • 我是新手,如何初始化 var?我试试这个: NSString *hex = [NSString stringWithFormat:@"%@",response]; CCOperation *op = "解密"; CC算法 *alg = @"AES"; CCOptions *options = NULL; const void *key = "xxxx"; size_t *keyLength = [密钥长度]; const void *iv = @"xxxxxxxx-x-xxxxx"; size_t dataInLength = [十六进制长度];无效 *dataOut = 响应; size_t dataOutAvailable = 10000; size_t *dataOutMoved = NULL; CCCrypt(op, alg, options , key, keyLength, iv, hex, dataInLength, dataOut, dataOutAvailable , dataOutMoved);
    • 这是一个 C 级 API,而且你到处混用对象类型和枚举。我在上面添加了一个示例。如果你想知道应该给什么类型的参数,只需按住 Cmd 键并单击函数名即可进入头文件,对参数类型执行相同操作即可查看选项。
    • 现在可以使用 16 字节的密钥大小。我可以做些什么来使用 32 字节的密钥大小?
    • 感谢您的回复,您确定不支持硬件吗?在网上我看到了这个gist.github.com/838614,但我不知道它是否适合我..
    • 我很愚蠢,对块大小和密钥大小感到困惑。 AES 算法始终使用 128 位块大小,但密钥大小不同,因此您实际上只需将 kCCKeySizeAES128 更改为 kCCKeySizeAES256 并提供更长的密钥。
    猜你喜欢
    • 2020-11-13
    • 1970-01-01
    • 1970-01-01
    • 2013-08-11
    • 1970-01-01
    • 1970-01-01
    • 2018-04-04
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多