0

I am developing an Android application that consumes a WS. For exchange of information between the android application and WebService, you must use the algorithm encryption / decryption Rijndael with 256 bit key.

That is, all the information returned from the WS, will be encrypted, so I decrypts them using the algorithm.

Likewise, all the information I send to WS should be encrypted. Therefore, I will use the encryption algorithm.

I have not found the Rijndael ready to be used in the android platform. But I have the same algorithm in C #.

public class KeydKey
{
    public KeydKey()
    {

    }


    #region Metodos de Criptografia
    #region key
    public string key(string vstrTextToBeEncrypted, string vstrEncryptionKey)
    {
        byte[] bytValue;
        byte[] bytKey;
        byte[] bytEncoded;
        byte[] bytIV = { 121, 241, 10, 1, 132, 74, 11, 39, 255, 91, 45, 78, 14, 211, 22, 62 };
        int intLength;
        int intRemaining;
        MemoryStream objMemoryStream = new MemoryStream();
        CryptoStream objCryptoStream;
        RijndaelManaged objRijndaelManaged;

        //O valor deve estar dentro da tabela ASCII (i.e., no DBCS chars)  
        bytValue = Encoding.UTF32.GetBytes(vstrTextToBeEncrypted.ToCharArray());
        intLength = vstrEncryptionKey.Length;

        /* 
           ******A chave cifrada será de 256 bits long (32 bytes)                             
           ****** Se for maior que 32 bytes então será truncado.                               
           ****** Se for menor que 32 bytes será alocado.                                        
           ****** Usando upper-case Xs
         */
        if (intLength >= 32)
        {
            vstrEncryptionKey = vstrEncryptionKey.Substring(0, 32);
        }
        else
        {
            intLength = vstrEncryptionKey.Length;
            intRemaining = 32 - intLength;
            string tmp = "";
            vstrEncryptionKey = vstrEncryptionKey + tmp.PadRight(intRemaining, 'X');
        }

        bytKey = Encoding.ASCII.GetBytes(vstrEncryptionKey.ToCharArray());
        objRijndaelManaged = new RijndaelManaged();

        /*  ****** Cria o valor a ser crifrado e depois escreve                                  
            ****** Convertido em uma disposição do byte 
         */
        try
        {
            objCryptoStream = new CryptoStream(objMemoryStream, objRijndaelManaged.CreateEncryptor(bytKey, bytIV), CryptoStreamMode.Write);
            objCryptoStream.Write(bytValue, 0, bytValue.Length);

            objCryptoStream.FlushFinalBlock();

            bytEncoded = objMemoryStream.ToArray();
            objMemoryStream.Close();
            objCryptoStream.Close();
            return Convert.ToBase64String(bytEncoded);
        }
        catch (Exception ex)
        {
            return null;
        }
    }
    #endregion

    #region dkey
    public string dkey(string vstrstringToBeDecrypted, string vstrDecryptionKey)
    {
        byte[] bytDataToBeDecrypted;
        byte[] bytTemp = new byte[0];
        byte[] bytIV = { 121, 241, 10, 1, 132, 74, 11, 39, 255, 91, 45, 78, 14, 211, 22, 62 };
        MemoryStream objMemoryStream = new MemoryStream();
        CryptoStream objCryptoStream;
        RijndaelManaged objRijndaelManaged;
        byte[] bytDecryptionKey;
        int intLength;
        int intRemaining;
        string strReturnstring = string.Empty;

        //Convert base64 cifrada para byte array
        bytDataToBeDecrypted = Convert.FromBase64String(vstrstringToBeDecrypted);
        intLength = vstrDecryptionKey.Length;

        /* 
           ******A chave cifrada será de 256 bits long (32 bytes)                             
           ****** Se for maior que 32 bytes então será truncado.                               
           ****** Se for menor que 32 bytes será alocado.                                        
           ****** Usando upper-case Xs
         */
        if (intLength >= 32)
        {
            vstrDecryptionKey = vstrDecryptionKey.Substring(0, 32);
        }
        else
        {
            intLength = vstrDecryptionKey.Length;
            intRemaining = 32 - intLength;
            string tmp = "";
            vstrDecryptionKey = vstrDecryptionKey + tmp.PadRight(intRemaining, 'X');
        }

        bytDecryptionKey = Encoding.ASCII.GetBytes(vstrDecryptionKey.ToCharArray());
        objRijndaelManaged = new RijndaelManaged();

        Array.Resize(ref bytTemp, bytDataToBeDecrypted.Length);

        objMemoryStream = new MemoryStream(bytDataToBeDecrypted);


        try
        {

            objCryptoStream = new CryptoStream(objMemoryStream, objRijndaelManaged.CreateDecryptor(bytDecryptionKey, bytIV), CryptoStreamMode.Read);
            objCryptoStream.Read(bytTemp, 0, bytTemp.Length);
            //objCryptoStream.FlushFinalBlock();
            objMemoryStream.Close();
            objCryptoStream.Close();
            return Encoding.UTF32.GetString(bytTemp).Replace("\0", "");
        }
        catch (Exception ex)
        {
            return null;
        }
    }

    #endregion

    #endregion


}

Someone tell me where I can get the algorithm for android? Or help me translate the algorithm that I have Java?

Thank you!

Taynã Bonaldo
  • 621
  • 9
  • 17
  • It might help to know that rijndael is AES. – Wug Jul 19 '12 at 15:59
  • I did not understand how the implementation! – Taynã Bonaldo Jul 19 '12 at 18:17
  • Java's security platform is somewhat contrived in my opinion. try searching on google for "java AES encryption example" – Wug Jul 19 '12 at 18:21
  • That's a very interesting method of calculating a key out of a String, completely insecure of course. I would suggest you have a look at [this](http://stackoverflow.com/a/4863924/328397) too. – Maarten Bodewes Jul 19 '12 at 18:37
  • Note that this implementation is almost certainly vulnerable to padding oracle attacks (max of 128 tries per byte to decrypt); you are much better off relying on TLS. – Maarten Bodewes Jul 19 '12 at 18:42
  • I understand the point of being vulnerable. The problem is that the WS has been implemented by the client. So I do the encryption in the same way that the WS. Or am I wrong? I'm studying it: http://developer.motorola.com/docs/using_the_advanced_encryption_standard_in_android/ But it is confusing me even more. What I doubt it was generated over the issue of padding. Even he is not used in the WS, I must use it in the application? This causes the difference? Furthermore, the client has an I "DEV_KEY" .... Where do I use it? – Taynã Bonaldo Jul 19 '12 at 20:24
  • The code that I have shared is the WS client. He even gave me this code. The problem is that in C #. – Taynã Bonaldo Jul 19 '12 at 20:26
  • Yes, I understand. Maybe, as a token of appreciation, you could indicate to the client that he is vulnerable. This is clearly not an implementation of WS-Security, so the fact that the cipher text is transported using WS should not matter much. – Maarten Bodewes Jul 20 '12 at 22:04

1 Answers1

3

Cipher.getInstance("AES/CBC/PKCS5Padding") should do the trick. You will have to match (character)-encodings and you may use SecretKeySpec(byte[32]) to create a 256 bit AES key.

Maarten Bodewes
  • 90,524
  • 13
  • 150
  • 263