一直试图冒险出去学习一些C#和powershell,给自己一点点尝试和学习的项目。最近我一直试图将一些代码从PowerShell转换为C#,我相信我已经开始工作,但我遇到了一些错误,为RijndaelManaged创建了IV。
这是从网络上拉出来的工作正常的powershell代码
function Decrypt-String($Encrypted, $Passphrase, $salt, $init="Yet another key")
{
if($Encrypted -is [string]){
$Encrypted = [Convert]::FromBase64String($Encrypted)
}
$r = new-Object System.Security.Cryptography.RijndaelManaged
$pass = [System.Text.Encoding]::UTF8.GetBytes($Passphrase)
$salt = [System.Text.Encoding]::UTF8.GetBytes($salt)
$r.Key = (new-Object Security.Cryptography.PasswordDeriveBytes $pass, $salt, "SHA1", 5).GetBytes(32) #256/8
$r.IV = (new-Object Security.Cryptography.SHA1Managed).ComputeHash( [Text.Encoding]::UTF8.GetBytes($init) )[0..15]
$d = $r.CreateDecryptor()
$ms = new-Object IO.MemoryStream @(,$Encrypted)
$cs = new-Object Security.Cryptography.CryptoStream $ms,$d,"Read"
$sr = new-Object IO.StreamReader $cs
Write-Output $sr.ReadToEnd()
$sr.Close()
$cs.Close()
$ms.Close()
$r.Clear()
}
这是我把它移到
的C#代码public static string Decrypt_String(string cipherText, string passPhrase, string Salt)
{
string hashAlgorithm = "SHA1";
int passwordIterations = 5;
initName = "Yet another key";
using (RijndaelManaged r = new RijndaelManaged())
{
byte[] cipherTextBytes = Convert.FromBase64String(cipherText);
byte[] PassPhraseBytes = Encoding.UTF8.GetBytes(passPhrase);
byte[] SaltBytes = Encoding.UTF8.GetBytes(Salt);
byte[] initVectorBytes = Encoding.UTF8.GetBytes(initName);
PasswordDeriveBytes password = new PasswordDeriveBytes(PassPhraseBytes,SaltBytes,hashAlgorithm,passwordIterations);
byte[] keyBytes = password.GetBytes(32); //(256 / 32)
r.Key = keyBytes;
SHA1Managed cHash = new SHA1Managed();
r.IV = cHash.ComputeHash(Encoding.UTF8.GetBytes(initName),0,16);
ICryptoTransform decryptor = r.CreateDecryptor();
MemoryStream memoryStream = new MemoryStream(cipherTextBytes);
CryptoStream cryptoStream = new CryptoStream(memoryStream,
decryptor,
CryptoStreamMode.Read);
StreamReader streamReader = new StreamReader(cryptoStream);
string output = streamReader.ReadToEnd();
return output;
}
}
目前ComputeHash正在回吐一个错误,告诉我该值无效。 这是我在工作加密函数中使用的值
cipherText =“s6ZqNpJq05jsMh2 + 1BxZzJQDDiJGRQPqIYzBjYQHsgw =”
saltValue =“} = [BJ8%] vjJDnQfmvC))))3Q”
passphrase =“S @ lt3d”
关于为什么IV不能正确设置的任何想法?
编辑: 对不起,例外是
Line 38: r.IV = cHash.ComputeHash(initVectorBytes, 0, 16);
Exception Details: System.ArgumentException: Value was invalid.
种类的通用
答案 0 :(得分:2)
@Nate是正确的,你正在使用ComputeHash
方法的不同重载,而你还没有正确处理它:
Encoding.UTF8.GetBytes(initName)
这将返回与字符串长度相同的字节数组 - 15 。但是,通过传递0
和16
,您要求ComputeHash
使用数组的第一个 16 元素。
cHash.ComputeHash(Encoding.UTF8.GetBytes(initName),0,16);
所以第一个修复方法是通过0
和15
(或者0
和initName.Length
),或者更好的是,回到你正在使用的重载在您的powershell脚本中,它自动计算出数组长度:
cHash.ComputeHash(Encoding.UTF8.GetBytes(initName));
但是你需要缩短生成的数组(它返回长度为20,但你只想要16):
using System.Linq;
...
cHash.ComputeHash(Encoding.UTF8.GetBytes(initName)).Take(16).ToArray();