0

Could someone please help decrypt the base64 string generated by iOS code below into its C# equivalent.

I am trying to end up with "Meet me at the secret location at 8pm" within c#.

iOS generated the following encryption: qd+SGaij5KSBScuLs3TpJS/3Dew8fHTudcs/5MG7Q1kqcrZzZycMgTcQuEEEED5f

This iOS code successfully encrypts and decrypts data as required within XCode 6.

Thank you in advance for your help and support.

Darren

#import <CommonCrypto/CommonCryptor.h>

- (void)viewDidLoad {
    [super viewDidLoad];
    // Do any additional setup after loading the view, typically from a nib.

    NSString *sData = @"Meet me at the secret location at 8pm";
    NSString *sIv = @"4QesEr03HwE5H1C+ICw7SA==";
    NSString *sKey = @"ovA6siPkyM5Lb9oNcnxLz676K6JK6FrJKk4efEUWBzg=";

    NSData *dData = [sData dataUsingEncoding:NSUTF8StringEncoding];
    NSData *dIv = [sIv dataUsingEncoding:NSUTF8StringEncoding];
    NSData *dKey = [sKey dataUsingEncoding:NSUTF8StringEncoding];

    NSData *dEncrypt = [self doCipher:dData iv:dIv key:dKey context:kCCEncrypt];

    NSData *dDecrypt = [self doCipher:dEncrypt iv:dIv key:dKey context:kCCDecrypt];
    NSString *sDecrypt = [[NSString alloc] initWithData:dDecrypt encoding:NSUTF8StringEncoding];
    NSLog(@"Decrypted Data: %@",sDecrypt);
}

- (NSData *)doCipher:(NSData *)dataIn
              iv:(NSData *)iv
             key:(NSData *)symmetricKey
         context:(CCOperation)encryptOrDecrypt
{
    CCCryptorStatus ccStatus   = kCCSuccess;
    size_t          cryptBytes = 0;    // Number of bytes moved to buffer.
    NSMutableData  *dataOut    = [NSMutableData dataWithLength:dataIn.length + kCCBlockSizeAES128];

    ccStatus = CCCrypt( encryptOrDecrypt,
                   kCCAlgorithmAES128,
                   kCCOptionPKCS7Padding,
                   symmetricKey.bytes,
                   kCCKeySizeAES128,
                   iv.bytes,
                   dataIn.bytes,
                   dataIn.length,
                   dataOut.mutableBytes,
                   dataOut.length,
                   &cryptBytes);

    if (ccStatus != kCCSuccess) {
        NSLog(@"CCCrypt status: %d", ccStatus);
    }

    dataOut.length = cryptBytes;

    NSString *base64 = [dataOut base64EncodedStringWithOptions:0];
    NSLog(@"%@",base64);

    return dataOut;
}
TriCron
  • 141
  • 2
  • 11
  • 3
    Have you tried anything yet? Check out this question: http://stackoverflow.com/questions/19441640/how-can-i-encrypt-and-decrypt-using-aes-128-without-an-iv The answer to this question may get you close. – dodald Oct 07 '14 at 18:10
  • 6
    This question appears to be off-topic because SO is not a translation service. – Maarten Bodewes Oct 08 '14 at 01:00
  • Can someone please explain why this question is off topic? All of the 5x tags are relevant. I am simply trying to decrypt a 64 base string using C# generated by iOs CCCrypt function. Can someone please guide me. Thanks – TriCron Oct 08 '14 at 07:54
  • 1) *Did* you try to decode the Base64 string at all? 2) *Did* you try to use the Cryptography classes to decode the binary? The CCCrypt code is irrelevant - either it produces a standard format or it doesn't. – Panagiotis Kanavos Oct 08 '14 at 09:02
  • Thanks PK - 1) Yes I Convert.FromBase64String 2) I am looking into Oliver's answers below using AES and the link given... – TriCron Oct 08 '14 at 10:04

2 Answers2

3

The encrypted text on each platform now reads:

X/aopyVDDva/wJ3If/5i73JGjwth9eH45Opxaaswgb8Kx3ynh8BhBTFRrHT0/i3y

Here is the working C# code

NOTE: C# code extracted from https://github.com/Pakhee/Cross-platform-AES-encryption

namespace CryptoTest
{
    public partial class Default : System.Web.UI.Page
    {
        protected void Page_Load(object sender, EventArgs e)
        {
            string iv = "4QesEr03HwE5H1C+ICw7SA=="; // origional iv 128 bits
            string key = "ovA6siPkyM5Lb9oNcnxLz676K6JK6FrJKk4efEUWBzg="; // origional key 256 bits
            string message = "Meet me at the secret location at 8pm";

            CryptLib cryptLib = new CryptLib();
            string encryptedText = cryptLib.encrypt(message, key, iv);

            string originalMessage = cryptLib.decrypt(encryptedText, key, iv);
            Debug.WriteLine(originalMessage);
        }
    }

    public class CryptLib
    {
        UTF8Encoding _enc;
        RijndaelManaged _rcipher;
        byte[] _key, _pwd, _ivBytes, _iv;

        private enum EncryptMode { ENCRYPT, DECRYPT };

        public CryptLib()
        {
            _enc = new UTF8Encoding();
            _rcipher = new RijndaelManaged();
            _rcipher.Mode = CipherMode.CBC;
            _rcipher.Padding = PaddingMode.PKCS7;
            _rcipher.KeySize = 256;
            _rcipher.BlockSize = 128;
            _key = new byte[32];
            _iv = new byte[_rcipher.BlockSize / 8]; //128 bit / 8 = 16 bytes
            _ivBytes = new byte[16];
        }

        private String encryptDecrypt(string _inputText, string _encryptionKey, EncryptMode _mode, string _initVector)
        {
            string _out = "";// output string
            _pwd = Encoding.UTF8.GetBytes(_encryptionKey);
            _ivBytes = Encoding.UTF8.GetBytes(_initVector);
            int len = _pwd.Length;
            if (len > _key.Length)
            {
                len = _key.Length;
            }
            int ivLenth = _ivBytes.Length;
            if (ivLenth > _iv.Length)
            {
                ivLenth = _iv.Length;
            }
            Array.Copy(_pwd, _key, len);
            Array.Copy(_ivBytes, _iv, ivLenth);
            _rcipher.Key = _key;
            _rcipher.IV = _iv;
            if (_mode.Equals(EncryptMode.ENCRYPT))
            {
                //encrypt
                byte[] plainText = _rcipher.CreateEncryptor().TransformFinalBlock(_enc.GetBytes(_inputText), 0, _inputText.Length);
                _out = Convert.ToBase64String(plainText);
            }
            if (_mode.Equals(EncryptMode.DECRYPT))
            {
                //decrypt
                byte[] plainText = _rcipher.CreateDecryptor().TransformFinalBlock(Convert.FromBase64String(_inputText), 0, Convert.FromBase64String(_inputText).Length);
                _out = _enc.GetString(plainText);
            }
            _rcipher.Dispose();
            return _out;// return encrypted/decrypted string
        }

        public string encrypt(string _plainText, string _key, string _initVector)
        {
            return encryptDecrypt(_plainText, _key, EncryptMode.ENCRYPT, _initVector);
        }

        public string decrypt(string _encryptedText, string _key, string _initVector)
        {
            return encryptDecrypt(_encryptedText, _key, EncryptMode.DECRYPT, _initVector);
        }
    }
}

Here is the working iOS code

    #import <CommonCrypto/CommonCryptor.h>

    - (void)viewDidLoad {
        [super viewDidLoad];
        // Do any additional setup after loading the view, typically from a nib.

        NSString *sData = @"Meet me at the secret location at 8pm";
        NSString *sIv = @"4QesEr03HwE5H1C+ICw7SA==";
        NSString *sKey = @"ovA6siPkyM5Lb9oNcnxLz676K6JK6FrJKk4efEUWBzg=";

        NSData *dData = [sData dataUsingEncoding:NSUTF8StringEncoding];

        NSData *dEncrypt = [self doCipher:dData key:sKey iv:sIv context:kCCEncrypt];
        NSData *base64 = [dEncrypt base64EncodedDataWithOptions:0];
        NSString *sBase64 = [[NSString alloc] initWithData:base64 encoding:NSUTF8StringEncoding];
        NSLog(@"Base64 String: %@",sBase64);

        NSData *dDecrypt= [self decrypt:dEncrypt key:sKey iv:sIv];
        NSString *sDecrypt = [[NSString alloc] initWithData:dDecrypt encoding:NSUTF8StringEncoding];
        NSLog(@"Decrypted Data: %@",sDecrypt);
    }

    - (NSData *)doCipher:(NSData *)plainText
                     key:(NSString *)key
                      iv:(NSString *)iv
                 context:(CCOperation)encryptOrDecrypt
    {
        NSUInteger dataLength = [plainText length];

        size_t buffSize = dataLength + kCCBlockSizeAES128;
        void *buff = malloc(buffSize);

        size_t numBytesEncrypted = 0;

        NSData *dIv = [iv dataUsingEncoding:NSUTF8StringEncoding];
        NSData *dKey = [key dataUsingEncoding:NSUTF8StringEncoding];

        CCCryptorStatus status = CCCrypt(encryptOrDecrypt,
                                         kCCAlgorithmAES128,
                                         kCCOptionPKCS7Padding,
                                         dKey.bytes, kCCKeySizeAES256,
                                         dIv.bytes,
                                         [plainText bytes], [plainText length],
                                         buff, buffSize,
                                         &numBytesEncrypted);
        if (status == kCCSuccess) {
            return [NSData dataWithBytesNoCopy:buff length:numBytesEncrypted];
        }

        free(buff);
        return nil;
    }
TriCron
  • 141
  • 2
  • 11
1

The given base64 string qd+SGaij5KSBScuLs3TpJS/3Dew8fHTudcs/5MG7Q1kqcrZzZycMgTcQuEEEED5f is a two way pack.

First it has to be base64 decoded (which is easy in C#) and afterwards it has to be decrypted by using the correct algorithm. From the given parameters it hopefully uses the AES or Rijndael algorithm (example code here) where you have to put in the base64 decoded bytes, the key and the IV.

After that you hopefully get out your desired data.

So i wrote an example on myself and i'm able to encrypt and decrypt the specified message with C#.

But the retrieved encrypted message differs from the iOS generated message:

Your iOS message: qd+SGaij5KSBScuLs3TpJS/3Dew8fHTudcs/5MG7Q1kqcrZzZycMgTcQuEEEED5f My C# message: wC2dn+QVhOhf+NqZVskopLdh2XDAdG3SmczrKF+TjQsGfxu07BEhRdiDqkbGY80O

I just made some little changes and dit a little deeper look. One thing i see is that you say in your iOS code that the key has a length of 256 bit. But the key you are providing has only a length of 128 bit. It seems that C# in that case simply switches back to 128 bit key length (cause changing the key size in the code below doesn't change the encrypted bytes). But maybe the CCCrypt in iOS makes something different. So either adopt in your iOS code the key size or provider a 256 bit key and than compare the results of iOS and C# again.

Example:

var message = @"Meet me at the secret location at 8pm";
var iv = @"4QesEr03HwE5H1C+ICw7SA==";
var key = @"ovA6siPkyM5Lb9oNcnxLz676K6JK6FrJKk4efEUWBzg=";

byte[] encryptedBytes;

using (var aesCryptoProvider = new AesCryptoServiceProvider())
{
    aesCryptoProvider.BlockSize = 128;
    aesCryptoProvider.KeySize = 256;
    aesCryptoProvider.IV = Convert.FromBase64String(iv);
    aesCryptoProvider.Key = Convert.FromBase64String(key);
    aesCryptoProvider.Padding = PaddingMode.PKCS7;
    aesCryptoProvider.Mode = CipherMode.CBC;

    using (var encryptor = aesCryptoProvider.CreateEncryptor())
    using (var memoryStream = new MemoryStream())
    using (var cryptoStream = new CryptoStream(memoryStream, encryptor, CryptoStreamMode.Write))
    using (var streamWriter = new StreamWriter(cryptoStream, Encoding.UTF8))
    {
        streamWriter.Write(message);
        streamWriter.Close();
        encryptedBytes = memoryStream.ToArray();
    }
}

var encryptedMessage = Convert.ToBase64String(encryptedBytes);
Console.WriteLine(encryptedMessage);

using (var aesCryptoProvider = new AesCryptoServiceProvider())
{
    aesCryptoProvider.BlockSize = 128;
    aesCryptoProvider.KeySize = 256;
    aesCryptoProvider.IV = Convert.FromBase64String(iv);
    aesCryptoProvider.Key = Convert.FromBase64String(key);
    aesCryptoProvider.Padding = PaddingMode.PKCS7;
    aesCryptoProvider.Mode = CipherMode.CBC;

    using (var decryptor = aesCryptoProvider.CreateDecryptor())
    using (var memoryStream = new MemoryStream(Convert.FromBase64String(encryptedMessage)))
    using (var cryptoStream = new CryptoStream(memoryStream, decryptor, CryptoStreamMode.Read))
    using (var streamReader = new StreamReader(cryptoStream, Encoding.UTF8))
    {
        Console.WriteLine(streamReader.ReadToEnd());
    }
}
Community
  • 1
  • 1
Oliver
  • 43,366
  • 8
  • 94
  • 151
  • Yes, I use Convert.FromBase64String. The encryted text sent is AES128 Algorithum, PKCS7 Padding, Keysize 256 but I can't seem to get any of the linked examples to work! I am trying to incorporate this into all of these methods without success. – TriCron Oct 08 '14 at 10:27
  • Excellent code. I can see where your coming from! Is there anything I can do in my iOs code to match your message? I feel we're so close but just missing something!!! – TriCron Oct 08 '14 at 14:01
  • I accepted Oliver's quality code because it shows an excellent example of encoding / decoding for C# using AES but it DID NOT solve my initial question. The complete cross platform working version for both Objective C and C# is answered below. – TriCron Oct 10 '14 at 09:02