4

I'm using Apple's SecKeyWrapper class from the CryptoExercise sample code in the Apple docs to do some symmetric encryption with AES128. For some reason, when I encrypt 1-15 characters or 17 characters, it encrypts and decrypts correctly. With 16 characters, I can encrypt, but on decrypt it throws an exception after the CCCryptorFinal call with ccStatus == -4304, which indicates a decode error. (Go figure.)

I understand that AES128 uses 16 bytes per encrypted block, so I get the impression that the error has something to do with the plaintext length falling on the block boundary. Has anyone run into this issue using CommonCryptor or SecKeyWrapper?

atxe
  • 5,029
  • 2
  • 36
  • 50
Ben Mosher
  • 13,251
  • 7
  • 69
  • 80

2 Answers2

6

The following lines...

// We don't want to toss padding on if we don't need to
if (*pkcs7 != kCCOptionECBMode) {
  if ((plainTextBufferSize % kChosenCipherBlockSize) == 0) {
*pkcs7 = 0x0000;
  } else {
    *pkcs7 = kCCOptionPKCS7Padding;
  }
}

... are the culprits of my issue. To solve it, I simply had to comment them out.

As far as I can tell, the encryption process was not padding on the encryption side, but was then still expecting padding on the decryption side, causing the decryption process to fail (which is generally what I was experiencing).

Always using kCCOptionPKCS7Padding to encrypt/decrypt is working for me so far, for strings that satisfy length % 16 == 0 and those that don't. And, again, this is a modification to the SecKeyWrapper class of the CryptoExercise example code. Not sure how this impacts those of you using CommonCrypto with home-rolled wrappers.

Ben Mosher
  • 13,251
  • 7
  • 69
  • 80
  • Note that any cryptography library that makes such a basic mistake should never ever be used. The padding should always be applied so you can see which bytes are padding and which bytes are plain data. The only reason ever to not pad a block cipher is when you know the message length by other means. – Maarten Bodewes Jun 14 '12 at 20:32
0

I too have encountered this issue using the CommonCrypto class but for ANY string with a length that was a multiple of 16.

My solution is a total hack since I have not yet found a real solution to the problem.

I pad my string with a space at the end if it is a multiple of 16. It works for my particular scenario since the extra space on the data does not affect the receipt of the data on the other side but I doubt it would work for anyone else's scenario.

Hopefully somebody smarter can point us in the right direction to a real solution.

TJ Asher
  • 737
  • 9
  • 27
  • Always leaving padding on is the solution. There is no way to detect if padding was added, unless your data does not end with a value 1..16 and you write your own crypto routines to check this (but this **should not** be done). – Maarten Bodewes Jun 14 '12 at 20:42