ASP.NET 数据加密/解密变得简单






4.33/5 (12投票s)
为 .NET 框架中的内置加密功能创建包装器。
引言
本文档展示了如何为使用 .NET 框架中默认情况下不可访问的现有内置方法加密和解密字符串创建一个基本的包装器。
背景
我不得不反向工程脚本资源 URL(例如 ScriptResource.axd?d=WIkfIHx2pe1WhCNefMjMESVyFb1-lrFL...)用于一个脚本组合项目,以便我可以在配置文件中放置像 System.Web.Forms.js 这样的资源路径,而不是那些冗长且不友好的 URL... 我注意到资源名称正在使用 MachingKeySection
类进行加密,并且由于所有这些非常有用的方法都声明为 private
或 internal
,我决定创建一个包装器,以便我可以轻松访问所有这些功能。
使用代码
如果您知道在 .NET 框架中查找什么,那么代码就非常简单明了。首先,我们获取我们正在查找的类的类型。在这种情况下,它是包含我们正在查找的 EncryptOrDecryptData
方法的 MachineKeySection
类。
// This class is made public but the methods
// we requiere are made private or internal.
Type machineKeySection = typeof(System.Web.Configuration.MachineKeySection);
现在我们知道了类型,就可以使用反射来获取对 EncryptOrDecryptData
方法的引用。此方法由 .NET 框架内部用于几乎所有操作。因此,现在我们有能力解密几乎所有内容。由于计算机的机器密钥用作加密密钥,因此我们只能解密在同一服务器上加密的数据。
// Get encryption / decryption method
// You can look up all the methods using Reflector
// or a simillar tool.
MethodInfo _EncDecMethod = machineKeySection.GetMethod("EncryptOrDecryptData",
BindingFlags.NonPublic | BindingFlags.Static, Type.DefaultBinder,
new[] { typeof(bool), typeof(byte[]), typeof(byte[]), typeof(int), typeof(int) },
null);
现在我们已经获得了对加密-解密方法的引用,就可以调用它了。
internal static byte[] EncryptOrDecryptData(bool fEncrypt, byte[] buf,
byte[] modifier, int start, int length)
bool fEncrypt
- 如果希望加密数据,则设置为true
,如果希望解密数据,则设置为false
。byte[] buf
- 您想要加密或解密的数据。int length
- 数据的长度,通常只是buf.length
,如果您想加密或解密整个字节数组。
扩展
如果您需要字符串加密和解密,那么可以通过添加其他两个方法来扩展类别的功能。一个用于解密,一个用于加密数据。您不必传递字节数组并将其转换为字符串,反之亦然,而只需传递字符串并获得字符串作为结果。
加密示例
// Data we want to encrypt
string data = "Encrypt me";
// Convert strig to byte array
byte[] bytes = Encoding.UTF8.GetBytes(data);
// Invoke the encryption method.
byte[] encData = (byte[])_EncDecMethod.Invoke(null,
new object[] { true, bytes, null, 0, bytes.Length });
// Ecnrypted string
string encData Convert.ToBase64String(encData);
现在可以将生成的字符串复制到任何您想要的地方,然后复制回来并解密。解密方法大致相同,只是顺序相反。两种方法实现都包含在演示项目中。
结论
如果您正在创建自定义配置文件或拥有包含敏感数据的 XML 文档,此代码非常有用。通过直接调用 EncryptOrDecryptData
,您可以加密几乎所有内容。