I am trying to encrypt an xml string.After the encryption is done then the decrypt the encrypted d I am getting the string as ALIGNMENT.
I dont understand what is the reason
(NSString*) doCipher:(NSString*)plainText:(CCOperation)encryptOrDecrypt {
const void *vplainText;
size_t plainTextBufferSize;
if (encryptOrDecrypt == kCCDecrypt)
{
NSData *EncryptData = [NSData dataFromBase64String:plainText];
plainTextBufferSize = [EncryptData length];
vplainText = [EncryptData bytes];
}
else
{
plainTextBufferSize = [plainText length];
vplainText = (const void *) [plainText UTF8String];
}
CCCryptorStatus ccStatus;
uint8_t *bufferPtr = NULL;
size_t bufferPtrSize = 0;
size_t movedBytes = 0;
// uint8_t iv[kCCBlockSize3DES];
bufferPtrSize = (plainTextBufferSize + kCCBlockSize3DES) & ~(kCCBlockSize3DES - 1);
bufferPtr = malloc( bufferPtrSize * sizeof(uint8_t));
memset((void *)bufferPtr, 0x0, bufferPtrSize);
// memset((void *) iv, 0x0, (size_t) sizeof(iv));
NSString *key = #"123456789012345678901234";
NSString *initVec = #"init Vec";
const void *vkey = (const void *) [key UTF8String];
const void *vinitVec = (const void *) [initVec UTF8String];
ccStatus = CCCrypt(encryptOrDecrypt,
kCCAlgorithm3DES,
kCCOptionPKCS7Padding,
vkey, //"123456789012345678901234", //key
kCCKeySize3DES,
vinitVec, //"init Vec", //iv,
vplainText, //"Your Name", //plainText,
plainTextBufferSize,
(void *)bufferPtr,
bufferPtrSize,
&movedBytes);
//if (ccStatus == kCCSuccess) NSLog(#"SUCCESS");
//else/
if (ccStatus == kCCParamError) return #"PARAM ERROR";
else if (ccStatus == kCCBufferTooSmall) return #"BUFFER TOO SMALL";
else if (ccStatus == kCCMemoryFailure) return #"MEMORY FAILURE";
else if (ccStatus == kCCAlignmentError) return #"ALIGNMENT";
else if (ccStatus == kCCDecodeError) return #"DECODE ERROR";
else if (ccStatus == kCCUnimplemented) return #"UNIMPLEMENTED";
NSString *result;
if (encryptOrDecrypt == kCCDecrypt)
{
result = [ [NSString alloc] initWithData: [NSData dataWithBytes:(const void *)bufferPtr length:(NSUInteger)movedBytes] encoding:NSASCIIStringEncoding];
}
else
{
NSData *myData = [NSData dataWithBytes:(const void *)bufferPtr length:(NSUInteger)movedBytes];
result = [myData base64EncodedString];
}
return result;
}
kCCAlignmentError means that the data you are passing is not correctly padded (specifically that the entire data length including padding is not a multiple of the block size). The most likely cause is that you are truncating your encrypted data somewhere, possibly outside of this routine.
You should check your encrypted data at each step and make sure that it is always a multiple of the block size (8 bytes). You'll need to base64-decode before checking the length.
Related
I have googled too much for this error but found nothing useful.
I am getting a file that is encrypted in php using the following code:
mcrypt_encrypt(MCRYPT_RIJNDAEL_128, $privateencryptkey, base64_encode(file), MCRYPT_MODE_CBC, $hardvector);
I am unable to decrypt it in IOS. I had tried many libraries like NSDATA+CommonCrypto, NSFileManager-AES, NSDATA-aes but i have not got success in decrypting the file.
Following is the objective-C code used:
- (NSData *)AESDecryptWithPassphrase:(NSString *)pass
{
NSMutableData *ret = [NSMutableData dataWithCapacity:[self length]];
unsigned long rk[RKLENGTH(KEYBITS)];
unsigned char key[KEYLENGTH(KEYBITS)];
const char *password = [pass UTF8String];
for (int i = 0; i < sizeof(key); i++)
key[i] = password != 0 ? *password++ : 0;
int nrounds = rijndaelSetupDecrypt(rk, key, KEYBITS);
unsigned char *srcBytes = (unsigned char *)[self bytes];
int index = 0;
while (index < [self length])
{
unsigned char plaintext[16];
unsigned char ciphertext[16];
int j;
for (j = 0; j < sizeof(ciphertext); j++)
{
if (index >= [self length])
break;
ciphertext[j] = srcBytes[index++];
}
rijndaelDecrypt(rk, nrounds, ciphertext, plaintext);
[ret appendBytes:plaintext length:sizeof(plaintext)];
}
return ret;
}
This code works well for text but unable to decrypt files.
When i save the decrypted files then it says the file system error. Those decrypted files cannot be opened on any system, i think the file format is disturbed in the process.
I also tried the following code but no success:
- (NSData *) decryptedDataUsingAlgorithm: (CCAlgorithm) algorithm
key: (id) key // data or string
initializationVector: (id) iv // data or string
options: (CCOptions) options
error: (CCCryptorStatus *) error
{
CCCryptorRef cryptor = NULL;
CCCryptorStatus status = kCCSuccess;
NSParameterAssert([key isKindOfClass: [NSData class]] || [key isKindOfClass: [NSString class]]);
NSParameterAssert(iv == nil || [iv isKindOfClass: [NSData class]] || [iv isKindOfClass: [NSString class]]);
NSMutableData * keyData, * ivData;
if ( [key isKindOfClass: [NSData class]] )
keyData = (NSMutableData *) [key mutableCopy];
else
keyData = [[key dataUsingEncoding: NSUTF8StringEncoding] mutableCopy];
if ( [iv isKindOfClass: [NSString class]] )
ivData = [[iv dataUsingEncoding: NSUTF8StringEncoding] mutableCopy];
else
ivData = (NSMutableData *) [iv mutableCopy]; // data or nil
[keyData autorelease];
[ivData autorelease];
// ensure correct lengths for key and iv data, based on algorithms
FixKeyLengths( algorithm, keyData, ivData );
status = CCCryptorCreate( kCCDecrypt, algorithm, options,
[keyData bytes], [keyData length], [ivData bytes],
&cryptor );
if ( status != kCCSuccess )
{
if ( error != NULL )
*error = status;
return ( nil );
}
NSData * result = [self _runCryptor: cryptor result: &status];
if ( (result == nil) && (error != NULL) )
*error = status;
CCCryptorRelease( cryptor );
return ( result );
}
2nd function from above code:
- (NSData *) _runCryptor: (CCCryptorRef) cryptor result: (CCCryptorStatus *) status
{
size_t bufsize = CCCryptorGetOutputLength( cryptor, (size_t)[self length], true );
void * buf = malloc( bufsize );
size_t bufused = 0;
size_t bytesTotal = 0;
*status = CCCryptorUpdate( cryptor, [self bytes], (size_t)[self length],
buf, bufsize, &bufused );
if ( *status != kCCSuccess )
{
free( buf );
return ( nil );
}
bytesTotal += bufused;
// From Brent Royal-Gordon (Twitter: architechies):
// Need to update buf ptr past used bytes when calling CCCryptorFinal()
*status = CCCryptorFinal( cryptor, buf + bufused, bufsize - bufused, &bufused );
if ( *status != kCCSuccess )
{
free( buf );
return ( nil );
}
bytesTotal += bufused;
return ( [NSData dataWithBytesNoCopy: buf length: bytesTotal] );
}
I haven't been able to solve this for a week...
One thing to note is the file parameter to mcrypt_encrypt, it appears that the file is being base64 encoded prior to encryption (not that it makes any sense), that would imply you would have to base64 decode after decryption.
The other parameters are straight forward:
MCRYPT_RIJNDAEL_128 is AES, 128 with a 128 bit key
MCRYPT_MODE_CBC is cbc mode, the default for CommonCrypto.
The padding to block size is with null characters, rather nonstandard so the non-padded length may be a problem.
Not that you need yet another AES method, this is the one I use:
#import <CommonCrypto/CommonCryptor.h>
+ (NSData *)doCipher:(NSData *)dataIn
iv:(NSData *)iv
key:(NSData *)symmetricKey
context:(CCOperation)encryptOrDecrypt
{
CCCryptorStatus ccStatus = kCCSuccess;
size_t cryptBytes = 0; // Number of bytes moved to buffer.
NSMutableData *dataOut = [NSMutableData dataWithLength:dataIn.length + kCCBlockSizeAES128];
ccStatus = CCCrypt( encryptOrDecrypt,
kCCAlgorithmAES128,
kCCOptionPKCS7Padding,
symmetricKey.bytes,
kCCKeySizeAES128,
iv.bytes,
dataIn.bytes,
dataIn.length,
dataOut.mutableBytes,
dataOut.length,
&cryptBytes);
if (ccStatus != kCCSuccess) {
NSLog(#"CCCrypt status: %d", ccStatus);
}
dataOut.length = cryptBytes;
return dataOut;
}
// Also add Security.framework to your project.
Note that it expects NSData input and the padding is specified as standard PKCS.
See CommonCryptor.h
i am trying to encrypt my data using before sending it to server, is there any highly secure two way encryption algorithm ? which one is best for this purpose.
Check ths once
Here, key is string variable, declare as a global variable.
add sequrity framework for your code and import
#import <CommonCrypto/CommonDigest.h>
#import <CommonCrypto/CommonCryptor.h>
- (void)viewDidLoad
{
[super viewDidLoad];
key=#"Your own key";
// encoding
NSString *encodingString=[[self encrypt:[#"Your String"
dataUsingEncoding:NSUTF8StringEncoding]
base64EncodedString];;
//decoding
NSData *data=[self decrypt:[NSData dataFromBase64String:encryptString]];
NSString *decodingString = [[NSString alloc] initWithBytes:[data bytes] length:
[data length] encoding: NSASCIIStringEncoding];
}
- (NSData *) encrypt:(NSData *) plainText {
return [self transform:kCCEncrypt data:plainText];
}
- (NSData *) decrypt:(NSData *) cipherText {
return [self transform:kCCDecrypt data:cipherText];
}
- (NSData *) transform:(CCOperation) encryptOrDecrypt data:(NSData *) inputData {
// kCCKeySizeAES128 = 16 bytes
// CC_MD5_DIGEST_LENGTH = 16 bytes
NSData* secretKey = [ChipperObject md5:Key];
CCCryptorRef cryptor = NULL;
CCCryptorStatus status = kCCSuccess;
uint8_t iv[kCCBlockSizeAES128];
memset((void *) iv, 0x0, (size_t) sizeof(iv));
status = CCCryptorCreate(encryptOrDecrypt,
kCCAlgorithmAES128,kCCOptionPKCS7Padding,
[secretKey bytes], kCCKeySizeAES128, iv, &cryptor);
if (status != kCCSuccess) {
return nil;
}
size_t bufsize = CCCryptorGetOutputLength(cryptor, (size_t)[inputData length],
true);
void * buf = malloc(bufsize * sizeof(uint8_t));
memset(buf, 0x0, bufsize);
size_t bufused = 0;
size_t bytesTotal = 0;
status = CCCryptorUpdate(cryptor, [inputData bytes], (size_t)[inputData length],
buf, bufsize, &bufused);
if (status != kCCSuccess) {
free(buf);
CCCryptorRelease(cryptor);
return nil;
}
bytesTotal += bufused;
status = CCCryptorFinal(cryptor, buf + bufused, bufsize - bufused, &bufused);
if (status != kCCSuccess) {
free(buf);
CCCryptorRelease(cryptor);
return nil;
}
bytesTotal += bufused;
CCCryptorRelease(cryptor);
return [NSData dataWithBytesNoCopy:buf length:bytesTotal];
}
Here is my code using 3des CCCrypt Method,Find GTMBase64.h from googlecode, https://code.google.com/p/google-toolbox-for-mac/source/browse/trunk/Foundation/GTMBase64.h?r=87
#import <CommonCrypto/CommonCryptor.h>
#import "GTMBase64.h"
- (NSData*)TripleDES:(NSData*)plainData encryptOrDecrypt:(CCOperation)encryptOrDecrypt key:(NSString*)key {
const void *vplainText;
size_t plainTextBufferSize;
if (encryptOrDecrypt == kCCDecrypt)
{
NSData *EncryptData = [GTMBase64 decodeData:plainData];
plainTextBufferSize = [EncryptData length];
vplainText = [EncryptData bytes];
}
else
{
plainTextBufferSize = [plainData length];
vplainText = (const void *)[plainData bytes];
}
CCCryptorStatus ccStatus;
uint8_t *bufferPtr = NULL;
size_t bufferPtrSize = 0;
size_t movedBytes = 0;
// uint8_t ivkCCBlockSize3DES;
bufferPtrSize = (plainTextBufferSize + kCCBlockSize3DES) & ~(kCCBlockSize3DES - 1);
bufferPtr = malloc( bufferPtrSize * sizeof(uint8_t));
memset((void *)bufferPtr, 0x0, bufferPtrSize);
// memset((void *) iv, 0x0, (size_t) sizeof(iv));
// NSString *key = #"123456789012345678901234";
NSString *initVec = #"init Vec";
const void *vkey = (const void *) [key UTF8String];
const void *vinitVec = (const void *) [initVec UTF8String];
ccStatus = CCCrypt(encryptOrDecrypt,
kCCAlgorithm3DES,
kCCOptionPKCS7Padding,
vkey, //"123456789012345678901234", //key
kCCKeySize3DES,
vinitVec, //"init Vec", //iv,
vplainText, //"Your Name", //plainText,
plainTextBufferSize,
(void *)bufferPtr,
bufferPtrSize,
&movedBytes);
//if (ccStatus == kCCSuccess) NSLog(#"SUCCESS");
/*else if (ccStatus == kCC ParamError) return #"PARAM ERROR";
else if (ccStatus == kCCBufferTooSmall) return #"BUFFER TOO SMALL";
else if (ccStatus == kCCMemoryFailure) return #"MEMORY FAILURE";
else if (ccStatus == kCCAlignmentError) return #"ALIGNMENT";
else if (ccStatus == kCCDecodeError) return #"DECODE ERROR";
else if (ccStatus == kCCUnimplemented) return #"UNIMPLEMENTED"; */
NSData *result;
if (encryptOrDecrypt == kCCDecrypt)
{
result = [NSData dataWithBytes:(const void *)bufferPtr length:(NSUInteger)movedBytes];
}
else
{
NSData *myData = [NSData dataWithBytes:(const void *)bufferPtr length:(NSUInteger)movedBytes];
result = [GTMBase64 encodeData:myData];
}
return result;
}
Usage
NSString *inputString = #"good";
//encode
NSData *inputData = [inputString dataUsingEncoding:NSUTF8StringEncoding];
NSData *encriptdata = [self TripleDES:inputData encryptOrDecrypt:kCCEncrypt key:#"ff68f8e82961489a8b14b345"];
NSString *encodeString = [GTMBase64 stringByEncodingData:encriptdata];
NSLog(#"encodeString : %#" ,encodeString);
//decode
NSData *encodeData = [GTMBase64 decodeString:encodeString];
NSData *decodeData = [self TripleDES:encodeData encryptOrDecrypt:kCCDecrypt key:#"ff68f8e82961489a8b14b345"];
NSString *decodeString = [[NSString alloc] initWithBytes:[decodeData bytes] length:[decodeData length] encoding:NSUTF8StringEncoding];
NSLog(#"decodeString : %#" ,decodeString);
Public Key Infrastructure (PKI) offers you a trustworthy way to encrypt data between 2 machines. You can give it a try.
You can use HTTPS, or you can also use RC6 to encrypt your data.
I am trying to decrypt the data from last couple of days. I decrypt the data but the result is not same as original. Please, can anyone suggest how I can do this. I am trying to decrypt the following data:
Encrypted Data : "Mmb9tEkmW82oFPJb3vNhHA=="
Encrypt Key : "91860F52E5C3A09BA3B827F28070E08D"
Original data: "Marco"
Please help.
Thanks
Here is how I used AES128
- (NSData *)cipherData:(NSData *)data {
return [self aesOperation:kCCEncrypt OnData:data];
}
- (NSData *)decipherData:(NSData *)data {
return [self aesOperation:kCCDecrypt OnData:data];
}
- (NSData *)aesOperation:(CCOperation)op OnData:(NSData *)data {
NSData *outData = nil;
// Data in parameters
const void *key = cipherKey.bytes;
const void *dataIn = data.bytes;
size_t dataInLength = data.length;
// Data out parameters
size_t outMoved = 0;
// Init out buffer
unsigned char outBuffer[BUFFER_SIZE];
memset(outBuffer, 0, BUFFER_SIZE);
CCCryptorStatus status = -1;
status = CCCrypt(op, kCCAlgorithmAES128, kCCOptionPKCS7Padding, key, kCCKeySizeAES256, NULL,
dataIn, dataInLength, &outBuffer, BUFFER_SIZE, &outMoved);
if(status == kCCSuccess) {
outData = [NSData dataWithBytes:outBuffer length:outMoved];
} else if(status == kCCBufferTooSmall) {
// Resize the out buffer
size_t newsSize = outMoved;
void *dynOutBuffer = malloc(newsSize);
memset(dynOutBuffer, 0, newsSize);
outMoved = 0;
status = CCCrypt(op, kCCAlgorithmAES128, kCCOptionPKCS7Padding, key, kCCKeySizeAES256, NULL,
dataIn, dataInLength, &outBuffer, BUFFER_SIZE, &outMoved);
if(status == kCCSuccess) {
outData = [NSData dataWithBytes:outBuffer length:outMoved];
}
}
return outData;
}
I am using apples "cryptoexcercise" (Security.Framework) in my application to encrypt and decrypt a data of numeric value. When I give the input 950,128 the values got encrypted, but it is not getting decrypted and exists with the encrypted value only. This happens only with the mentioned numeric values. Could you please check this issue and give the solution to solve this problem?
here is my code
(void)testAsymmetricEncryptionAndDecryption {
uint8_t *plainBuffer; uint8_t *cipherBuffer; uint8_t *decryptedBuffer;
const char inputString[] = "950"; int len = strlen(inputString);
if (len > BUFFER_SIZE) len = BUFFER_SIZE-1;
plainBuffer = (uint8_t *)calloc(BUFFER_SIZE, sizeof(uint8_t)); cipherBuffer = (uint8_t *)calloc(CIPHER_BUFFER_SIZE, sizeof(uint8_t)); decryptedBuffer = (uint8_t *)calloc(BUFFER_SIZE, sizeof(uint8_t));
strncpy( (char *)plainBuffer, inputString, len);
NSLog(#"plain text : %s", plainBuffer);
[self encryptWithPublicKey:(UInt8 *)plainBuffer cipherBuffer:cipherBuffer];
NSLog(#"encrypted data: %s", cipherBuffer);
[self decryptWithPrivateKey:cipherBuffer plainBuffer:decryptedBuffer];
NSLog(#"decrypted data: %s", decryptedBuffer);
free(plainBuffer); free(cipherBuffer); free(decryptedBuffer); }
(void)encryptWithPublicKey:(uint8_t *)plainBuffer cipherBuffer:(uint8_t *)cipherBuffer {
OSStatus status = noErr;
size_t plainBufferSize = strlen((char *)plainBuffer); size_t cipherBufferSize = CIPHER_BUFFER_SIZE;
NSLog(#"SecKeyGetBlockSize() public = %d", SecKeyGetBlockSize([self getPublicKeyRef])); // Error handling // Encrypt using the public. status = SecKeyEncrypt([self getPublicKeyRef], PADDING, plainBuffer, plainBufferSize, &cipherBuffer[0], &cipherBufferSize ); NSLog(#"encryption result code: %d (size: %d)", status, cipherBufferSize); NSLog(#"encrypted text: %s", cipherBuffer); }
(void)decryptWithPrivateKey:(uint8_t *)cipherBuffer plainBuffer:(uint8_t *)plainBuffer { OSStatus status = noErr;
size_t cipherBufferSize = strlen((char *)cipherBuffer);
NSLog(#"decryptWithPrivateKey: length of buffer: %d", BUFFER_SIZE); NSLog(#"decryptWithPrivateKey: length of input: %d", cipherBufferSize);
// DECRYPTION size_t plainBufferSize = BUFFER_SIZE;
// Error handling status = SecKeyDecrypt([self getPrivateKeyRef], PADDING, &cipherBuffer[0], cipherBufferSize, &plainBuffer[0], &plainBufferSize ); NSLog(#"decryption result code: %d (size: %d)", status, plainBufferSize); NSLog(#"FINAL decrypted text: %s", plainBuffer);
}
(SecKeyRef)getPublicKeyRef { OSStatus sanityCheck = noErr; SecKeyRef publicKeyReference = NULL;
if (publicKeyRef == NULL) { NSMutableDictionary *queryPublicKey = [[NSMutableDictionary alloc] init];
// Set the public key query dictionary.
[queryPublicKey setObject:(id)kSecClassKey forKey:(id)kSecClass];
[queryPublicKey setObject:publicTag forKey:(id)kSecAttrApplicationTag];
[queryPublicKey setObject:(id)kSecAttrKeyTypeRSA forKey:(id)kSecAttrKeyType];
[queryPublicKey setObject:[NSNumber numberWithBool:YES] forKey:(id)kSecReturnRef];
// Get the key.
sanityCheck = SecItemCopyMatching((CFDictionaryRef)queryPublicKey, (CFTypeRef *)&publicKeyReference);
if (sanityCheck != noErr)
{
publicKeyReference = NULL;
}
[queryPublicKey release];
} else { publicKeyReference = publicKeyRef; }
return publicKeyReference; }
(SecKeyRef)getPrivateKeyRef { OSStatus resultCode = noErr; SecKeyRef privateKeyReference = NULL;
if(privateKeyRef == NULL) { NSMutableDictionary * queryPrivateKey = [[NSMutableDictionary alloc] init];
// Set the private key query dictionary.
[queryPrivateKey setObject:(id)kSecClassKey forKey:(id)kSecClass];
[queryPrivateKey setObject:privateTag forKey:(id)kSecAttrApplicationTag];
[queryPrivateKey setObject:(id)kSecAttrKeyTypeRSA forKey:(id)kSecAttrKeyType];
[queryPrivateKey setObject:[NSNumber numberWithBool:YES] forKey:(id)kSecReturnRef];
// Get the key.
resultCode = SecItemCopyMatching((CFDictionaryRef)queryPrivateKey, (CFTypeRef *)&privateKeyReference);
NSLog(#"getPrivateKey: result code: %d", resultCode);
if(resultCode != noErr)
{
privateKeyReference = NULL;
}
[queryPrivateKey release];
} else { privateKeyReference = privateKeyRef; }
return privateKeyReference; }
I am sorry for the late reply... but your example worked perfectly for me, except the fact,
1) for privateTag and publicTag I had to declare
NSData *privateTag = [NSData dataWithBytes:privateKeyIdentifier length:strlen((const char *)privateKeyIdentifier)];
NSData *publicTag = [NSData dataWithBytes:publicKeyIdentifier length:strlen((const char *)privateKeyIdentifier)];
2) and also changing privateKey == NULL rather than privateKeyRef ==NULL in the key reference IF condition..
I've seen quite a lot of posts about CCCrypt and 3DES on the iPhone at various places around the Net, but there does not seem to be a working example of using it with ECB mode, always with PKCS7Padding.
Does anyone have any working code to encrypt and decrypt a passed string using 3DES and ECB mode using the CCCrypt function?
Currently my code (which I admit came from a site somewhere, I think it was Apple's own developer forums) is as follows:
+ (NSString*)doCipher:(NSString*)plainText action:(CCOperation)encryptOrDecrypt {
const void *vplainText;
size_t plainTextBufferSize;
if (encryptOrDecrypt == kCCDecrypt) {
NSData *EncryptData = [[NSData alloc] initWithBase64EncodedString:plainText];
plainTextBufferSize = [EncryptData length];
vplainText = [EncryptData bytes];
}
else {
//plainTextBufferSize = [plainText length];
//vplainText = (const void *)[plainText UTF8String];
NSData *plainTextData = [plainText dataUsingEncoding: NSUTF8StringEncoding];
plainTextBufferSize = [plainTextData length];
vplainText = [plainTextData bytes];
}
CCCryptorStatus ccStatus;
uint8_t *bufferPtr = NULL;
size_t bufferPtrSize = 0;
size_t movedBytes = 0;
// uint8_t ivkCCBlockSize3DES;
bufferPtrSize = (plainTextBufferSize + kCCBlockSize3DES) & ~(kCCBlockSize3DES - 1);
bufferPtr = malloc( bufferPtrSize * sizeof(uint8_t));
memset((void *)bufferPtr, 0x0, bufferPtrSize);
// memset((void *) iv, 0x0, (size_t) sizeof(iv));
NSString *key = #"123456789012345678901234";
NSString *initVec = #"init Vec";
const void *vkey = (const void *)[key UTF8String];
const void *vinitVec = (const void *)[initVec UTF8String];
ccStatus = CCCrypt(encryptOrDecrypt,
kCCAlgorithm3DES,
kCCOptionECBMode,
vkey, //"123456789012345678901234", //key
kCCKeySize3DES,
nil, //"init Vec", //iv,
vplainText, //"Your Name", //plainText,
plainTextBufferSize,
(void *)bufferPtr,
bufferPtrSize,
&movedBytes);
//if (ccStatus == kCCSuccess) NSLog(#"SUCCESS");
/*else*/ if (ccStatus == kCCParamError) return #"PARAM ERROR";
else if (ccStatus == kCCBufferTooSmall) return #"BUFFER TOO SMALL";
else if (ccStatus == kCCMemoryFailure) return #"MEMORY FAILURE";
else if (ccStatus == kCCAlignmentError) return #"ALIGNMENT";
else if (ccStatus == kCCDecodeError) return #"DECODE ERROR";
else if (ccStatus == kCCUnimplemented) return #"UNIMPLEMENTED";
NSString *result;
if (encryptOrDecrypt == kCCDecrypt) {
result = [[[NSString alloc] initWithData:[NSData dataWithBytes:(const void *)bufferPtr length:(NSUInteger)movedBytes] encoding:NSASCIIStringEncoding] autorelease];
}
else {
NSData *myData = [NSData dataWithBytes:(const void *)bufferPtr length:(NSUInteger)movedBytes];
result = [myData base64EncodingWithLineLength:movedBytes];
}
return result; }
The above ALWAYS fails with PARAM ERROR.
- (NSData *) encrypt:(NSString *) dataToEncrypt{
NSUInteger data_length= [dataToEncrypt length];
uint8_t input_raw_data[data_length];
//The [dataToEncrypt length] gives the number of chars present in the string.So say there are 10 chars.
//Now,the getBytes needs to get the raw bytes from this i.e. binary NSData.But suppose the encoding was
//full 16 bit encoding then the number of bytes needed wd have been double- 20.But as we are using the
//NSUTF8StringEncoding,the number of byes needed is 1 per char as the chars(even if originally unicode are
//compressed into an 8 bit UTF8 encoding.)
[dataToEncrypt getBytes:&input_raw_data maxLength:data_length usedLength:NULL encoding:NSUTF8StringEncoding options:0 range:NSMakeRange(0,data_length) remainingRange:NULL];
//According to 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 buffer_size = data_length + kCCBlockSizeAES128;
void* buffer = malloc(buffer_size);
size_t num_bytes_encrypted = 0;
CCCryptorStatus crypt_status = CCCrypt(kCCEncrypt, kCCAlgorithmAES128, kCCOptionPKCS7Padding,
[self.symmetricKey bytes], kCCKeySizeAES256,
NULL,
input_raw_data, data_length,
buffer, buffer_size,
&num_bytes_encrypted);
NSLog(#"~~num bytes encrypted: %d",num_bytes_encrypted);
if (crypt_status == kCCSuccess){
NSLog(#"~~Data encoded successfully...");
return [NSData dataWithBytesNoCopy:buffer length:num_bytes_encrypted];
}
free(buffer); //free the buffer;
return nil;
}
- (NSData *) decrypt:(NSData *) dataToDecrypt{
NSUInteger data_length= [dataToDecrypt 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 buffer_size = data_length + kCCBlockSizeAES128;
void* buffer = malloc(buffer_size);
size_t num_bytes_decrypted = 0;
CCCryptorStatus crypt_status = CCCrypt(kCCDecrypt, kCCAlgorithmAES128, kCCOptionPKCS7Padding,
[self.symmetricKey bytes], kCCKeySizeAES256,
NULL /* initialization vector (optional) */,
[dataToDecrypt bytes], data_length, /* input */
buffer, buffer_size, /* output */
&num_bytes_decrypted);
NSLog(#"~~num bytes decrypted: %d",num_bytes_decrypted);
if (crypt_status == kCCSuccess){
NSLog(#"~~Data decoded successfully...");
return [NSData dataWithBytesNoCopy:buffer length:num_bytes_decrypted];
}
free(buffer); //free the buffer;
return nil;
}
The above code worked for me, with some changes. The changes are i decelare the moveBytes and bufferPtf as instance variable and did following chandge.
if (encryptOrDecrypt == kCCDecrypt) {
plainTextBufferSize = movedBytes;
vplainText = bufferPtr;
}
else {
plainTextBufferSize = [plainText length];
vplainText = (const void *)[plainText UTF8String];
}
instead base64encoding use nsasciiencoding.