I use following code to encrypt using AES.
- (NSData*)AES256EncryptWithKey:(NSString*)key theMsg:(NSData *)myMessage {
// '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 = [myMessage 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) */,
[myMessage 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;
}
However the following code chunk returns null if I tried to print the encryptmessage variable. Same thing applies to decryption as well. What am I doing wrong here?
NSData *encrData = [self AES256EncryptWithKey:theKey theMsg:myMessage];
NSString *encryptmessage = [[NSString alloc] initWithData:encrData encoding:NSUTF8StringEncoding];
Thank you
try using
size_t bufferSize= dataLength + kCCBlockSizeAES256;
instead of
size_t bufferSize = dataLength + kCCBlockSizeAES128;
Related
I'm writing an application that sends crypted data to an external server. To do that, I have written functions to encrypt/decrypt a NSData buffer. These functions are working perfectly with iOS5, but not works with iOS6. I haven't modified the code. Anybody has a solution? Here is the code:
- (NSData*) AES256EncryptWithKey :(NSString*)pKey :(NSString*)pIV
{
// key length is incorrect?
if ([pKey length] != kCCKeySizeAES256)
{
M_LogErrorT("AE - incorrect value - " << [pKey length]);
return nil;
}
// is initialization vector used?
bool useIV = (pIV && [pIV length]);
// initialization vector length is incorrect?
if (useIV && [pIV length] != kCCBlockSizeAES128)
{
M_LogErrorT("AE - incorrect IV - " << [pIV length]);
return nil;
}
// key should be 32 bytes for AES256, will be null-padded otherwise
char pKeyPtr[kCCKeySizeAES256 + 1]; // room for terminator (unused)
bzero(pKeyPtr, sizeof(pKeyPtr)); // fill with zeroes (for padding)
// fetch key data
[pKey getCString:pKeyPtr maxLength:sizeof(pKeyPtr) encoding:NSUTF8StringEncoding];
// initialization vector should be 16 bytes for AES256
char pIVPtr[kCCBlockSizeAES128 + 1]; // room for terminator (unused)
bzero(pIVPtr, sizeof(pIVPtr)); // fill with zeroes (for padding)
// initialization vector is used?
if (useIV)
// fetch initialization vector data
[pIV getCString:pIVPtr maxLength:sizeof(pIVPtr) 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* pBuffer = malloc(bufferSize);
size_t numBytesEncrypted = 0;
CCCryptorStatus cryptStatus = CCCrypt(kCCEncrypt,
kCCAlgorithmAES128,
kCCOptionPKCS7Padding,
pKeyPtr,
kCCKeySizeAES256,
useIV ? pIVPtr : NULL, /* initialization vector (optional) */
[self bytes],
dataLength, /* input */
pBuffer,
bufferSize, /* output */
&numBytesEncrypted);
if (cryptStatus == kCCSuccess)
// the returned NSData takes ownership of the buffer and will free it on deallocation
return [NSData dataWithBytesNoCopy:pBuffer length:numBytesEncrypted];
// free the buffer
free(pBuffer);
return nil;
}
- (NSData*) AES256DecryptWithKey :(NSString*)pKey :(NSString*)pIV
{
// key length is incorrect?
if ([pKey length] != kCCKeySizeAES256)
{
M_LogErrorT("AE - incorrect value - " << [pKey length]);
return nil;
}
// is initialization vector used?
bool useIV = (pIV && [pIV length]);
// initialization vector length is incorrect?
if (useIV && [pIV length] != kCCBlockSizeAES128)
{
M_LogErrorT("AE - incorrect IV - " << [pIV length]);
return nil;
}
// key should be 32 bytes for AES256, will be null-padded otherwise
char pKeyPtr[kCCKeySizeAES256 + 1]; // room for terminator (unused)
bzero(pKeyPtr, sizeof(pKeyPtr)); // fill with zeroes (for padding)
// fetch key data
[pKey getCString:pKeyPtr maxLength:sizeof(pKeyPtr) encoding:NSUTF8StringEncoding];
// initialization vector should be 16 bytes for AES256
char pIVPtr[kCCBlockSizeAES128 + 1]; // room for terminator (unused)
bzero(pIVPtr, sizeof(pIVPtr)); // fill with zeroes (for padding)
// initialization vector is used?
if (useIV)
// fetch initialization vector data
[pIV getCString:pIVPtr maxLength:sizeof(pIVPtr) 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* pBuffer = malloc(bufferSize);
size_t numBytesDecrypted = 0;
CCCryptorStatus cryptStatus = CCCrypt(kCCDecrypt,
kCCAlgorithmAES128,
kCCOptionPKCS7Padding,
pKeyPtr,
kCCKeySizeAES256,
useIV ? pIVPtr : NULL, /* initialization vector (optional) */
[self bytes],
dataLength, /* input */
pBuffer,
bufferSize, /* output */
&numBytesDecrypted);
if (cryptStatus == kCCSuccess)
// the returned NSData takes ownership of the buffer and will free it on deallocation
return [NSData dataWithBytesNoCopy:pBuffer length:numBytesDecrypted];
// free the buffer
free(pBuffer);
return nil;
}
I use the same code but without the initialization vector and that is working perfectly.
Perhaps try looking in that direction.
I need to decrypt a video file on the iPhone.
Server is using Cipher c = Cipher.getInstance("AES/ECB/NoPadding");
In iPhone I am using the following code (pastie link), but I am not able to decrypt the file successfully.
#import <CommonCrypto/CommonCryptor.h>
#implementation NSData (AES256)
- (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;
}
#end
I have found the solution. changing below line worked for me as an alternative to "AES/ECB/NoPadding" mode in java.
CCCryptorStatus cryptStatus = CCCrypt(kCCEncrypt, kCCAlgorithmAES128, kCCOptionECBMode,
keyPtr, kCCKeySizeAES128,
NULL /* initialization vector (optional) */,
[self bytes], dataLength, /* input */
buffer, bufferSize, /* output */
&numBytesEncrypted);
I am devloping an application which stores a huge amount of data in the sqlite database. But I want to keep the data safe so that no one hacks my database and see the data in my database.
Now how can I encrypt and decrypt my sqlite database?
Pls help me.
Thanks.
I was developed an app that require and I've used this way
First of all, I've initiated a class, called it ConstantMethods.h+m
ConstantMethods.h
#import <Foundation/Foundation.h>
#import <CommonCrypto/CommonCryptor.h>
static NSString *keyEncryption = #"YourPrivateKey";
#interface ConstantMethods : NSObject {
}
+ (NSData*) encryptString:(NSString*)plaintext withKey:(NSString*)key;
+ (NSString*) decryptData:(NSData*)ciphertext withKey:(NSString*)key;
#end
ConstantMethods.m
#import "ConstantMethods.h"
#implementation NSData (AES256)
- (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;
}
#end
#implementation ConstantMethods
+ (NSData*) encryptString:(NSString*)plaintext withKey:(NSString*)key {
return [[plaintext dataUsingEncoding:NSUTF8StringEncoding] AES256EncryptWithKey:key];
}
+ (NSString*) decryptData:(NSData*)ciphertext withKey:(NSString*)key {
return [[[NSString alloc] initWithData:[ciphertext AES256DecryptWithKey:key]
encoding:NSUTF8StringEncoding] autorelease];
}
#end
Then, in your class, import the ConstantMethods.h and use the class as the following:
[ConstantMethods encryptString:#"yourString"];
and when you want to decrypt, use the following:
[ConstantMethods decryptData:#"yourString" withKey:keyEncryption];
After the encryption, insert the encrypted data to the database, and when retrieving the data from database, decrypt it.
I hope that this can help you.
Question is about iOS5 application. I have a view controller where I have some UITextFields.
I would like to encrypt data using AES-256.
In fact, I don't know what are the prerequisite packages that I have to add to do encryption and decryption. I have gone trough other posts but too much explanation messed it up.
Kindly let me know what and all packages, header files I have to include to encrypt data using AES-256
Chandra
refer a following category.
FAQ: What is a category?
In short, Cocoa API to add the method. briefly expand class.
More information,
CustomizingExistingClasses
Category
File-New-Cocoa Touch - Objective-C category
If you want to use a category, your class add a #import"NSData+Encryption.h"
//NSData+Encryption.h
#interface NSData (Encryption)
- (NSData *)AES256EncryptWithKey:(NSString *)key;
- (NSData *)AES256DecryptWithKey:(NSString *)key;
#end
//NSData+Encryption.m
#import "NSData+Encryption.h"
#import <CommonCrypto/CommonCryptor.h>
#implementation NSData (Encryption)
- (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;
}
#end
I'd like to have a file encryption functionality for my iphone application. For desktop based applications i used the function below to encrypt relatively small files:
- (NSData *)aesEncrypt:(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;
}
But i don't think this code can be used on an iphone. If i try to encrypt a 5mb file it will take up at least 10 mb in ram, since it will be loaded to NSData and returned as such. Is there a method that would eccrypt a file by reading small blocks and writing output to another file? Or am i wrong about this taking so m
Try RNCryptor
https://github.com/rnapier/RNCryptor
I've used this successfully in my app.