0

I have the following code which encrypts/decrypts data for me in java

I need to encrypt/decrypt data in C# on a windows phone(8) device and same data should be able to decrypt/encrypt using this java code.

what would be the equivalent code of this java code in C# in Windows Phone??

public class AESencrp {
private static final String ALGO = "AES";
private static final byte[] keyValue = new byte[] { 'S', 'D', 'P', 'i', 'b', 'm', 'B','H', 'A', 'R', 'T','I', 'P', 'K', 'e', 'y' };

public static String encrypt(String Data) throws Exception {
    System.out.println(".............Encryption start............");
    Key key = generateKey();
    System.out.println("Key : " + key);
    Cipher c = Cipher.getInstance(ALGO);
    c.init(Cipher.ENCRYPT_MODE, key);
    byte[] encVal = c.doFinal(Data.getBytes());
    //System.out.println("encVal in byte[] : " + encVal);
    String encryptedValue = new BASE64Encoder().encode(encVal);
    System.out.println("encryptedValue byusing base64 : " + encryptedValue);
    System.out.println("..............Encryption End............");
    return encryptedValue;
}

public static String decrypt(String encryptedData) throws Exception {
    //final byte[] keyValue1 =  new byte[] { 'T', 'h', 'e', 'B', 'e', 's', 't','S', 'e', 'c', 'r','e', 't', 'K', 'e', 'y' };
    System.out.println("");
    System.out.println("");
    System.out.println(".............Decryption start............");
    Key key = generateKey();
    //Key key = new SecretKeySpec(keyValue1, ALGO);
    //System.out.println("Key : " + key);
    Cipher c = Cipher.getInstance(ALGO);
    c.init(Cipher.DECRYPT_MODE, key);
    byte[] decordedValue = new BASE64Decoder().decodeBuffer(encryptedData);
    //System.out.println("decryptedValue byusing base64 : " + decordedValue);
    byte[] decValue = c.doFinal(decordedValue);
   // System.out.println("decValue in byte[] : " + decValue);
    String decryptedValue = new String(decValue);
    System.out.println("String representation of decrypted value: " + decryptedValue);
    System.out.println(".............Decryption End............");
    return decryptedValue;
}
private static Key generateKey() throws Exception {
    Key key = new SecretKeySpec(keyValue, ALGO);
    System.out.println("key is " + keyValue  );
    return key;
}


public static void main(String[] args) throws Exception {
    String password = "encrypt_this";
    String passwordEnc = AESencrp.encrypt(password);
    String passwordDec = AESencrp.decrypt(passwordEnc);
    System.out.println("");System.out.println("");
    System.out.println("Plain Text : " + password);
    System.out.println("Encrypted Text : " + passwordEnc);
    System.out.println("Decrypted Text : " + passwordDec);
   }
}

It seems in this code I only need one piece of string which is -

private static final byte[] keyValue = new byte[] { 'S', 'D', 'P', 'i', 'b', 'm', 'B','H', 'A', 'R', 'T','I', 'P', 'K', 'e', 'y' };

to encrypt the data.

Rest everything is done automatically.

I have seen some solution on this link

http://robtiffany.com/dont-forget-to-encrypt-your-windows-phone-7-data/

But it requires SALT value (I dont really know what it is???)

also, the site says that one can skip some steps and use pre-created Key and Initialization Vector.

any help in this matter??

kshitijgandhi
  • 1,532
  • 1
  • 16
  • 28

2 Answers2

1

You can use the native libraries to encrypt your string the same way your Java code does. You just need to set the IV(Salt) to an empty array with the needed size of 16.

I have created a class to do the encryption/decryption and converting (byte[] to string and reverse).

I hope you don't mind the german comments. Just had no time to translate them yet

static class AesClass
{
    public static byte[] EncryptStringToBytes(string plainText, byte[] Key)
    {
        // Überprüfe, ob alle Parameter gefüllt sind
        if ((String.IsNullOrEmpty(plainText) || (Key.Length <= 0 || Key == null)))
            throw new Exception("Both values mustn't be null or empty");

        byte[] encrypted;

        // Erstelle ein Objekt der Klasse Aes und
        // belege den Schlüssel, sowie den Salt (Initalisierungsvektor) mit den Parametern
        using (AesManaged aesAlgo = new AesManaged())
        {
            aesAlgo.Key = Key;
            aesAlgo.IV = new byte[16];
            //Verschlüsseler zur Umwandlung erstellen
            ICryptoTransform encryptor = aesAlgo.CreateEncryptor();

            // Erstelle Streams, welche für die Verschlüsselung genutzt werden
            using (MemoryStream msEncrypt = new MemoryStream())
            {
                using (CryptoStream csEncrypt = new CryptoStream(msEncrypt, encryptor, CryptoStreamMode.Write))
                {
                    using (StreamWriter swEncrypt = new StreamWriter(csEncrypt))
                    {
                        //Schreibe die Daten in den Stream
                        swEncrypt.Write(plainText);
                    }
                    encrypted = msEncrypt.ToArray();
                }
            }
        }
        // Gebe die verschlüsselten Bytes aus dem Stream zurück
        return encrypted;
    }

    public static string DecryptStringFromBytes(byte[] cipherText, byte[] Key)
    {
        //Überprüfe, ob alle Parameter gefüllt sind
        if (((cipherText.Length <= 0 || cipherText == null) || (Key.Length <= 0 || Key == null)))
            throw new Exception("Both values mustn't be null or empty");

        //Erstelle eine Variable, in welcher später der entschlüsselte Text gespeichert wird
        string plaintext = null;

        try
        {
            // Erstelle ein Objekt von AES mit begrenzter Gültigkeit und
            // weiße dem Schlüssel (Key) und Salt (IV), die als Parameter übergebenen Werte zu
            using (AesManaged aesAlgo = new AesManaged())
            {
                aesAlgo.Key = Key;
                aesAlgo.IV = new byte[16];

                // Erstelle einen Entschlüsseler, welcher den Schlüssel und Salt nutzt,
                // um den ByteArray-Stream zu verändern (entschlüsseln)
                ICryptoTransform decryptor = aesAlgo.CreateDecryptor(aesAlgo.Key, aesAlgo.IV);

                // Erstelle Stream, welche zu Entschlüsselung genutzt werden
                // Ein Stream ist eine Darstellung einer geordneten Abfolge von Bytes
                using (MemoryStream msDecrypt = new MemoryStream(cipherText))
                {
                    using (CryptoStream csDecrypt = new CryptoStream(msDecrypt, decryptor, CryptoStreamMode.Read))
                    {
                        using (StreamReader srDecrypt = new StreamReader(csDecrypt))
                        {
                            // Lese die entschlüsselten Bytes aus dem entschlüsselten Stream
                            // und füge sie komplett in die Variable, welche den entschlüsselte Text speichert.
                            plaintext = srDecrypt.ReadToEnd();
                        }
                    }
                }
            }

        }
        catch (Exception ex)
        {
            //MessageBox.Show(ex.Message + "\r\nMöglichweise passt der aktuelle Schlüssel oder Salt nicht mit jenem überein, welcher die Daten verschlüsselt hat");
            return null;
        }
        return plaintext;
    }

    ///
    /// Wandle den String in ein ByteArray mit Base64
    /// Base64 ist ein Verfahren zur Kodierung von Binärdaten
    ///
    public static byte[] AESStringToByteArray(string cipher)
    {
        byte[] encByteArray = Convert.FromBase64String(cipher);
        return encByteArray;
    }

    ///
    /// Wandelt das übergebene Bytearray in einen menschenlesbaren String.
    /// Base64 ist ein Verfahren um Binärdaten zu kodieren
    ///
    ///Die Binärdaten
    /// Den gewandelten String
    public static string AESByteArrayToString(byte[] arr)
    {
        string base64 = Convert.ToBase64String(arr);
        return base64;
    }
}

You can use the class in the following way (I guess you call in on a page):

private static byte[] keyValue = new byte[] { (int)'S', (int)'D', (int)'P', (int)'i', (int)'b', (int)'m', (int)'B', (int)'H', 
        (int)'A', (int)'R', (int)'T', (int)'I', (int)'P', (int)'K', (int)'e', (int)'y' };


private void Button_Encrypt_Click(object sender, RoutedEventArgs e)
{
    byte[] Data = AesClass.EncryptStringToBytes(TextBox_UnecryptedString.Text, keyValue);
    TextBox_EncryptedString.Text = AesClass.AESByteArrayToString(Data);
}

private void Button_Decrypt_Click(object sender, RoutedEventArgs e)
{
    byte[] cipherText = AesClass.AESStringToByteArray(TextBox_EncryptedString.Text); 
    TextBox_DecryptedString.Text = AesClass.DecryptStringFromBytes(cipherText, keyValue);
}

Result:

Java:

Java Result

C#/WP7:

WP7 Result

Daniel Abou Chleih
  • 2,440
  • 2
  • 19
  • 31
0

AES encryption can be done on C# as well as on Java, but there are some differences.

Sadly now I remember it quite poor, but native wp7 cryptography had some problems with ciphers. I've written about it here and here. You'd better download BouncyCastle.Crypto library for wp7.


after downloading that library, try this:

        private char[] keyValue = new char[] { 'S', 'D', 'P', 'i', 'b', 'm', 'B', 'H', 'A', 'R', 'T', 'I', 'P', 'K', 'e', 'y' };
        private char[] keyValue1 = new char[] { 'T', 'h', 'e', 'B', 'e', 's', 't', 'S', 'e', 'c', 'r', 'e', 't', 'K', 'e', 'y' };
        private byte[] key;
        private byte[] key1;

        public AESPage()
        {
            InitializeComponent();
        }

        private void buttonEncrypt_Tap(object sender, System.Windows.Input.GestureEventArgs e)
        {
            key = keyValue.Select(x => Convert.ToByte(x)).ToArray();
            key1 = keyValue1.Select(s => Convert.ToByte(s)).ToArray();

            String password = "encrypt_this";
            String passwordEnc = encrypt(GetBytes(password));
            String passwordDec = decrypt(GetBytes(passwordEnc));
        }

        private String encrypt(byte[] Data)
        {
            IBufferedCipher cipher = CipherUtilities.GetCipher("AES");
            cipher.Init(true, new KeyParameter(key));
            byte[] encVal = cipher.DoFinal(Data);
            MemoryStream memoryStream = new MemoryStream();
            //Encrypt Data 
            memoryStream.Write(encVal, 0, encVal.Length);
            memoryStream.Flush();
            //Return encrypted String 
            byte[] decryptBytes = memoryStream.ToArray();
            return GetString(decryptBytes);
        }

        private String decrypt(byte[] encryptedData)
        {
            IBufferedCipher cipher = CipherUtilities.GetCipher("AES");
            cipher.Init(false, new KeyParameter(key1));
            byte[] decValue = cipher.DoFinal(encryptedData);
            MemoryStream memoryStream = new MemoryStream();
            //Decrypt Data 
            memoryStream.Write(decValue, 0, decValue.Length);
            memoryStream.Flush();
            //Return decrypted String 
            byte[] decryptBytes = memoryStream.ToArray();
            return GetString(decryptBytes);
        }

        private byte[] GetBytes(string str)
        {
            byte[] bytes = new byte[str.Length * sizeof(char)];
            System.Buffer.BlockCopy(str.ToCharArray(), 0, bytes, 0, bytes.Length);
            return bytes;
        }

        private String GetString(byte[] result)
        {
            return System.Text.Encoding.UTF8.GetString(result, 0, result.Length);
        }

I've written this for a simple windows-phone page with single button without writing additional class, like your AESencrp, but I think the idea is clear.

Community
  • 1
  • 1
Olter
  • 1,129
  • 1
  • 21
  • 40