你是否对web.config machineKey这样的配置产生过疑惑?
<machineKey validationKey=”21F090935F6E49C2C797F69BBAAD8402ABD2EE0B667A8B44EA7DD4374267A75D7 AD972A119482D15A4127461DB1DC347C1A63AE5F1CCFAACFF1B72A7F0A281B” decryptionKey=”ABAA84D7EC4BB56D75D217CECFFB9628809BDB8BF91CFCD64568A145BE59719F”validation=”SHA1″decryption=”AES”/> |
或者你想了解machineKey的加密、解密及验签算法…
你将在本文有所收获。
首先附上.NET源码地址:http://referencesource.microsoft.com/
1. machineKey配置的作用
以下是MSDN https://msdn.microsoft.com/zh-cn/library/w8h3skw9的解释
对算法、密钥进行配置,以便将其用于对 Forms 身份验证数据和视图状态数据进行加密、解密和验证,并将其用于进程外会话状态标识。
意思是说WebForm的Form与ViewState的数据都是根据这一配置算法进行加密、解密及验证的。该MSDN文档最新文档只更新到了 .NET Framework 4,引申一点来讲,.NET后续的MVC的Form提交以及OWIN的Cookie、OAuth身份验证都采用的是machineKey配置的算法。
2. machineKey的默认加密/解密算法
查阅.NET命名空间 System.Web.Security.Cryptography下的machineKey加密算法工厂类MachineKeyCryptoAlgorithmFactory代码:
private Func<SymmetricAlgorithm> GetEncryptionAlgorithmFactory()
{
return GetGenericAlgorithmFactory<SymmetricAlgorithm>(configAttributeName: "decryption", configAttributeValue: _machineKeySection.GetDecryptionAttributeSkipValidation(), switchStatement: algorithmName =>
{
// We suppress CS0618 since some of the algorithms we support are marked with [Obsolete].
// These deprecated algorithms are *not* enabled by default. Developers must opt-in to
// them, so we're secure by default.#pragma warning disable 618
switch (algorithmName)
{
case "AES":
case "Auto":
// currently "Auto" defaults to AES
return CryptoAlgorithms.CreateAes;
case "DES":
return CryptoAlgorithms.CreateDES;
case "3DES":
return CryptoAlgorithms.CreateTripleDES;
default:
return null;
// unknown#pragma warning restore 618
}
},
errorResourceString: SR.Wrong_decryption_enum);
}
注意到算法名”AES”与”Auto”都返回的是AES加密/解密算法:
case "AES":case "Auto":
// currently "Auto" defaults to AES
return CryptoAlgorithms.CreateAes;
而这两行代码
configAttributeName: "decryption",
configAttributeValue:_machineKeySection.GetDecryptionAttributeSkipValidation()
则表示算法名称由machineKey的decryption属性配置决定。
我们再来看一下GetDecryptionAttributeSkipValidation方法是如何获取这一属性值的:
// returns the value in the 'decryption' attribute (or the default value if null) without throwing an exception if the value is malformedinternal
string GetDecryptionAttributeSkipValidation()
{
return (string)base[_propDecryption] ?? "Auto";
}
(代码位于命名空间System.Web.Configuration MachineKeySection类)
可以看到,优先取base[_propDecryption],若为空,则默认为”Auto”。那么_propDecryption又是什么呢?转到定义即可看到:
private static readonly ConfigurationProperty _propDecryption = new ConfigurationProperty("decryption", typeof(string), "Auto", StdValidatorsAndConverters.WhiteSpaceTrimStringConverter, StdValidatorsAndConverters.NonEmptyStringValidator, ConfigurationPropertyOptions.None);
可以看到,默认值取的”Auto”,而结合上文的GetEncryptionAlgorithmFactory方法可以看到”Auto”对应的算法为AES,所以machineKey的默认加密/解密算法为AES。
3. machineKey默认的验签算法
首先,查看一下获取验前算法工厂方法定义(同样位于命名空间 System.Web.Security.Cryptography下的类MachineKeyCryptoAlgorithmFactory):
private Func<KeyedHashAlgorithm> GetValidationAlgorithmFactory()
{
return GetGenericAlgorithmFactory<KeyedHashAlgorithm>(configAttributeName: "validation", configAttributeValue: _machineKeySection.GetValidationAttributeSkipValidation(), switchStatement: algorithmName =>
{
switch (algorithmName)
{
case "SHA1": return CryptoAlgorithms.CreateHMACSHA1;
case "HMACSHA256": return CryptoAlgorithms.CreateHMACSHA256;
case "HMACSHA384": return CryptoAlgorithms.CreateHMACSHA384;
case "HMACSHA512": return CryptoAlgorithms.CreateHMACSHA512;
default: return null; // unknown
}
}, errorResourceString: SR.Wrong_validation_enum_FX45);
}
可以看到,验签算法取的validation属性:
configAttributeName: “validation”,configAttributeValue: _machineKeySection.GetValidationAttributeSkipValidation(), |
而GetValidationAttributeSkipValidation又是这样获取的:
// returns the value in the ‘validation’ attribute (or the default value if null) without throwing an exception if the value is malformedinternal string GetValidationAttributeSkipValidation() { return (string)base[_propValidation] ?? DefaultValidationAlgorithm;} |
而_propDecryption的定义如下:
private static readonly ConfigurationProperty _propValidation = new ConfigurationProperty(“validation”, typeof(string), DefaultValidationAlgorithm, StdValidatorsAndConverters.WhiteSpaceTrimStringConverter, StdValidatorsAndConverters.NonEmptyStringValidator, ConfigurationPropertyOptions.None); |
可以看到,validation属性值默认取的DefaultValidationAlgorithm,DefaultValidationAlgorithm定义如下:
// If the default validation algorithm changes, be sure to update the _HashSize and _AutoGenValidationKeySize fields also.internal const string DefaultValidationAlgorithm = “HMACSHA256”; |
可以看到,默认算法为”HMACSHA256”,所以machineKey的默认验签算法为”HMACSHA256”。