Question

I am developing a ios app, using C# in server side. I need to use 3DES encryption to encrypt the password.

In both code:

key = "FC13573F412EAA1BA8E34791C06504C1429C5BCEB94DB111";
plainText = "123456"; // (or CryptString = "123456")

now C# result is correct, buy i never get the same result in objective-c, please help

following is C# code:

public bool Crypt3DESToBase64(string CryptString, string Key, out string DecryptString)
    {
        DecryptString = "";
        try
        {
            // encode to bytes
            byte[] KEY = HexStringToByteArray(Key);
            byte[] CRYPTSTRING = System.Text.Encoding.UTF8.GetBytes(CryptString);

            //set iv and key
            byte[] tmpiv = { 1, 2, 3, 4, 5, 6, 7, 8 };
            byte[] tmpkey = { 0, 1, 2, 3, 4, 5, 6, 7, 0, 1, 2, 3, 4, 5, 6, 7, 0, 1, 2, 3, 4, 5, 6, 7 };

            for (int ii = 0; ii < 24; ii++)
            {
                tmpkey[ii] = KEY[ii];
            }
            TripleDESCryptoServiceProvider dsp = new TripleDESCryptoServiceProvider();
            dsp.Mode = System.Security.Cryptography.CipherMode.CBC;
            dsp.Padding = System.Security.Cryptography.PaddingMode.PKCS7;

            ICryptoTransform tridesencrypt = dsp.CreateEncryptor(tmpkey, tmpiv);

            DecryptString = Convert.ToBase64String(tridesencrypt.TransformFinalBlock(CRYPTSTRING, 0, CRYPTSTRING.Length));

            dsp.Clear();

            return true;
        }
        catch (Exception e)
        {
            return false;
        }
    }

    public static byte[] HexStringToByteArray(string s)
    {
        Byte[] buf = new byte[s.Length / 2];
        for (int i = 0; i < buf.Length; i++)
        {
            buf[i] = (byte)(chr2hex(s.Substring(i * 2, 1)) * 0x10 + chr2hex(s.Substring(i * 2 + 1, 1)));
        }
        return buf;
    }

    private static byte chr2hex(string chr)
    {
        switch (chr)
        {
            case "0":
                return 0x00;
            case "1":
                return 0x01;
            case "2":
                return 0x02;
            case "3":
                return 0x03;
            case "4":
                return 0x04;
            case "5":
                return 0x05;
            case "6":
                return 0x06;
            case "7":
                return 0x07;
            case "8":
                return 0x08;
            case "9":
                return 0x09;
            case "A":
                return 0x0a;
            case "B":
                return 0x0b;
            case "C":
                return 0x0c;
            case "D":
                return 0x0d;
            case "E":
                return 0x0e;
            case "F":
                return 0x0f;
        }
        return 0x00;
    }

and following is objective-c code:

#define gIv  @"12345678"
#define kSecrectKeyLength 24
+ (NSString*)encrypt:(NSString*)plainText withKey:(NSString*)key{
    uint8_t keyByte[kSecrectKeyLength];
    NSMutableData *keyData = [[NSMutableData alloc] init];
    int i;
    for (i=0; i < [key length] / 2; i++) {
        NSString *tempNumber = [key substringWithRange: NSMakeRange(i * 2, 2)];
        NSScanner *scanner=[NSScanner scannerWithString:tempNumber];
        unsigned int temp;
        [scanner scanHexInt:&temp];
        Byte B = (Byte)(0xFF & temp);
        keyByte[i] = B;
    }

    NSData* data = [plainText dataUsingEncoding:NSUTF8StringEncoding];
    size_t plainTextBufferSize = [data length];
    const void *vplainText = (const void *)[data bytes];

    CCCryptorStatus ccStatus;
    uint8_t *bufferPtr = NULL;
    size_t bufferPtrSize = 0;
    size_t movedBytes = 0;

    bufferPtrSize = (plainTextBufferSize + kCCBlockSize3DES) & ~(kCCBlockSize3DES - 1);
    bufferPtr = malloc( bufferPtrSize * sizeof(uint8_t));
    memset((void *)bufferPtr, 0x0, bufferPtrSize);

    const void *vkey = (const void *) keyByte;
    const void *vinitVec = (const void *) [gIv UTF8String];

    ccStatus = CCCrypt(kCCEncrypt,
                   kCCAlgorithm3DES,
                   kCCOptionPKCS7Padding,
                   vkey,
                   kCCKeySize3DES,
                   vinitVec,
                   vplainText,
                   plainTextBufferSize,
                   (void *)bufferPtr,
                   bufferPtrSize,
                   &movedBytes);

    NSData *myData = [NSData dataWithBytes:(const void *)bufferPtr length:(NSUInteger)movedBytes];
    NSString *result = [GTMBase64 stringByEncodingData:myData];

    NSLog(@"result=%@",result);

    return result;
}

please help, thanks very much!

Was it helpful?

Solution

Your IV is different. In your C# code you are using bytes 1,2 etc. but in your objective-C you are using the byte value of characters '1', '2' (which are bytes 49, 50 etc).

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top