File Encryption and Decryption using AES in Objective-C - ios

I am very new in iOS app developing. I need to encrypt and decrypt the files in ios using objective-c. While i am searching i got string encrypt and decrypt only.
CCCryptorStatus status = CCCrypt(kCCDecrypt,/* kCCEncrypt, etc. */
kCCAlgorithmAES128, /* kCCAlgorithmAES128, etc. */
kCCOptionPKCS7Padding, /* kCCOptionPKCS7Padding, etc. */
keyPointer, kCCKeySizeAES256,/* key and its length */
ivPointer, /* initialization vector - use same IV which was used for decryption */
[encryptedText bytes], [encryptedText length], //input
buff, buffSize,//output
&numBytesEncrypted);
Here how can i encrypt and decrypt the files. Thanks

Finally i got the solution for file encrypt and decrypt using AES. I maintain same code for both encrypt and decrypt for files using crypt type. if we pass the crypttype as 1 the file encrypt using aes. If we do decrypt we can pass the value as 2.
FileAes.m
RCT_EXPORT_METHOD(encryptDecryptFile:(NSString *)crypType
appkey:(NSString *)key
inputPath:(NSString *)inputPath
outPutPath : (NSString *)outputPath
resolver:(RCTPromiseResolveBlock)resolve
rejecter:(RCTPromiseRejectBlock)reject)
{
if ([[SecurityUtil encryptDecryptAESFile:crypType app_key:key input_path:inputPath output_path:outputPath] length] <= 0) {
reject(#"ERROR", #"decrypt failed", nil);
}
resolve ([SecurityUtil encryptDecryptAESFile:crypType app_key:key input_path:inputPath output_path:outputPath]);
}
SecurityUtil.m
+(NSString*)encryptDecryptAESFile:(NSString*)cryptType app_key:(NSString*)key input_path:(NSString*)inputPath output_path:(NSString *)outputPath
{
NSLog(#"file input path===> %#",cryptType);
NSString *res;
NSData *decryedData;
#try {
NSData *data = [NSData dataWithContentsOfFile:inputPath];
if(cryptType == #"1"){
decryedData = [data AES128EncryptFileWithKey:key ];
}else{
decryedData = [data AES128DecryptFileWithKey:key ];
}
//NSData *decryedData = [data AES128DecryptFileWithKey:key gIv:key];
[decryedData writeToFile:outputPath atomically:YES];
res =#"success";
return res;
}
#catch (NSException *exception) {
NSLog(#"Exception in decrypt File==> %#", exception.reason);
res=#"failure";
return res;
}
#finally {
NSLog(#"Finally condition=== %#",res);
return res;
}
}
NSDataAesFile.m
- (NSData *)AES128DecryptFileWithKey:(NSString *)key {//FileDecrypt
char keyPtr[kCCKeySizeAES128+1];
bzero(keyPtr, sizeof(keyPtr));
[key getCString:keyPtr maxLength:sizeof(keyPtr) encoding:NSUTF8StringEncoding];
char ivPtr[kCCKeySizeAES128+1];
memset(ivPtr, 0, sizeof(ivPtr));
[key getCString:ivPtr maxLength:sizeof(ivPtr) encoding:NSUTF8StringEncoding];//gIv
NSUInteger dataLength = [self length];
size_t bufferSize = dataLength + kCCBlockSizeAES128;
void *buffer = malloc(bufferSize);
size_t numBytesDecrypted = 0;
CCCryptorStatus cryptStatus = CCCrypt(kCCDecrypt,
kCCAlgorithmAES128,
kCCOptionPKCS7Padding,
keyPtr,
kCCBlockSizeAES128,
ivPtr,
[self bytes],
dataLength,
buffer,
bufferSize,
&numBytesDecrypted);
if (cryptStatus == kCCSuccess) {
NSLog(#"crypt status==> %d", cryptStatus);
return [NSData dataWithBytesNoCopy:buffer length:numBytesDecrypted];
}
free(buffer);
return nil;
}
The above code is working for me. May be it will help.

Related

How to decrypt AES128 encryption with provided string, mode, key, padding and key

I am trying to decrypt an AES encryption with the following information provided:
Encryption type: AES 128
Mode: CBC
Padding: PKCS5 (.net uses PKCS7)
Password(key): jayjay
Encryption ref: https://zenu.wordpress.com/2011/09/21/aes-128bit-cross-platform-java-and-c-encryption-compatibility/
Example provided:
Encrypted string: vsiv+Tv0H9Tz0GHtf2S4KBXVV+0L6Wr0xCWwA1QOPs8rnyRxNDDgH4ogo5Mm+wrzEW6uFD2kdFI2IcSTx+RMu
3817A7n1/ZLCjqq6ZTXI3QZbWgr6AH3SOGM/lcnud4EROGUiZuTiWIBjxTy+q/8tA==
Decrypted string (expected): BadgeID^CustIDLookup^First Name^Last Name^Title^Company^Address 1^Address
2^City^State^Zip^Country^Phone^Email
Unfortunately without actually knowing how it has been encrypted, it seems that the decoding is not fully working.
I've created a category of NSString with the following method:
- (NSString *)decryptWithKey:(NSString *)key {
NSData *stringData = [self dataUsingEncoding:NSUTF8StringEncoding];
NSData *keyData = [key dataUsingEncoding:NSUTF8StringEncoding];
size_t decryptedDataLength = [stringData length] + kCCKeySizeAES128;
NSMutableData *decryptedData = [NSMutableData dataWithLength:kCCKeySizeAES128 + decryptedDataLength];
size_t numberOfBytes;
CCCryptorStatus status = CCCrypt(kCCDecrypt,
kCCAlgorithmAES128,
kCCOptionPKCS7Padding,
[keyData bytes],
kCCKeySizeAES128,
nil,
[stringData bytes], [stringData length],
decryptedData.mutableBytes, [decryptedData length],
&numberOfBytes);
if (status == kCCSuccess) {
return [decryptedData base64EncodedStringWithOptions:NSDataBase64Encoding64CharacterLineLength];
} else {
NSLog(#"Status: %d", status);
return #"";
}
}
I get a kCCSuccess status but the string is not as expected. Any help will be greatly appreciated.

AES/cbc/pkcs5padding encription IOS

I have used AES algorithm for encryption in android.
The following code we have used for encryption.
String seed = "somekey";
Key key = null;
// 128 bit key
byte[] byteKey = seed.substring(0, 16).getBytes("UTF-8");
key = new SecretKeySpec(byteKey, "AES");
Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
cipher.init(Cipher.ENCRYPT_MODE, key, new IvParameterSpec(
new byte[16]));
byte[] encValue = cipher.doFinal(pValue.getBytes());
encryptedText = new BASE64Encoder().encode(encValue);
Can any one please provide the above logic for IOS.
Thanking in Advance.
It works both on android with:
#define FBENCRYPT_KEY_SIZE kCCKeySizeAES128
instead:
#define FBENCRYPT_KEY_SIZE kCCKeySizeAES256
You can use the following snippet as start point:
+ (NSData*)encryptData:(NSData*)data key:(NSData*)key iv:(NSData*)iv;
{
NSData* result = nil;
// setup key
unsigned char cKey[FBENCRYPT_KEY_SIZE];
bzero(cKey, sizeof(cKey));
[key getBytes:cKey length:FBENCRYPT_KEY_SIZE];
// setup iv
char cIv[FBENCRYPT_BLOCK_SIZE];
bzero(cIv, FBENCRYPT_BLOCK_SIZE);
if (iv) {
[iv getBytes:cIv length:FBENCRYPT_BLOCK_SIZE];
}
// setup output buffer
size_t bufferSize = [data length] + FBENCRYPT_BLOCK_SIZE;
void *buffer = malloc(bufferSize);
// do encrypt
size_t encryptedSize = 0;
CCCryptorStatus cryptStatus = CCCrypt(kCCEncrypt,
FBENCRYPT_ALGORITHM,
kCCOptionPKCS7Padding,
cKey,
FBENCRYPT_KEY_SIZE,
cIv,
[data bytes],
[data length],
buffer,
bufferSize,
&encryptedSize);
if (cryptStatus == kCCSuccess) {
result = [NSData dataWithBytesNoCopy:buffer length:encryptedSize];
} else {
free(buffer);
NSLog(#"[ERROR] failed to encrypt|CCCryptoStatus: %d", cryptStatus);
}
return result;
}
+ (NSData*)decryptData:(NSData*)data key:(NSData*)key iv:(NSData*)iv;
{
NSData* result = nil;
// setup key
unsigned char cKey[FBENCRYPT_KEY_SIZE];
bzero(cKey, sizeof(cKey));
[key getBytes:cKey length:FBENCRYPT_KEY_SIZE];
// setup iv
char cIv[FBENCRYPT_BLOCK_SIZE];
bzero(cIv, FBENCRYPT_BLOCK_SIZE);
if (iv) {
[iv getBytes:cIv length:FBENCRYPT_BLOCK_SIZE];
}
// setup output buffer
size_t bufferSize = [data length] + FBENCRYPT_BLOCK_SIZE;
void *buffer = malloc(bufferSize);
// do decrypt
size_t decryptedSize = 0;
CCCryptorStatus cryptStatus = CCCrypt(kCCDecrypt,
FBENCRYPT_ALGORITHM,
kCCOptionPKCS7Padding,
cKey,
FBENCRYPT_KEY_SIZE,
cIv,
[data bytes],
[data length],
buffer,
bufferSize,
&decryptedSize);
if (cryptStatus == kCCSuccess) {
result = [NSData dataWithBytesNoCopy:buffer length:decryptedSize];
} else {
free(buffer);
NSLog(#"[ERROR] failed to decrypt| CCCryptoStatus: %d", cryptStatus);
}
return result;
}
Constants
#define FBENCRYPT_ALGORITHM kCCAlgorithmAES128
#define FBENCRYPT_BLOCK_SIZE kCCBlockSizeAES128
#define FBENCRYPT_KEY_SIZE kCCKeySizeAES256
For more information, see FBEncryptor
Hope this helps.
Since AES has a bock size of 16-bytes PKCS#7Padding is required. Some earlier AES library implementers specified PKCS#5Padding in error.
PKCS#5Padding is only specified for a block size up to 8-bytes and PKCS#7Padding is specified for a block size up to 255-bytes. See Wikipedia: Padding. IOW PKCS#7Padding can be used in place of PKCS#5Padding.

3DES iOS encrypt different from .Net server

I'm trying to encrypt a request, I made this function but I'm getting a different encrypt value in the .NET server. This is the function I'm using in iOS:
- (NSData *)Encrypt3DESWithInput:(NSString *)input
key:(NSString *)key
{
NSData *inputData = [input dataUsingEncoding:NSUTF8StringEncoding];
NSData *keyData = [key dataUsingEncoding:NSUTF8StringEncoding];
NSUInteger dataLength = [inputData length];
size_t bufferSize = dataLength + kCCBlockSize3DES;
void *buffer = malloc(bufferSize);
size_t numBytesEncrypted = 0;
CCCryptorStatus cryptStatus = CCCrypt(kCCEncrypt,
kCCAlgorithm3DES,
kCCOptionPKCS7Padding,
[keyData bytes],
kCCKeySize3DES,
initializationVector,
[inputData bytes],
dataLength,
buffer,
bufferSize,
&numBytesEncrypted);
if (cryptStatus == kCCSuccess) {
NSLog(#"Success");
//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;
}
These are the values im using in the private key and the initialization vector:
static NSString *const privateKey = #"";
static const char initializationVector[8] = {31, 10, 35, 17, 0, 42, 151, 64};
Use a key that is the natural length of the encryption/decryption routine. Don't rely on key padding, that is undefined. If you have a password use PBKDF2 to create a full length secure key..
The key string is #"" yet the key data is created by [key dataUsingEncoding:NSUTF8StringEncoding]
NSString *keyString = #"";
NSData *keyData = [keyString dataUsingEncoding:NSUTF8StringEncoding];
NSLog output:
keyString: ''
keyData: <>
Note the key length is 0 so the DES method will access random data from memory.

Why am I getting different results each time I try to decrypt AES data with the iOS SDK?

I am working on AES encryption and decryption.
I am giving single data and single key to decrypt but am getting different outputs every time.
I am using like this:
+(NSData*)decryptData:(NSData*)data key:(NSData*)key iv:(NSData*)iv
{
NSData* result = nil;
// setup key
unsigned char cKey[FBENCRYPT_KEY_SIZE];
bzero(cKey, sizeof(cKey));
[key getBytes:cKey length:FBENCRYPT_KEY_SIZE];
// setup iv
char cIv[FBENCRYPT_BLOCK_SIZE];
bzero(cIv, FBENCRYPT_BLOCK_SIZE);
if (iv) {
[iv getBytes:cIv length:FBENCRYPT_BLOCK_SIZE];
}
// setup output buffer
size_t bufferSize = [data length] + FBENCRYPT_BLOCK_SIZE;
void *buffer = malloc(bufferSize);
// do decrypt
size_t decryptedSize = 0;
CCCryptorStatus cryptStatus = CCCrypt(kCCDecrypt,
FBENCRYPT_ALGORITHM,
kCCOptionECBMode,
cKey,
FBENCRYPT_KEY_SIZE,
cIv,
[data bytes],
[data length],
buffer,
bufferSize,
&decryptedSize);
if (cryptStatus == kCCSuccess) {
result = [NSData dataWithBytesNoCopy:buffer length:decryptedSize];
} else {
free(buffer);
NSLog(#"[ERROR] failed to decrypt| CCCryptoStatus: %d", cryptStatus);
}
return result;
}
Best guess without any example data, etc is that the key or iv are the incorrect size and/or the padding or mode is different.

Web service to Xcode encryption

I am trying encrypt data on an iPhone and send up the encrypted text to a web service for them to decrypt it. If the decryption works then it returns the First name in the xml as a confirmation things worked. Here is my Xcode
Note: The 'key' is the same in both xcode and web service
The information I want encrypted:
NSString *fnameencrypted = [[NSString alloc] AES256EncryptWithKey:f_name.text withKey:key]];
NSString *lnameencrypted = [[NSString alloc] AES256EncryptWithKey:l_name.text withKey:key]];
The NSString method
-(NSString *)AES256EncryptWithKey:(NSString *)plaintext withKey:(NSString *)key{
NSData *plainData = [plaintext dataUsingEncoding:NSASCIIStringEncoding];
NSData *encryptedData = [plainData AES256EncryptWithKey:key];
NSString *encryptedString = [encryptedData base64Encoding];
return encryptedString;
}
EDIT
The encryption method
-(NSData *)AES256EncryptWithKey:(NSString *)key{
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:NSASCIIStringEncoding];
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, kCCOptionECBMode + 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;
}
Here is my web service code
private static string Decrypt(string encryptedText, string completeEncodedKey, int keySize)
{
RijndealManaged aesEncryption = new RijndealManaged();
aesEncryption.KeySize = keySize; //keySize is 256
aesEncryption.BlockSize = 128;
aesEncryption.Mode = CipherMode.ECB;
aesEncryption.Padding = PaddingMode.PKCS7;
aesEncryption.IV = Convert.FromBase64String(ASCIIEncoding.ACSII.GetString(Convert.FromBase64String(completeEncodedString)).Split(',')[0]);
aesEncryption.Key = Convert.FromBase64String(ASCIIEncoding.ACSII.GetString(Convert.FromBase64String(completeEncodedString)).Split(',')[1]);
ICryptoTransform decrypto = aesEncryption.CreateDecryptor();
byte[] encryptedBytes = Convert.FromBase64CharArray(encryptedText.ToCharArray(), 0, encryptedText.Length);
return ASCIIEncoding.ASCII.GetString(decrypto.TransformFinalBlock(encryptedBytes, 0, encryptedBytes.Length);
}
This code does not work because it returns
<response><return>0</return></response>

Resources