【问题标题】:Encryption / Decryption using Rijndael with key 256bit on Android在 Android 上使用带有 256 位密钥的 Rijndael 进行加密/解密
【发布时间】:2012-07-19 15:57:19
【问题描述】:

我正在开发一个使用 WS 的 Android 应用程序。 android应用程序和WebService之间的信息交换,必须使用256位密钥的算法加密/解密Rijndael。

也就是说,WS返回的所有信息,都会被加密,所以我用算法解密。

同样,我发送给 WS 的所有信息都应该加密。因此,我将使用加密算法。

我还没有找到可以在 android 平台上使用的 Rijndael。但我在 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


}

有人告诉我在哪里可以得到 android 的算法?或者帮我翻译一下我有Java的算法?

谢谢!

【问题讨论】:

  • 知道 rijndael 是 AES 可能会有所帮助。
  • 没看懂怎么实现的!
  • Java 的安全平台在我看来有些做作。尝试在谷歌上搜索“java AES 加密示例”
  • 这是一种从字符串中计算密钥的非常有趣的方法,当然完全不安全。我建议你也看看this
  • 请注意,这个实现几乎肯定容易受到填充预言攻击(每个字节最多 128 次尝试解密);你最好依赖 TLS。

标签: android web-services encryption rijndael


【解决方案1】:

Cipher.getInstance("AES/CBC/PKCS5Padding") 应该可以解决问题。您必须匹配(字符)编码,并且可以使用 SecretKeySpec(byte[32]) 创建 256 位 AES 密钥。

【讨论】:

    猜你喜欢
    • 2012-05-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-07-20
    相关资源
    最近更新 更多