views:

2881

answers:

6

Hi All,

I am building a iPhone app which uses c# web services. My c# web services takes user details and validates against my DB and returns xml files.

So Now the issue is how to encrypt user details(username and password are 10chars each) in objective c and decrypt in C#.

I am very new to cryptography, which method is the best. will it be possible to encrypt in Objective c and Decrypt in C#.

thanks..

A: 

Your question is very vague, but in short; yes, it is possible. You will need to figure out what the expectations of your cryptography are (high security or high speed?) and then weigh the benefits of various algorthms and their implementation difficulties in Objective-C and C#.

McWafflestix
+2  A: 

On the assumption that you're encrypting this information in order to protect it over the network, the best solution is to connect over SSL. This will address the problem without creating new complexities in the code. SSL handling is generally available in both .NET and Cocoa.

Is there some other reason that you're trying to encrypt this data?

Rob Napier
SSL (actually, TLS) is definitely the way to go. People who are completely new to cryptography shouldn't try to implement an encryption system in production code. It's too easy to do it wrong and end up with a false sense of security. TLS is a standard, cross-platform way to encrypt web traffic, and the OS X and .NET implementations are likely to have been verified by highly competent people.
A: 

The following is from the The CSharp Cookbook. It is about as straight forwand an example as exists. You would of course have to port the encrypt portion to Objective C, but so long as you used the same Key, it should generate the same result.

You need to use Rijndael cipher which is available here in ObjC compatible code

 public static void EncDecString()
        {
            string encryptedString = CryptoString.Encrypt("MyPassword");
            Console.WriteLine("encryptedString: " + encryptedString);
            // get the key and IV used so you can decrypt it later
            byte [] key = CryptoString.Key;
            byte [] IV = CryptoString.IV;

            CryptoString.Key = key;
            CryptoString.IV = IV;
            string decryptedString = CryptoString.Decrypt(encryptedString);
            Console.WriteLine("decryptedString: " + decryptedString);

        }

        public sealed class CryptoString
        {
            private CryptoString() {}

            private static byte[] savedKey = null;
            private static byte[] savedIV = null;

            public static byte[] Key
            {
                get { return savedKey; }
                set { savedKey = value; }
            }

            public static byte[] IV
            {
                get { return savedIV; }
                set { savedIV = value; }
            }

            private static void RdGenerateSecretKey(RijndaelManaged rdProvider)
            {
                if (savedKey == null)
                {
                    rdProvider.KeySize = 256;
                    rdProvider.GenerateKey();
                    savedKey = rdProvider.Key;
                }
            }

            private static void RdGenerateSecretInitVector(RijndaelManaged rdProvider)
            {
                if (savedIV == null)
                {
                    rdProvider.GenerateIV();
                    savedIV = rdProvider.IV;
                }
            }

            public static string Encrypt(string originalStr)
            {
                // Encode data string to be stored in memory
                byte[] originalStrAsBytes = Encoding.ASCII.GetBytes(originalStr);
                byte[] originalBytes = {};

                // Create MemoryStream to contain output
                MemoryStream memStream = new MemoryStream(originalStrAsBytes.Length);

                RijndaelManaged rijndael = new RijndaelManaged();

                // Generate and save secret key and init vector
                RdGenerateSecretKey(rijndael);
                RdGenerateSecretInitVector(rijndael);

                if (savedKey == null || savedIV == null)
                {
                    throw (new NullReferenceException(
                        "savedKey and savedIV must be non-null."));
                }

                // Create encryptor, and stream objects
                ICryptoTransform rdTransform = 
                    rijndael.CreateEncryptor((byte[])savedKey.Clone(),
                                            (byte[])savedIV.Clone());
                CryptoStream cryptoStream = new CryptoStream(memStream, rdTransform, 
                    CryptoStreamMode.Write);

                // Write encrypted data to the MemoryStream
                cryptoStream.Write(originalStrAsBytes, 0, originalStrAsBytes.Length);
                cryptoStream.FlushFinalBlock();
                originalBytes = memStream.ToArray();

                // Release all resources
                memStream.Close();
                cryptoStream.Close();
                rdTransform.Dispose();
                rijndael.Clear();

                // Convert encrypted string
                string encryptedStr = Convert.ToBase64String(originalBytes);
                return (encryptedStr);
            }

            public static string Decrypt(string encryptedStr)
            {
                // Unconvert encrypted string
                byte[] encryptedStrAsBytes = Convert.FromBase64String(encryptedStr);
                byte[] initialText = new Byte[encryptedStrAsBytes.Length];

                RijndaelManaged rijndael = new RijndaelManaged();
                MemoryStream memStream = new MemoryStream(encryptedStrAsBytes);

                if (savedKey == null || savedIV == null)
                {
                    throw (new NullReferenceException(
                        "savedKey and savedIV must be non-null."));
                }

                // Create decryptor, and stream objects
                ICryptoTransform rdTransform = 
                    rijndael.CreateDecryptor((byte[])savedKey.Clone(), 
                                            (byte[])savedIV.Clone());
                CryptoStream cryptoStream = new CryptoStream(memStream, rdTransform, 
                    CryptoStreamMode.Read);

                // Read in decrypted string as a byte[]
                cryptoStream.Read(initialText, 0, initialText.Length);

                // Release all resources
                memStream.Close();
                cryptoStream.Close();
                rdTransform.Dispose();
                rijndael.Clear();

                // Convert byte[] to string
                string decryptedStr = Encoding.ASCII.GetString(initialText);
                return (decryptedStr);
            }
        }

I can't speak regarding the Objective C implementation of Rijndael cipher, but I have used this(C#) code for the basis of some production work and it has worked wonderfully.

Serapth
A: 

I don't know Objective C, but for the C# decryption, look into the various CryptoServiceProviders in System.Security.Cryptography.

Here is one example I wrote using TripleDES:

public class TripleDES
{
 private byte[] mbKey;
 private byte[] mbIV;
 private TripleDESCryptoServiceProvider tdProvider = new TripleDESCryptoServiceProvider();
 private UTF8Encoding UTEncode = new UTF8Encoding();

 // Key:  **YOUR KEY**
 // Project IV:  **YOUR IV**
 public TripleDES(string strKey, string strIV)
 {
  mbKey = UTEncode.GetBytes(strKey);
  mbIV = UTEncode.GetBytes(strIV);  
 }

 public TripleDES()
 {
  //
  // TODO: Add constructor logic here
  //
 }


 public string EncryptToString(string strInput)
 {   
  return Convert.ToBase64String(this.EncryptToBytes(strInput));   
 }

 public byte[] EncryptToBytes(string strInput)
 {
  byte[] bInput = UTEncode.GetBytes(strInput);
  byte[] bOutput = ProcessInput(bInput, tdProvider.CreateEncryptor(mbKey, mbIV));
  return bOutput;
 }

 public string DecryptToString(string strInput)
 {
  return UTEncode.GetString(DecryptToBytes(strInput));
 }

 public byte[] DecryptToBytes(string strInput)
 {
  byte[] bInput = Convert.FromBase64String(strInput);
  byte[] bOutput = ProcessInput(bInput, tdProvider.CreateDecryptor(mbKey, mbIV));
  return bOutput;
 }

 private byte[] ProcessInput(byte[] input, ICryptoTransform ctProcessor)
 {
  MemoryStream memStream = new MemoryStream();
  CryptoStream crpStream = new CryptoStream(memStream, ctProcessor, CryptoStreamMode.Write);

  crpStream.Write(input, 0, input.Length);
  crpStream.FlushFinalBlock();

  memStream.Position = 0;

  byte[] output;
  output = new byte[memStream.Length];

  memStream.Read(output, 0, output.Length);

  memStream.Close();
  crpStream.Close();

  return output;
 }
}

}

Ian Jacobs
+2  A: 

Thanks for the rapid replies. I appreciate your help. I found a blog which explains my problem. Here is the link for it.

http://dotmac.rationalmind.net/2009/02/aes-interoperability-between-net-and-iphone/

I am implementing it now. I will let you know the status soon.

Thanks a lot..
Happy coding..

nbojja
its working fine...
nbojja
+1  A: 

Check out this Cryptographer class to encrypt and decrypt: http://developergeeks.com/article/24/how-to-do-string-encryption-and-decryption-in-c-sharp-dot-net