Reputation: 729
I use CommonCryptor.h for encryption and decryption to encrypt various size of text.
EX.
// first stringhello peter, how are you. You look not good today. Do you want to go to the department store
// second string
i'm fine.
I use the methods borrowed by the below link. Any cocoa source code for AES encryption decryption? How can I get the the specific and equal size of NSData returned from the method like 256 bytes, no matter how many charactors I encrypt. For example, I want the size of encrypted data for the first and second string to be 256 bytes equally.
If it's not possible, which algorithm I should use to get the equal size of encrypted text for various length of 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;
}
Upvotes: 0
Views: 515
Reputation: 15693
As @Jonathan Leffler points out, this can result in the creation of a great deal of extra message traffic.
Basically you need to add enough junk to the shorter message to make it the same length as the longer message. There are a lot of ways to do this, but here is a very simple one. Assume that your shorter message doesn't end in "Q". Add enough Qs to make it the same length as the longer message. On decryption, remove all trailing Qs. If the message does end in "Q" then use "X" instead. This scheme is not foolproof (the longer message may end in Q or X as well). For a foolproof scheme you will need to encode the original length (or the padding length) in a fixed size field somewhere in the padding, which may mean padding the longer message as well.
Upvotes: 0