objective c cryptography:如何获得各种长度的相同大小的加密数据

时间:2011-12-16 04:24:51

标签: objective-c encryption cryptography aes

我使用CommonCryptor.h进行加密和解密,以加密各种大小的文本。

  

EX。
  //第一个字符串

     你好彼得,你好吗?你今天看起来不太好。你想去百货商店吗?

     

//第二个字符串

     

我没事。

我使用以下链接借用的方法。 Any cocoa source code for AES encryption decryption? 我怎样才能获得从256字节方法返回的特定和相同大小的NSData,无论我加密了多少个字符。 例如,我希望第一个和第二个字符串的加密数据大小平均为256个字节。

如果不可能,我应该使用哪种算法为不同长度的NSData获取相同大小的加密文本?

#import <CommonCrypto/CommonCryptor.h>
@implementation NSData (AESAdditions)
- (NSData*)AES256EncryptWithKey:(NSString*)key {
    // 'key' should be 32 bytes for AES256, will be null-padded otherwise
    char keyPtr[kCCKeySizeAES256 + 1]; // room for terminator (unused)
    bzero(keyPtr, sizeof(keyPtr)); // fill with zeroes (for padding)

    // fetch key data
    [key getCString:keyPtr maxLength:sizeof(keyPtr) encoding:NSUTF8StringEncoding];

    NSUInteger dataLength = [self length];

    //See the doc: For block ciphers, the output size will always be less than or
    //equal to the input size plus the size of one block.
    //That's why we need to add the size of one block here
    size_t bufferSize           = dataLength + kCCBlockSizeAES128;
    void* buffer                = malloc(bufferSize);

    size_t numBytesEncrypted    = 0;
    CCCryptorStatus cryptStatus = CCCrypt(kCCEncrypt, kCCAlgorithmAES128, kCCOptionPKCS7Padding,
                                          keyPtr, kCCKeySizeAES256,
                                          NULL /* initialization vector (optional) */,
                                          [self bytes], dataLength, /* input */
                                          buffer, bufferSize, /* output */
                                          &numBytesEncrypted);

    if (cryptStatus == kCCSuccess)
    {
        //the returned NSData takes ownership of the buffer and will free it on deallocation
        return [NSData dataWithBytesNoCopy:buffer length:numBytesEncrypted];
    }

    free(buffer); //free the buffer;
    return nil;
}

- (NSData*)AES256DecryptWithKey:(NSString*)key {
    // 'key' should be 32 bytes for AES256, will be null-padded otherwise
    char keyPtr[kCCKeySizeAES256 + 1]; // room for terminator (unused)
    bzero(keyPtr, sizeof(keyPtr)); // fill with zeroes (for padding)

    // fetch key data
    [key getCString:keyPtr maxLength:sizeof(keyPtr) encoding:NSUTF8StringEncoding];

    NSUInteger dataLength = [self length];

    //See the doc: For block ciphers, the output size will always be less than or
    //equal to the input size plus the size of one block.
    //That's why we need to add the size of one block here
    size_t bufferSize           = dataLength + kCCBlockSizeAES128;
    void* buffer                = malloc(bufferSize);

    size_t numBytesDecrypted    = 0;
    CCCryptorStatus cryptStatus = CCCrypt(kCCDecrypt, kCCAlgorithmAES128, kCCOptionPKCS7Padding,
                                          keyPtr, kCCKeySizeAES256,
                                          NULL /* initialization vector (optional) */,
                                          [self bytes], dataLength, /* input */
                                          buffer, bufferSize, /* output */
                                          &numBytesDecrypted);

    if (cryptStatus == kCCSuccess)
    {
        //the returned NSData takes ownership of the buffer and will free it on deallocation
        return [NSData dataWithBytesNoCopy:buffer length:numBytesDecrypted];
    }

    free(buffer); //free the buffer;
    return nil;
}

1 个答案:

答案 0 :(得分:0)

正如@Jonathan Leffler所指出的,这可能会导致大量额外的消息流量。

基本上,您需要为较短的消息添加足够的垃圾,使其与较长的消息长度相同。有很多方法可以做到这一点,但这里有一个非常简单的方法。假设您的短消息不以“Q”结尾。添加足够的Q以使其与较长消息的长度相同。在解密时,删除所有尾随Q.如果消息以“Q”结尾,则改为使用“X”。这种方案并非万无一失(较长的消息也可能以Q或X结尾)。对于一个万无一失的方案,您需要在填充中的某个固定大小的字段中对原始长度(或填充长度)进行编码,这可能意味着填充更长的消息。