任何人都可以为下面的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;
}
}
答案 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
进行解密。