来自C#的AES加密的等效PHP代码

时间:2013-01-31 11:02:58

标签: c# php encryption aes

任何人都可以为下面的C#Aes加密提供等效的PHP代码,我尝试过不同的php AES加密但没有用,输出不匹配,提前谢谢。

此处使用的键和iv值以十六进制表示,预期输出为十六进制。

C#:

public class AESAlgorithm
    {

    public static string GeneratePrivateKey()
    {
        string str;

        RijndaelManaged rijndaelManaged = null;
        try
        {
            rijndaelManaged = new RijndaelManaged();
            rijndaelManaged.KeySize = 128;
            rijndaelManaged.GenerateKey();
            str = ConvertByteArrayToHexString(rijndaelManaged.Key);
        }
        finally
        {
            if (rijndaelManaged == null)
            {
                rijndaelManaged.Clear();
            }
        }
        return str;
    }

    public static string GenerateAuthKey(string timestamp, string appCode, string attUid, string privateKey)
    {
        return Encrypt(String.Format("{0}|{1}|{2}", timestamp, appCode, attUid), privateKey);
    }

    public static string Encrypt(string textToEncrypt, string hexStringKey)
    {
        string str1;

        RijndaelManaged rijndaelManaged = null;
        try
        {
            rijndaelManaged = new RijndaelManaged();
            rijndaelManaged.Mode = CipherMode.CBC;
            rijndaelManaged.Padding = PaddingMode.PKCS7;
            rijndaelManaged.KeySize = 128;
            rijndaelManaged.BlockSize = 128;
            byte[] bs1 = ConvertHexStringToByteArray(hexStringKey);
            rijndaelManaged.Key = bs1;
            rijndaelManaged.IV = bs1;
            ICryptoTransform iCryptoTransform = rijndaelManaged.CreateEncryptor();
            byte[] bs2 = Encoding.UTF8.GetBytes(textToEncrypt);
            str1 = ConvertByteArrayToHexString(iCryptoTransform.TransformFinalBlock(bs2, 0, (int)bs2.Length));
        }
        finally
        {
            if (rijndaelManaged == null)
            {
                rijndaelManaged.Clear();
            }
        }
        return str1;
    }

    public static string Decrypt(string hexStringToDecrypt, string hexStringKey)
    {
        string str1;

        RijndaelManaged rijndaelManaged = null;
        try
        {
            rijndaelManaged = new RijndaelManaged();
            rijndaelManaged.Mode = CipherMode.CBC;
            rijndaelManaged.Padding = PaddingMode.PKCS7;
            rijndaelManaged.KeySize = 128;
            rijndaelManaged.BlockSize = 128;
            byte[] bs1 = ConvertHexStringToByteArray(hexStringToDecrypt);
            byte[] bs2 = ConvertHexStringToByteArray(hexStringKey);
            rijndaelManaged.Key = bs2;
            rijndaelManaged.IV = bs2;
            byte[] bs3 = rijndaelManaged.CreateDecryptor().TransformFinalBlock(bs1, 0, (int)bs1.Length);
            str1 = Encoding.UTF8.GetString(bs3);
        }
        finally
        {
            if (rijndaelManaged == null)
            {
                rijndaelManaged.Clear();
            }
        }
        return str1;
    }

    private static string ConvertByteArrayToHexString(byte[] input)
    {
        bool flag;

        StringBuilder stringBuilder = new StringBuilder();
        byte[] bs = input;
        int i = 0;
        do
        {
            byte b = bs[i];
            stringBuilder.AppendFormat("{0:x2}", b);
            i++;

            flag = i < (int)bs.Length;
        }
        while (flag);
        return stringBuilder.ToString();
    }

    private static byte[] ConvertHexStringToByteArray(string hexString)
    {
        bool flag = (hexString.Length & 1) == 0;
        if (!flag)
        {
            throw new ArgumentOutOfRangeException("hexString", hexString, "hexString must contain an even number of characters.");
        }
        byte[] bs1 = new byte[hexString.Length / 2];
        int i = 0;
        do
        {
            bs1[i / 2] = Byte.Parse(hexString.Substring(i, 2), NumberStyles.HexNumber);
            i += 2;

            flag = i < hexString.Length;
        }
        while (flag);
        return bs1;
    }
}

1 个答案:

答案 0 :(得分:0)

您的示例代码非常糟糕,您使用关键字节作为IV,攻击者肯定可以使用选择的密文攻击轻松地计算关键字节。这会让你的授权密钥难堪。

IV必须是AES-CBC的独特和不可预测的。

我的建议,因为这似乎是某种类型的凭据,您应该使用Authenticated Encryption

我有一些剪切和粘贴代码,我会继续审核,Modern Examples of Symmetric Authenticated Encryption of a string C#

使用nonSecretPayload = new byte[]{2,X};加密时,我的示例的 .NET内置加密(AES)-Then-MAC(HMAC)版本应与RNCryptor兼容({ {1}} X没有密码,0使用密码)并使用1进行解密。

尽管RNCryptor是objective-c,但我相信RNCryptor有PHP示例。