1

冒険して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.

ジェネリックの種類

4

1 に答える 1

2

@Nateは正しく、ComputeHashメソッドの別のオーバーロードを使用していて、それを適切に処理していません。

Encoding.UTF8.GetBytes(initName)

これにより、文字列と同じ長さのバイト配列が返されます-15。しかし、0とを渡すことで、配列の最初の1616要素を使用するように求められます。ComputeHash

cHash.ComputeHash(Encoding.UTF8.GetBytes(initName),0,16);

したがって、この最初の修正は、パス015(または多分0initName.Length)のいずれか、またはさらに良いことに、PowerShellスクリプトで使用しているオーバーロードに戻り、配列の長さを自動的に計算することです。

cHash.ComputeHash(Encoding.UTF8.GetBytes(initName));

ただし、結果の配列を短くする必要があります(長さは20になりますが、必要なのは16だけです)。

using System.Linq;
...
cHash.ComputeHash(Encoding.UTF8.GetBytes(initName)).Take(16).ToArray();
于 2012-08-29T17:17:47.417 に答える