Задача c Криптография: как получить одинаковый размер зашифрованных данных различной длины - PullRequest
0 голосов
/ 16 декабря 2011

Я использую CommonCryptor.h для шифрования и дешифрования для шифрования текста различного размера.

EX.
// первая строка

привет Питер, как ты? Ты сегодня плохо выглядишь. Вы хотите пойти в универмаг

// вторая строка

Я в порядке.

Я использую методы, заимствованные по ссылке ниже. Какой-нибудь исходный код какао для расшифровки шифрования AES? Как я могу получить конкретный и равный размер NSData, возвращаемый методом, например, 256 байтов, независимо от того, сколько символов я шифрую. Например, я хочу, чтобы размер зашифрованных данных для первой и второй строки равнялся 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 голосов
/ 16 декабря 2011

Как отмечает @Jonathan Leffler, это может привести к созданию большого дополнительного трафика сообщений.

Как правило, вам нужно добавить достаточно мусора к более короткому сообщению, чтобы сделать его такой же длины, как и более длинное сообщение. Есть много способов сделать это, но вот очень простой. Предположим, что ваше более короткое сообщение не заканчивается на "Q". Добавьте достаточно Q, чтобы сделать его такой же длины, как длинное сообщение. При расшифровке удалите все завершающие вопросы. Если сообщение заканчивается на «Q», используйте вместо него «X». Эта схема не является надежной (более длинное сообщение также может заканчиваться на Q или X). Для надежной схемы вам необходимо закодировать исходную длину (или длину заполнения) в поле фиксированного размера где-нибудь в заполнении, что также может означать заполнение более длинного сообщения.

...