title: 3DES Decryption Sometimes Different
body: <p>I'm having a problem using the CCCrypt function to simply encrypt/decrypt a chunk of data.</p>
  
  <p>My platform is iOS 8 in Xcode 6.</p>
  
  <p>What I'm doing is, I convert a test string to NSData format and pass it into a wrapper function I made.  The return of that function is the encrypted data.  I take that encrypted data and then pass it back into the function specifying that it should be decrypted.</p>
  
  <ul>
  <li><strong>Sometimes</strong> the value comes back decrypted properly.</li>
  <li>Sometimes it's complete junk.</li>
  <li>Sometimes said junk is not the same (but sometimes it is).</li>
  <li>Sometimes I'm seeing the correct string but with extra junk at the end of it.</li>
  </ul>
  
  <p>I wrapped the use of the encryption/decryption function in a loop so I can see the inconsistent behavior more closely.</p>
  
  <p><strong>The Implementation</strong></p>
  
  <pre><code>NSString* unencryptedString = @"Testtest";
  NSData* unencryptedData = [NSData dataWithBytes:(void*)[unencryptedString UTF8String] length:[unencryptedString length]];
  NSData* encryptedData = nil;
  NSData* decryptedData = nil;
  
  for(int i=0;i&lt;100;i++)
  {
      encryptedData = [NSData tripleDesEncrypt:YES Data:unencryptedData error:&amp;err];
      decryptedData = [NSData tripleDesEncrypt:NO Data:encryptedData error:&amp;err];
  
      NSLog(@"unencrypted: %@, encrypted: %s\n\ndecrypted: %s", unencryptedString, encryptedData.bytes, decryptedData.bytes);
  
      if(err)
          NSLog(@"error: %@", err);
  }
  </code></pre>
  
  <p><strong>The Function</strong></p>
  
  <pre><code>+(NSData*)tripleDesEncrypt:(BOOL)encrypt
                    Data:(NSData *)inputData
                   error:(NSError **)error
  {
      NSString* tripleDesKeyString = @"ABCd@Efghijklmno";
      NSData* tripleDesKeyData = [tripleDesKeyString dataUsingEncoding:NSUTF8StringEncoding];
      const void* tripleDesKey = [tripleDesKeyData bytes];
  
      NSString* ivKeyString =   @"012345678901234567890123";
      NSData* keyData = [ivKeyString dataUsingEncoding:NSUTF8StringEncoding];
      const void* ivKey = [keyData bytes];
      NSAssert(keyData.length == kCCKeySize3DES, @"tripleDesEncrypt; the keyData is an invalid size");
  
      NSNumber* pOptions = [NSNumber numberWithInt:kCCOptionPKCS7Padding];
      int options = [pOptions intValue];
      size_t dataMoved;
  
      unsigned encryptionBufferLen = inputData.length + kCCBlockSize3DES;
      void* encryptedBuffer = malloc(encryptionBufferLen);
      memset(encryptedBuffer, 0, encryptionBufferLen);
  
      CCCryptorStatus
      result = CCCrypt(encrypt ? kCCEncrypt : kCCDecrypt, // operation
                       kCCAlgorithm3DES, // Algorithm
                       options, // options
                       tripleDesKey, // key
                       tripleDesKeyData.length, // keylength
                       ivKey,// iv
                       inputData.bytes, // dataIn
                       inputData.length, // dataInLength,
                       encryptedBuffer, // dataOut
                       encryptionBufferLen, // dataOutAvailable
                       &amp;dataMoved); // dataOutMoved
  
      NSData* outputData = [NSData dataWithBytes:encryptedBuffer length:dataMoved];
      free(encryptedBuffer);
  
      return outputData;
  }
  </code></pre>
  
  <p><strong>The Output</strong></p>
  
  <p><em>(I'll only run a few iterations of the output to show the weird differences.)</em></p>
  
  <pre><code>unencrypted: Testtest, encrypted: jgüb  -A7‘œåÅKX
  decrypted: ¿Ïh5¥√‚qN;1»Í
  
  unencrypted: Testtest, encrypted: ¥⁄˘qÓırS{ÿœ•
  decrypted: Æ˛ {íÒ⁄ñè–%4¢‚g
  
  unencrypted: Testtest, encrypted: jgüb  -A7‘œåÅKX
  decrypted: Testtest∞¸yå`j/private/tmp/com.apple.CoreSimulator.SimDevice.47124028-EC86-4CC0-8CA2-7DCDED3994B1.launchd_sim/syslogsock
  
  
  unencrypted: Testtest, encrypted: /Âò◊9ƒ˘=m]˚†%À
  decrypted: u‹z©tÙÁ∑&lt;%ˇπØ•
  
  unencrypted: Testtest, encrypted: jgüb  -A7‘œåÅKX
  decrypted: ¿Ïh5¥√‚qN;1»Í
  
  unencrypted: Testtest, encrypted: jgüb  -A7‘œåÅKX
  decrypted: Testtest
  </code></pre>