![](/img/trans.png)
[英]Decrypting AES in C# where the file was encryped using OpenSSL -nosalt; the AES is expecting a size 16 byte array IV?
[英]C# AES 128 CBC with -nosalt producing different results than openssl AES -128-cbc -nosalt
我有一個來自第三方的加密示例,我需要與...集成
我應該向他們發送加密的消息,並且他們確實會對其解密並執行所需的操作。
他們為我提供了一個示例,說明他們期望如何對字符串進行加密..
echo -n [“要加密的字符串”] | openssl enc -aes-128-cbc -A -a -nosalt -K [十六進制加密密鑰] -iv 30303030303030303303030303030030
我得到的沙盒加密密鑰十六進制是313233343536373839
目前,我無法按原樣使用上述指定的密鑰和IV,因為.Net中的AES實現引發了我和錯誤,提示“指定的密鑰不是此算法的有效大小”
然后我只是用0填充鍵以匹配32個字節,並截斷了IV以匹配16個字節。
然后我至少可以運行代碼,但是我的C#代碼中的加密字符串無法在openssl上解密。
下面是我的代碼..
public static string EncryptString(string plainText, string password)
{
byte[] key, iv;
//converting key to hex
byte[] ba = Encoding.ASCII.GetBytes("0123456789abcdef");
string encryptionKeyHex = BitConverter.ToString(ba);
encryptionKeyHex = encryptionKeyHex.Replace("-", "");
// Padding key hex with zeros to match the size that .Net algo expects
if (encryptionKeyHex.Length < 32)
{
while (encryptionKeyHex.Length < 32)
{
encryptionKeyHex += "0";
}
}
var keyBytes = Encoding.ASCII.GetBytes(encryptionKeyHex);
var ivBytes = Encoding.ASCII.GetBytes("3030303030303030"); // truncated the original IV specified in the question description to match the size.
iv = ivBytes;
key = keyBytes;
var amAes = new AesManaged();
amAes.Mode = CipherMode.CBC;
amAes.Padding = PaddingMode.PKCS7;
amAes.KeySize = 128;
amAes.BlockSize = 128;
amAes.Key = key;
amAes.IV = iv;
var icTransformer = amAes.CreateEncryptor();
var msTemp = new MemoryStream();
var csEncrypt = new CryptoStream(msTemp, icTransformer, CryptoStreamMode.Write);
var sw = new StreamWriter(csEncrypt);
sw.Write(plainText);
sw.Close();
sw.Dispose();
csEncrypt.Clear();
csEncrypt.Dispose();
byte[] bResult = msTemp.ToArray();
//var sha = new SHA1CryptoServiceProvider();
//var result = sha.ComputeHash(bResult);
string sResult = Convert.ToBase64String(bResult);
sResult = HttpUtility.UrlEncode(sResult);
if (System.Diagnostics.Debugger.IsAttached)
{
string debugDetails = "";
debugDetails += "==> INPUT : " + plainText + Environment.NewLine;
debugDetails += "==> SECRET : " + password + Environment.NewLine;
//debugDetails += "==> SALT : " + Program.ByteArrayToHexString(salt) + Environment.NewLine;
debugDetails += "==> KEY : " + Encoding.ASCII.GetString(amAes.Key) + " (" + amAes.KeySize.ToString() + ")" + Environment.NewLine;
debugDetails += "==> IV : " + Encoding.ASCII.GetString(amAes.IV) + Environment.NewLine;
debugDetails += "==> ENCRYPTED : " + sResult;
Console.WriteLine(debugDetails);
}
return sResult;
}
輸出:
==>輸入:{“ filter.accession_number.equals”:“ 0987654321”}
==>秘密:==>密鑰:30313233343536373839000000000000(256)
==> IV:3030303030303030
==>加密的:B2uDRjnekFAlRDEKDldTs09lWiE4u16ZunVwDGi6gKm6YsaRlW4HU6eKJqfYZc7b
更新資料
已經注意到,使用相同的方法在Windows盒上進行加密的情況與在Linux盒上進行加密的結果不同。
在使用openssl的Linux機器上,我們得到..
命令:echo -n'{“ filter.accession_number.equals”:“ 0987654321”}'| openssl enc -aes-128-cbc -A -a -nosalt -K 313233343536373839 -iv 30303030303030303303030303030030
結果:MTAusb6rYkxYf9 / REbFq9M1XwR + 6Q58FfSJPTxDNwgs6z3jZ8ru + 7ysnKuy2p3ox
該加密的字符串很好用..我能夠成功解密它。
在windows框上向openssl發出相同的命令時,會給我們..
命令:echo -n'{“ filter.accession_number.equals”:“ 0987654321”}'| openssl enc -aes-128-cbc -A -a -nosalt -K 313233343536373839 -iv 30303030303030303303030303030030
結果:Db9829q6QX6CPwLkE + rs6zqRJJQaGZ9xk7fbztaGqsKcHPcr7equz3yOJPLc + S6yvW4jXQTzoOk43F16GW7sPw ==
該字符串不起作用...
這是適合遇到類似問題的任何人的工作代碼示例... @Maarten Bodewes您的確向我指出了正確的方向,只是必須重新排列代碼才能使其正常工作。 謝謝 :)
public static string EncryptString(string plainText)
{
byte[] key, iv;
byte[] rawKey = Encoding.ASCII.GetBytes("123456789abcdef");
string encryptionKeyHex = BitConverter.ToString(rawKey);
byte[] hexKayBytes = FromHex(encryptionKeyHex); // convert to bytes with 'dashes'
byte[] data = FromHex("30-30-30-30-30-30-30-30-30-30-30-30-30-30-30-30");
encryptionKeyHex = ByteArrayToHexString(hexKayBytes);
// modifying key size to match the algorithm validation on key size
if (encryptionKeyHex.Length < 32)
{
while (encryptionKeyHex.Length < 32)
{
encryptionKeyHex += "0";
}
}
var ivOriginal = BitConverter.ToString(data);
ivOriginal = ivOriginal.Replace("-", "");
if (ivOriginal.Length < 16)
{
while (ivOriginal.Length < 16)
{
ivOriginal += "0";
}
}
var keyBytes = StringToByteArray(encryptionKeyHex);
var ivBytes = StringToByteArray(ivOriginal);
iv = ivBytes;
key = keyBytes;
var amAes = new AesManaged();
amAes.Mode = CipherMode.CBC;
amAes.Padding = PaddingMode.PKCS7;
amAes.KeySize = 128;
amAes.BlockSize = 128;
amAes.Key = key;
amAes.IV = iv;
var icTransformer = amAes.CreateEncryptor();
var msTemp = new MemoryStream();
var csEncrypt = new CryptoStream(msTemp, icTransformer, CryptoStreamMode.Write);
var sw = new StreamWriter(csEncrypt);
sw.Write(plainText);
sw.Close();
sw.Dispose();
csEncrypt.Clear();
csEncrypt.Dispose();
byte[] bResult = msTemp.ToArray();
string sResult = Convert.ToBase64String(bResult);
if (System.Diagnostics.Debugger.IsAttached)
{
string debugDetails = "";
debugDetails += "==> INPUT : " + plainText + Environment.NewLine;
debugDetails += "==> SECRET : " + password + Environment.NewLine;
//debugDetails += "==> SALT : " + Program.ByteArrayToHexString(salt) + Environment.NewLine;
debugDetails += "==> KEY : " + Encoding.ASCII.GetString(amAes.Key) + " (" + amAes.KeySize.ToString() + ")" + Environment.NewLine;
debugDetails += "==> IV : " + Encoding.ASCII.GetString(amAes.IV) + Environment.NewLine;
debugDetails += "==> ENCRYPTED : " + sResult;
Console.WriteLine(debugDetails);
}
return sResult;
}
public static byte[] FromHex(string hex)
{
hex = hex.Replace("-", "");
byte[] raw = new byte[hex.Length / 2];
for (int i = 0; i < raw.Length; i++)
{
raw[i] = Convert.ToByte(hex.Substring(i * 2, 2), 16);
}
return raw;
}
private static string ByteArrayToHexString(byte[] bytes)
{
StringBuilder sbHex = new StringBuilder();
foreach (byte b in bytes)
sbHex.AppendFormat("{0:x2}", b);
return sbHex.ToString();
}
public static byte[] StringToByteArray(String hex)
{
int NumberChars = hex.Length;
byte[] bytes = new byte[NumberChars / 2];
for (int i = 0; i < NumberChars; i += 2)
bytes[i / 2] = Convert.ToByte(hex.Substring(i, 2), 16);
return bytes;
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.