আমি পড়ছি যে SHA256 এর মতো হ্যাশিং ফাংশনগুলি সত্যই পাসওয়ার্ডগুলি সংরক্ষণের উদ্দেশ্যে ব্যবহার করা হয়নি:
https://patrickmn.com/security/store-passwords-securely/#notpasswordhashes
পরিবর্তে অভিযোজিত কী ডেরাইভেশন ফাংশনগুলির মতো পিবিকেডিএফ 2, বিসিক্রিপ্ট বা স্ক্রিপ্ট ছিল। মাইক্রোসফ্ট তাদের মাইক্রোসফ্ট-এ পাসওয়ার্ডহ্যাশারের জন্য লিখেছেন এমন একটি পিবিকেডিএফ 2 ভিত্তিক একটি এখানে রয়েছে spস্পেন নেট.আইডেন্টিটি লাইব্রেরি:
/* =======================
* HASHED PASSWORD FORMATS
* =======================
*
* Version 3:
* PBKDF2 with HMAC-SHA256, 128-bit salt, 256-bit subkey, 10000 iterations.
* Format: { 0x01, prf (UInt32), iter count (UInt32), salt length (UInt32), salt, subkey }
* (All UInt32s are stored big-endian.)
*/
public string HashPassword(string password)
{
var prf = KeyDerivationPrf.HMACSHA256;
var rng = RandomNumberGenerator.Create();
const int iterCount = 10000;
const int saltSize = 128 / 8;
const int numBytesRequested = 256 / 8;
// Produce a version 3 (see comment above) text hash.
var salt = new byte[saltSize];
rng.GetBytes(salt);
var subkey = KeyDerivation.Pbkdf2(password, salt, prf, iterCount, numBytesRequested);
var outputBytes = new byte[13 + salt.Length + subkey.Length];
outputBytes[0] = 0x01; // format marker
WriteNetworkByteOrder(outputBytes, 1, (uint)prf);
WriteNetworkByteOrder(outputBytes, 5, iterCount);
WriteNetworkByteOrder(outputBytes, 9, saltSize);
Buffer.BlockCopy(salt, 0, outputBytes, 13, salt.Length);
Buffer.BlockCopy(subkey, 0, outputBytes, 13 + saltSize, subkey.Length);
return Convert.ToBase64String(outputBytes);
}
public bool VerifyHashedPassword(string hashedPassword, string providedPassword)
{
var decodedHashedPassword = Convert.FromBase64String(hashedPassword);
// Wrong version
if (decodedHashedPassword[0] != 0x01)
return false;
// Read header information
var prf = (KeyDerivationPrf)ReadNetworkByteOrder(decodedHashedPassword, 1);
var iterCount = (int)ReadNetworkByteOrder(decodedHashedPassword, 5);
var saltLength = (int)ReadNetworkByteOrder(decodedHashedPassword, 9);
// Read the salt: must be >= 128 bits
if (saltLength < 128 / 8)
{
return false;
}
var salt = new byte[saltLength];
Buffer.BlockCopy(decodedHashedPassword, 13, salt, 0, salt.Length);
// Read the subkey (the rest of the payload): must be >= 128 bits
var subkeyLength = decodedHashedPassword.Length - 13 - salt.Length;
if (subkeyLength < 128 / 8)
{
return false;
}
var expectedSubkey = new byte[subkeyLength];
Buffer.BlockCopy(decodedHashedPassword, 13 + salt.Length, expectedSubkey, 0, expectedSubkey.Length);
// Hash the incoming password and verify it
var actualSubkey = KeyDerivation.Pbkdf2(providedPassword, salt, prf, iterCount, subkeyLength);
return actualSubkey.SequenceEqual(expectedSubkey);
}
private static void WriteNetworkByteOrder(byte[] buffer, int offset, uint value)
{
buffer[offset + 0] = (byte)(value >> 24);
buffer[offset + 1] = (byte)(value >> 16);
buffer[offset + 2] = (byte)(value >> 8);
buffer[offset + 3] = (byte)(value >> 0);
}
private static uint ReadNetworkByteOrder(byte[] buffer, int offset)
{
return ((uint)(buffer[offset + 0]) << 24)
| ((uint)(buffer[offset + 1]) << 16)
| ((uint)(buffer[offset + 2]) << 8)
| ((uint)(buffer[offset + 3]));
}
নোট করুন এর জন্য মাইক্রোসফ্ট.এএসপনেটকোর.ক্রিপোগ্রাফি.কি- ডেরিভেশন নুগেট প্যাকেজ ইনস্টল করা হয়েছে যার জন্য .NET স্ট্যান্ডার্ড 2.0 (। নেট 4.6.1 বা তার বেশি) প্রয়োজন। .NET- র পূর্ববর্তী সংস্করণগুলির জন্য মাইক্রোসফ্টের সিস্টেম.বিউব.হেলপার্স লাইব্রেরি থেকে ক্রিপ্টো ক্লাসটি দেখুন ।
আপডেট নভেম্বর 2015
আপডেট অন্য মাইক্রোসফট লাইব্রেরি থেকে PBKDF2-HMAC-SHA256 এর পরিবর্তে PBKDF2-HMAC-SHA256 ব্যবহার করে হ্যাশিং ব্যবহার করা হয়েছে এমন একটি প্রয়োগকরণ ব্যবহারের আপডেট হওয়া উত্তর (নোট PBKDF2-HMAC-SHA1 এখনও সুরক্ষিত যদি এটির পরিমাণ যথেষ্ট থাকে)। আপনি সরলিকৃত কোডটি অনুলিপি করে উত্সটি পরীক্ষা করতে পারেন যেহেতু এটি পূর্ববর্তী উত্তর থেকে বাস্তবায়িত হ্যাশগুলি যাচাইকরণ এবং আপগ্রেড করার ক্ষেত্রে পরিচালনা করে, যদি আপনাকে ভবিষ্যতে এটিরকাউন্ট বাড়ানোর প্রয়োজন হয় তবে দরকারী।