How to encrypt an NSString in Objective C with DES in ECB-Mode?
DES encryption in ECB mode uses an 8 byte block size, and encodes each blocks individually. The problem is that your input string doesn't divide into 8 bytes equally and the cryptor doesn't know what to do with the final non 8 byte block.
The fix is to allow the cryptor to pad the final block by adding kCCOptionPKCS7Padding to the options to CCCrypt. eg (snippet from an NSData encryption category):
CCCryptorStatus cryptStatus = CCCrypt(kCCEncrypt,
kCCAlgorithmDES,
kCCOptionPKCS7Padding | kCCOptionECBMode,
keyPtr,
kCCKeySizeDES,
NULL,
[self bytes],
dataLength,
buffer,
bufferSize
&numBytesEncrypted);
Take a look at this post for more details regarding padding algorithms. Hope this helps.
Comments
-
Thomas Kekeisen almost 2 years
I am trying to encrypt an NSString in Objective C on the iPhone. At least I wan't to get a string like "TmsbDaNG64lI8wC6NLhXOGvfu2IjLGuEwc0CzoSHnrs=" when I encode "us=foo;pw=bar;pwAlg=false;" by using this key: "testtest".
My problem for now is, that CCCrypt always returns "4300 - Parameter error" and I have no more idea why.
This is my code (the result of 5 hours google and try'n'error):
NSString *token = @"us=foo;pw=bar;pwAlg=false;"; NSString *key = @"testtest"; const void *vplainText; size_t plainTextBufferSize; plainTextBufferSize = [token length]; vplainText = (const void *) [token UTF8String]; CCCryptorStatus ccStatus; uint8_t *bufferPtr = NULL; size_t bufferPtrSize = 0; size_t *movedBytes; 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 *initVec = @"init Vec"; const void *vkey = (const void *) [key UTF8String]; const void *vinitVec = (const void *) [initVec UTF8String]; ccStatus = CCCrypt(kCCEncrypt, kCCAlgorithmDES, kCCOptionECBMode, vkey, //"123456789012345678901234", //key kCCKeySizeDES, NULL,// vinitVec, //"init Vec", //iv, vplainText, //"Your Name", //plainText, plainTextBufferSize, (void *)bufferPtr, bufferPtrSize, movedBytes); NSString *result; NSData *myData = [NSData dataWithBytes:(const void *)bufferPtr length:(NSUInteger)movedBytes]; result = [myData base64Encoding];
-
Thomas Kekeisen about 14 yearsAllright, this worked for me, thank you! Now I have the following result: "Tm==Da==64==8w==NL==OG==u2==LG==wc==zo==nrs=" but I want: "TmsbDaNG64lI8wC6NLhXOGvfu2IjLGuEwc0CzoSHnrs=" without all the equal signs. Do you have an idea how to fix this?
-
Thomas Kekeisen about 14 yearsSolved it. I am now using a base64-encoding-method from here which produces no "==" all the time: cocoadev.com/index.pl?BaseSixtyFour
-
Adhamox over 12 yearsThank you @crafterm. Saved my life!
-
Motti Shneor about 6 yearsThank you very much, the first real answer to my issues... however, could you PLEASE also explain how to use the other block-by-block APIs? not the one-shot CCCrypt ? I need to convert an old ntlm authentication code that uses openSSL DES_ecb_encrypt after DES_set_key etc.