C# ASP.NET MembershipProvider--它是如何进行加密的?
我需要了解MembershipProvider如何执行加密的详细信息:C# ASP.NET MembershipProvider--它是如何进行加密的?,c#,asp.net,C#,Asp.net,我需要了解MembershipProvider如何执行加密的详细信息: 它使用什么算法 是否有任何base64编码预处理或后处理 除了它使用的标准算法之外,它还做了什么 给定要加密的纯文本密码,请引导我完成生成返回的最终加密密码的确切步骤 我认为看到源代码对回答我的问题会有很大帮助,但我一直无法在网上找到它。我只找到了,它没有提供实现细节 谢谢你提供的任何信息 可从Microsoft获得成员资格提供程序的源代码。Scott Guthrie几年前在博客上写过这件事 下面是您想要/需要的代码。。。这
谢谢你提供的任何信息 可从Microsoft获得成员资格提供程序的源代码。Scott Guthrie几年前在博客上写过这件事
下面是您想要/需要的代码。。。这有点像兔子圈,所以要完全理解,我建议你做以下几点:
- 安装
[可选]安装 - 在任意位置编写以下代码:
var dummyMembershipProvider=新的SqlMembershipProvider()代码>
dummyMembershipProvider.ChangePassword(“用户名”、“旧密码”、“新密码”)代码>
- 在
ChangePassword
- 这将开始你的兔子圈之旅。。。它应该是这样的:
SqlMembershipProvider.ChangePassword
SqlMembershipProvider.EncodePassword
MembershipProvider.EncryptPassword
IMembershipAdapter.EncryptOrDecryptData
MembershipAdapter.EncryptOrDecryptData
MachineKeySection.EncryptOrDecryptData
- 购买ReSharper是因为你意识到你不能再没有它了
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;
}
}
公共密封类机器密钥部分:配置部分
{
内部静态字节[]EncryptOrDecryptData(布尔密码,字节[]buf,字节[]修饰符,整数开始,整数长度,
bool useValidationSymAlgo,bool useLegacyMode,IVType-IVType)
{
图();
如果(使用legacyMode)
useLegacyMode=\u UsingCustomEncryption;//仅对自定义算法使用传统模式
System.IO.MemoryStream ms=新的System.IO.MemoryStream();
ICryptoTransform oDesEnc=GetCryptoTransform(fEncrypt,useValidationSymAlgo,useLegacyMode);
CryptoStream cs=新的加密流(ms、oDesEnc、CryptoStreamMode.Write);
//DevDiv Bugs 137864:将随机或散列IV添加到要加密的数据的开头。
//MembershipProvider使用IVType.None,即使在SP2模式下也需要兼容性。
boolcreateiv=((ivType!=ivType.None)和&(compatimode>MachineKeyCompatibilityMode.Framework20SP1));
如果(fEncrypt&createIV)
{
字节[]iv=空;
int ivLength=(useValidationSymAlgo?_IVLengthValidation:_IVLengthDecryption);
开关(ivType)
{
case-IVType.Hash:
iv=GetIVHash(buf,ivLength);
打破
病例类型:随机:
iv=新字节[ivLength];
RandomNumberGenerator.GetBytes(iv);
打破
}
Assert(iv!=null,“IVType的无效值:”+IVType.ToString(“G”));
cs.写入(iv,0,iv.长度);
}
cs.写入(buf、开始、长度);
if(fEncrypt&&modifier!=null)
{
cs.Write(修饰符,0,修饰符.长度);
}
cs.FlushFinalBlock();
字节[]paddedData=ms.ToArray();
字节[]b数据;
cs.Close();
ReturnCryptoTransform(fEncrypt、oDesEnc、useValidationSymAlgo、useLegacyMode);
//DevDiv Bugs 137864:从未加密数据的开头删除随机或散列IV
如果(!fEncrypt&&createIV)
{
//去掉第一个字节,这些字节要么是随机位,要么是原始数据的散列
//无论哪种方式,它都始终等于密钥长度
int ivLength=(useValidationSymAlgo?_IVLengthValidation:_IVLengthDecryption);
int bDataLength=paddedData.Length-ivLength;
//如果数据足够长,足以包含填充,则有效
如果(bDataLength>=0)
{
bData=新字节[bDataLength];
//从填充数据复制到非填充缓冲区bData。
//如果数据完全是填充的,就不要麻烦复制
如果(bDataLength>0)
{
块拷贝(paddedData,ivLength,bData,0,bDataLength);
}
}
其他的
{
//数据没有填充,因为它不够长
b数据=填充数据;
}
}
其他的
{
b数据=填充数据;
}
如果(!fEncrypt&&modifier!=null&&modifier.Length>0)
{
对于(int iter=0;iterI不确定框架版本之间的实现是否有任何差异,但为了避免混淆,您指的是.NET的哪个版本?@Cory实际上可以说最新版本的代码已经发布了,但大约有100行代码我不知道是否应该发布。我建议使用downlo下载反编译器,然后自己查看源代码。具体来说,请查看.NET 2.0和.NET 4的System.Web.Configuration.MachineKeySection.EncryptOrDecryptData()
。这还取决于您使用的成员资格提供程序。表单提供程序使用SHA1或MD5算法散列密码(单向)。SQL成员资格可以使用AES、DES或TripleDES(取决于配置)进行散列或加密