Triple DES compatibility between .Net and iPhone?

I need to encrypt a string on an iPhone and send it to .Net for decryption using Triple DES. I can encrypt / decrypt on iPhone and with .Net, but I get different results on both platforms.

I use the same code as AES encryption / decryption between .Net and iPhone in here

The only thing I changed .net is the encryption algorithm, so when it says AesCryptoServiceProvider, I set TripleDesServiceProvider

Like in .net, the only thing I changed is the encryption algorithm, so when it says kCCAlgorithmAES128, I add kCCAlgorithm3DES

What am I missing?

[UPDATE]

Thank you for your responses.

If I stay on the same platform, I can encrypt / decrypt without problems, but if I encrypt on iPhone and decrypt on .net, there will be a problem, because on each platform there are different results with the same inputs.

As Overslacked said, I think the problem is with the salt, but I could not find any sha or md5 documentation that the algorithm uses on each platform, or any parameter to configure it.

Here is the code that I actually use on the iPhone:

int main(int argc, char *argv[]){ NSString * _secret = @"hello"; NSString * _key = @"1234567890"; _out = [self doCipher:_secret key:_key context:kCCEncrypt]; NSLog(@"encrypted data in str: %@", _out); _outDecrypted = [StringEncryption doCipher:_out key:_key context:kCCDecrypt]; NSLog(@"decrypted data in str: %@", _outDecrypted); } + (NSString *)doCipher:(NSString *)sTextIn key:(NSString *)sKey context:(CCOperation)encryptOrDecrypt { NSMutableData * dTextIn; if (encryptOrDecrypt == kCCDecrypt) { dTextIn = [[[NSData alloc] base64DecodeString:sTextIn ]mutableCopy]; } else{ dTextIn = [[sTextIn dataUsingEncoding: NSASCIIStringEncoding]mutableCopy]; } NSMutableData * dKey = [[sKey dataUsingEncoding:NSASCIIStringEncoding]mutableCopy]; [dKey setLength:24]; uint8_t *bufferPtr1 = NULL; size_t bufferPtrSize1 = 0; size_t movedBytes1 = 0; uint8_t iv[kCCBlockSize3DES]; memset((void *) iv, 0x0, (size_t) sizeof(iv)); bufferPtrSize1 = ([sTextIn length] + kCCBlockSize3DES) & ~(kCCBlockSize3DES -1); bufferPtr1 = malloc(bufferPtrSize1 * sizeof(uint8_t)); memset((void *)bufferPtr1, 0x00, bufferPtrSize1); ccStatus = CCCrypt(encryptOrDecrypt, // CCOperation op kCCAlgorithm3DES, // CCAlgorithm alg kCCOptionPKCS7Padding, // CCOptions options [dKey bytes], // const void *key [dKey length], // size_t keyLength iv, // const void *iv [dTextIn bytes], // const void *dataIn [dTextIn length], // size_t dataInLength (void *)bufferPtr1, // void *dataOut bufferPtrSize1, // size_t dataOutAvailable &movedBytes1); // size_t *dataOutMoved NSString * sResult; if (encryptOrDecrypt == kCCDecrypt){ sResult = [[[ NSString alloc] initWithData:[NSData dataWithBytes:bufferPtr1 length:movedBytes1] encoding:NSASCIIStringEncoding] autorelease]; } else { NSData *dResult = [NSData dataWithBytes:bufferPtr1 length:movedBytes1]; sResult = [dResult base64EncodeData:dResult]; } return sResult; } 

Here is the code I use for .net

  class Program { static void Main(string[] args) { string key = "1234567890"; string secret = "hello"; string crypto = EncryptedString.EncryptString(secret, key); Console.WriteLine(crypto); secret = EncryptedString.DecryptString(crypto, key); Console.WriteLine(secret); Main(null); } } public class EncryptedString { public static string EncryptString(string plainSourceStringToEncrypt, string passPhrase) { //Set up the encryption objects using (TripleDESCryptoServiceProvider acsp = GetProvider(Encoding.ASCII.GetBytes(passPhrase))) { byte[] sourceBytes = Encoding.ASCII.GetBytes(plainSourceStringToEncrypt); ICryptoTransform ictE = acsp.CreateEncryptor(); //Set up stream to contain the encryption MemoryStream msS = new MemoryStream(); //Perform the encrpytion, storing output into the stream CryptoStream csS = new CryptoStream(msS, ictE, CryptoStreamMode.Write); csS.Write(sourceBytes, 0, sourceBytes.Length); csS.FlushFinalBlock(); //sourceBytes are now encrypted as an array of secure bytes byte[] encryptedBytes = msS.ToArray(); //.ToArray() is important, don't mess with the buffer String b64 = System.Text.ASCIIEncoding.ASCII.GetString(encryptedBytes); return Convert.ToBase64String(encryptedBytes); } } public static string DecryptString(string base64StringToDecrypt, string passphrase) { //Set up the encryption objects using (TripleDESCryptoServiceProvider acsp = GetProvider(Encoding.Default.GetBytes(passphrase))) { byte[] RawBytes = Convert.FromBase64String(base64StringToDecrypt); ICryptoTransform ictD = acsp.CreateDecryptor(); MemoryStream msD = new MemoryStream(RawBytes, 0, RawBytes.Length); CryptoStream csD = new CryptoStream(msD, ictD, CryptoStreamMode.Read); return (new StreamReader(csD)).ReadToEnd(); } } private static TripleDESCryptoServiceProvider GetProvider(byte[] key) { TripleDESCryptoServiceProvider result = new TripleDESCryptoServiceProvider(); result.Mode = CipherMode.CBC; result.Padding = PaddingMode.PKCS7; result.IV = new byte[] { 0, 0, 0, 0, 0, 0, 0, 0 }; result.Key = key; return result; } } 
+4
source share
3 answers

AES keys - 128, 192 or 256 bits, 192 - rarely.

Triple DSE is usually 112 bits, but may be 168 bits. Note that this is indicated in bits. Triple DES expects each byte to have a parity bit and therefore 7 data bits. Typically, Triple DES is used in compatibility mode (compatible with Single DES), performing one DES encoding, decoding and encoding one key, used for both encoding and decoding, k1, k2, k1. Thus, an 8-byte key * 7 bits * 2 = 112. Sometimes they decode, encode, decode, so this can also be a problem.

Enter the keys first. As you change from AES to 3DES, the key sizes will be different, this can be a problem. Also make sure that modes and IV are correct.

It is best to reset the key, IV (if any) and data in hexadecimal format on both sides of the crypto function and on both platforms. First make them match each other. Then the problem is base64 or any other manipulations.

+4
source

You need to match all your inputs, keys, salts and algorithms on both sides EXACTLY for this to work. AesCryptoServiceProvider and TripleDesServiceProvider will give different results, and kCCAlgorithmAES128 and kCCAlgorithm3DES will give different results.

0
source

Remember the random value that the .Net Crypto packet will add to your data before encryption, if I remember correctly, this is usually the first 16 bits of data.

0
source

All Articles