我需要了解 MembershipProvider 如何执行加密的细节:
- 它使用什么算法?
- 是否有任何base64编码预处理或后处理?
- 除了它使用的标准算法之外,它还有什么其他功能吗?
给定一个要加密的纯文本密码,请引导我完成生成返回的最终加密密码的确切步骤。
我认为查看源代码对回答我的问题大有帮助,但我一直无法在网上找到它。我只找到了这个文档,它没有提供实现细节。
感谢您提供任何信息!
以下是您想要/需要的代码......到达那里有点像兔子沃伦,所以要完全理解,我建议您执行以下操作:
var dummyMembershipProvider = new SqlMembershipProvider();
dummyMembershipProvider.ChangePassword("userName", "oldPassword", "newPassword");
ChangePassword
SqlMembershipProvider.ChangePassword
SqlMembershipProvider.EncodePassword
MembershipProvider.EncryptPassword
IMembershipAdapter.EncryptOrDecryptData
MembershipAdapter.EncryptOrDecryptData
MachineKeySection.EncryptOrDecryptData
无论如何,这是 MachineKeySection.EncryptOrDecryptData:
public sealed class MachineKeySection : ConfigurationSection
{
internal static byte[] EncryptOrDecryptData(bool fEncrypt, byte[] buf, byte[] modifier, int start, int length,
bool useValidationSymAlgo, bool useLegacyMode, IVType ivType)
{
EnsureConfig();
if (useLegacyMode)
useLegacyMode = _UsingCustomEncryption; // only use legacy mode for custom algorithms
System.IO.MemoryStream ms = new System.IO.MemoryStream();
ICryptoTransform oDesEnc = GetCryptoTransform(fEncrypt, useValidationSymAlgo, useLegacyMode);
CryptoStream cs = new CryptoStream(ms, oDesEnc, CryptoStreamMode.Write);
// DevDiv Bugs 137864: Add Random or Hashed IV to beginning of data to be encrypted.
// IVType.None is used by MembershipProvider which requires compatibility even in SP2 mode.
bool createIV = ((ivType != IVType.None) && (CompatMode > MachineKeyCompatibilityMode.Framework20SP1));
if (fEncrypt && createIV)
{
byte[] iv = null;
int ivLength = (useValidationSymAlgo ? _IVLengthValidation : _IVLengthDecryption);
switch (ivType)
{
case IVType.Hash:
iv = GetIVHash(buf, ivLength);
break;
case IVType.Random:
iv = new byte[ivLength];
RandomNumberGenerator.GetBytes(iv);
break;
}
Debug.Assert(iv != null, "Invalid value for IVType: " + ivType.ToString("G"));
cs.Write(iv, 0, iv.Length);
}
cs.Write(buf, start, length);
if (fEncrypt && modifier != null)
{
cs.Write(modifier, 0, modifier.Length);
}
cs.FlushFinalBlock();
byte[] paddedData = ms.ToArray();
byte[] bData;
cs.Close();
ReturnCryptoTransform(fEncrypt, oDesEnc, useValidationSymAlgo, useLegacyMode);
// DevDiv Bugs 137864: Strip Random or Hashed IV from beginning of unencrypted data
if (!fEncrypt && createIV)
{
// strip off the first bytes that were either random bits or a hash of the original data
// either way it is always equal to the key length
int ivLength = (useValidationSymAlgo ? _IVLengthValidation : _IVLengthDecryption);
int bDataLength = paddedData.Length - ivLength;
// valid if the data is long enough to have included the padding
if (bDataLength >= 0)
{
bData = new byte[bDataLength];
// copy from the padded data to non-padded buffer bData.
// dont bother with copy if the data is entirely the padding
if (bDataLength > 0)
{
Buffer.BlockCopy(paddedData, ivLength, bData, 0, bDataLength);
}
}
else
{
// data is not padded because it is not long enough
bData = paddedData;
}
}
else
{
bData = paddedData;
}
if (!fEncrypt && modifier != null && modifier.Length > 0)
{
for(int iter=0; iter<modifier.Length; iter++)
if (bData[bData.Length - modifier.Length + iter] != modifier[iter])
throw new HttpException(SR.GetString(SR.Unable_to_validate_data));
byte[] bData2 = new byte[bData.Length - modifier.Length];
Buffer.BlockCopy(bData, 0, bData2, 0, bData2.Length);
bData = bData2;
}
return bData;
}
}
成员资格提供程序的源代码可从 Microsoft 获得。几年前,斯科特·格思里在博客上写过它。
http://weblogs.asp.net/scottgu/archive/2006/04/13/442772.aspx