私は実際に、組み込みデバイスの Visual C# .NET 2.0 で開発しているアプリに非常に単純なログイン メカニズムを実装しようとしています。いくつかの調査の後、msdn でパスワードハッシュを実行するコードサンプルを見つけました:
byte.Parse
残念ながら、このコード サンプルを使用しようとすると、16 進数の文字列の部分文字列に対する呼び出しで FormatException が発生しますSaltValue
。コードに変更を加えていないため、理由を理解するのに本当に苦労しています。
コードは次のとおりです。
using System;
using System.Collections.Generic;
using System.Text;
using System.Security.Cryptography;
using System.Globalization;
private const int SaltValueSize = 4;
private static string GenerateSaltValue()
{
UnicodeEncoding utf16 = new UnicodeEncoding();
if (utf16 != null)
{
// Create a random number object seeded from the value
// of the last random seed value. This is done
// interlocked because it is a static value and we want
// it to roll forward safely.
Random random = new Random(unchecked((int)DateTime.Now.Ticks));
if (random != null)
{
// Create an array of random values.
byte[] saltValue = new byte[SaltValueSize];
random.NextBytes(saltValue);
// Convert the salt value to a string. Note that the resulting string
// will still be an array of binary values and not a printable string.
// Also it does not convert each byte to a double byte.
//Original line :
//string saltValueString = utf16.GetString(saltValue);
//Replaced by :
string saltValueString = utf16.GetString(saltValue, 0, SaltValueSize);
// Return the salt value as a string.
return saltValueString;
}
}
return null;
}
private static string HashPassword(string clearData, string saltValue, HashAlgorithm hash)
{
UnicodeEncoding encoding = new UnicodeEncoding();
if (clearData != null && hash != null && encoding != null)
{
// If the salt string is null or the length is invalid then
// create a new valid salt value.
if (saltValue == null)
{
// Generate a salt string.
saltValue = GenerateSaltValue();
}
// Convert the salt string and the password string to a single
// array of bytes. Note that the password string is Unicode and
// therefore may or may not have a zero in every other byte.
byte[] binarySaltValue = new byte[SaltValueSize];
//FormatException raised here
binarySaltValue[0] = byte.Parse(saltValue.Substring(0, 2), System.Globalization.NumberStyles.HexNumber, CultureInfo.InvariantCulture.NumberFormat);
binarySaltValue[1] = byte.Parse(saltValue.Substring(2, 2), System.Globalization.NumberStyles.HexNumber, CultureInfo.InvariantCulture.NumberFormat);
binarySaltValue[2] = byte.Parse(saltValue.Substring(4, 2), System.Globalization.NumberStyles.HexNumber, CultureInfo.InvariantCulture.NumberFormat);
binarySaltValue[3] = byte.Parse(saltValue.Substring(6, 2), System.Globalization.NumberStyles.HexNumber, CultureInfo.InvariantCulture.NumberFormat);
//...
//Some more code
//...
}
}
私は1行だけを変更しました:
string saltValueString = utf16.GetString(saltValue);
に
string saltValueString = utf16.GetString(saltValue, 0, SaltValueSize);
メソッドの最初のバージョンは組み込み C# では使用できないように見えるためです。とにかく、この行を変更せずに (非埋め込み環境で) テストしましたが、それでも FormatException が発生していました。
SaltValueSize
他の msdn コード サンプル (関連する) から値を
コピーしました:パスワードを検証する方法
例外を発生させるテスト:
HashPassword("youpi", null, new SHA1CryptoServiceProvider());