Triple DES decryption in iOS

I am currently using the following to decrypt Triple DES on iOS:

NSString* plainText = @"My Text"; NSString* keyText = @"cf6f1ed3bf0a156e"; NSData *plainData = [plainText dataUsingEncoding:NSUTF8StringEncoding]; NSData *keyData = [keyText dataUsingEncoding:NSUTF8StringEncoding]; size_t bufferSize = plainData.length + kCCBlockSize3DES; NSMutableData *cypherData = [NSMutableData dataWithLength:bufferSize]; size_t movedBytes = 0; CCCryptorStatus ccStatus; ccStatus = CCCrypt(kCCDecrypt, kCCAlgorithm3DES, kCCOptionECBMode, keyData.bytes, kCCBlockSize3DES, NULL, plainData.bytes, plainData.length, cypherData.mutableBytes, cypherData.length, &movedBytes); cypherData.length = movedBytes; if( ccStatus == kCCSuccess ) { NSLog(@"Data: %@",cypherData); NSLog(@"Data encoded string: %@",[NSString stringWithUTF8String:[cypherData bytes]]); NSLog(@"Data encoded: %@",[[NSString alloc] initWithData:cypherData encoding:NSUTF8StringEncoding]); } else { NSLog(@"Failed DES decrypt ..."); return nil; } 

However, I keep getting the following on the console:

Data: String encoded according to data: (null) Data encoded: (null)

Any ideas as to why this is happening? Can anyone see any possible problems with this code?

+6
source share
2 answers

Change the error message to:

 NSLog(@"Failed DES decrypt, status: %d", ccStatus); 

You will see the status -4300 and look at that in CommonCryptoError.h to find:
kCCParamError = -4300
@constant kCCParamError Illegal parameter value.

Status errors can be your friend if you do not ignore them. πŸ˜€

  • You specify 3DES, which should have a key length of 24 bytes, you supply 16 bytes. You should probably upgrade to kCCAlgorithmDES and kCCBlockSizeDES (see next paragraph). But the key can be encoded in hexadecimal and must be decoded up to 8 bytes.

  • In the call, the 5th parameter is size_t keyLength , but you send kCCBlockSize3DES , which is 8 bytes. The key and block sizes are not necessarily the same size.

  • By default, there is no indentation, and this means that the data that must be encrypted must be an exact multiple of the block size (8 bytes). Either add another byte to the input, or specify kCCOptionPKCS7Padding as an option.

  • In the general case, it is impossible to express the encryption result directly in the character string, in particular, not in the UTF-8 representation - there are byte values ​​that are not displayed. For this reason, if you need character encoding, then Base64 or hexadecimal are usually used.

Note. It is possible for a key to be 16-byte, and two-element 3DES is needed, in which case duplicate and add the first 8 bytes to the key to make it a 24-byte 3DES key. You need to understand the algorithm, key and parameters.

This sample code works, but is neither optimal nor safe, but the starting point for you:

You can change this to 3DES by setting a 24-byte key and changing kCCAlgorithmDES to kCCAlgorithm3DES and kCCKeySizeDES to kCCKeySize3DES

 NSString* plainText = @"My Text-"; NSString* keyText = @"cf6f1ed3"; NSData *plainData = [plainText dataUsingEncoding:NSUTF8StringEncoding]; NSData *keyData = [keyText dataUsingEncoding:NSUTF8StringEncoding]; size_t bufferSize = plainData.length + kCCBlockSizeDES; NSMutableData *cypherData = [NSMutableData dataWithLength:bufferSize]; size_t movedBytes = 0; CCCryptorStatus ccStatus; ccStatus = CCCrypt(kCCDecrypt, kCCAlgorithmDES, kCCOptionECBMode, keyData.bytes, kCCKeySizeDES, NULL, plainData.bytes, plainData.length, cypherData.mutableBytes, cypherData.length, &movedBytes); cypherData.length = movedBytes; if( ccStatus == kCCSuccess ) { NSLog(@"Data: %@"encoded,cypherData); } else { NSLog(@"Failed DES decrypt, status: %d", ccStatus); } 

But for security reasons, use AES with a random IV, if possible use RNCryptor , it will take care of all the unpleasant but important details for you.

+2
source

The key is 16 bytes long. 3DES takes a 24-byte key (thanks to Zaph for the fix, also noting that you only read 8 bytes). This may not cause this error, but means that the key is not what you think.

A series of hexadecimal digits in a string are just UTF-8 values. "00" is not 0x00, 0x00. This is 0x30, 0x30.

The reason you get (null) is this:

 NSLog(@"Data encoded string: %@",[NSString stringWithUTF8String:[cypherData bytes]]); 

Cryptographic output is unlikely to be the legitimate string of UTF-8. If you want to encode random data as a string, you need an encoding such as hexadecimal encoding or Base64 encoding. Base64 is built-in, and you can use [NSData base64EncodedStringWithOptions:] to encode it.

+3
source

Source: https://habr.com/ru/post/1013304/


All Articles