2016-03-25 41 views
1

我需要AES128使用密钥和IV对16字节AES块对16字节的数据块进行加密。如何将NSData作为密钥发送,并发送给CCCrypt

我见过的每个CCCrypt示例都带有(NSString *)键和IV。我的密钥和IV是NSData 16个字节。我已经将NSData转换为十六进制字符串,但结果不正确。当我这样做时,我得到一个32字节的AES块。

所以我的问题是,我需要做什么来获取NSData作为一个const void *读入CCCrypt?

- (NSData *)AES128Operation:(CCOperation)operation key:(NSString *)key iv:(NSString *)iv theData:(NSData *)theData 
{ 
    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 = [theData length]; 
    size_t bufferSize = dataLength + kCCBlockSizeAES128; 
    void *buffer = malloc(bufferSize); 

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


    if (cryptStatus == kCCSuccess) { 
     return [NSData dataWithBytesNoCopy:buffer length:numBytesEncrypted]; 
    } 
    free(buffer); 
    return nil; 
} 
+1

您指定PKCS7填充。 PKCS7至少添加1个字节的填充,因此,加密16个字节会将您推送到2个16字节= 32字节的加密数据块中。 –

+0

谢谢。对不起,我只是把它放进去测试。当填充不存在时,我确实得到了16个字节。我问如何将16字节的NSData转换为ivPtr和keyPtr的const void *输入。 – Scott

+0

ECB模式不使用IV,也许你需要默认的CBC模式。 – zaph

回答

0
+ (NSData *)AES128:(NSData *)dataIn 
     operation:(CCOperation)operation // kCC Encrypt, Decrypt 
       key:(NSData *)key 
      options:(CCOptions)options  // kCCOption PKCS7Padding, ECBMode, 
       iv:(NSData *)iv 
      error:(NSError **)error 
{ 
    CCCryptorStatus ccStatus = kCCSuccess; 
    size_t   cryptBytes = 0; 
    NSMutableData *dataOut = [NSMutableData dataWithLength:dataIn.length + kCCBlockSizeAES128]; 

    ccStatus = CCCrypt(operation, 
         kCCAlgorithmAES, 
         options, 
         key.bytes, key.length, 
         iv.bytes, 
         dataIn.bytes, dataIn.length, 
         dataOut.mutableBytes, dataOut.length, 
         &cryptBytes); 

    if (ccStatus == kCCSuccess) { 
     dataOut.length = cryptBytes; 
    } 
    else { 
     if (error) { 
      *error = [NSError errorWithDomain:@"kEncryptionError" 
             code:ccStatus 
            userInfo:nil]; 
     } 
     dataOut = nil; 
    } 

    return dataOut; 
} 
+0

谢谢Zaph,但仍然得到了32字节的结果。 dataIn,key和IV都是16个字节。我试过AES和AES128,我有PKS7Padding,这是一个CBC块。我想,当你传递所有16字节的数据时,你应该得到16个字节。 – Scott

+0

使用填充必须始终添加一些填充,因此必须添加一个填充块时传递块大小倍数的数据。请参阅:[PKCS#7填充](https://en.wikipedia.org/wiki/Padding_(cryptography)#PKCS7)。 – zaph

+0

这确实对@ zaph有帮助。我必须加密并发送到解密的服务。我被告知他们正在使用CBC和PKCS7padding,但只需要16个字节。当我添加填充选项时,它给了我32个,但是当我发送它时就解决了。我会投票你的回应,但我没有足够的代表!再次感谢。 – Scott