美文网首页
ASP.NET Encrypt and Decrypt

ASP.NET Encrypt and Decrypt

作者: 不会撒娇的猫咪 | 来源:发表于2018-11-14 19:53 被阅读19次

    背景

    在程序或服务开发过程中,我们通常会把一些程序需要用到的常量数据配置在web.config或app.config文件中,通常配置到这些文件中的Key与Value都是明文的,但有时候我们并不希望这些配置让他人知道。
    在这种情况下,我们可以使用ASP.NET Encrypt和Decrypt来对配置文件进行加密,不影响程序使用,但又不被他人知道配置的具体内容。


    环境

    1. Windonw 7 / Windows Server 2008
    2. .Net Framework 4.0
    3. IIS

    以上环境准备好后,在搭建好的IIS上创建三个站点 WebSite1, WebSite2, WebSite3


    工具

    1. asp.net_regiis.exe
    2. vs 2010 tool
    3. sn.exe
    4. gacutil.exe

    asp.net_regiis.exe位于路径C:\Windows\Microsoft.NET\Framework64\v4.0.30319
    使用管理员身份运行cmd.exe
    Start --> All Programs --> Microsoft Visual Studio 2010 --> Visual Studio Tools --> Visual Studio x64 Win64 Command Prompt (2010)(run as administrator)
    sn, gacutil 在VS 2010 tool中可直接使用


    Providers in .NET Framework

    • DpapiProtectedConfigurationProvider
      uses the Windows Data Protected API(DPAPI) to encrypt and Decrypt data.

    • RsaProtectedConfigurationProvider
      useed the RSA encryption algorithm to encrypt and Decrypt data.

    Providers means Protected configuration Providers


    Machine-Level and User-Level

    Machine-Level

    available to all users
    Machine-level 的Key对所有管理员用户有效果,但也受ACLs的约束
    

    User-Level

    available only to the user that created the key container.
    stored with the Windonw user profile for a particular user
    userd to encrypt and decrypt information for applications that run under that specific user identity.
    user-level 的Key是与用户账号绑定的,用户被删除时,key也被删除
    

    这里所讲的avalliable是指能够加密和解密


    Tool and Parameters

    Tool

    asp.net_regiis.exe
    

    encrypt parameters

    -pe the name of the configuraiton element to be encrypt
    -app identity the application for which the web.config file will be encrypted
    -site identity which web site the application is a part of
    -prov identity the name of the ProtectedConfigurationProvider that will preform the encryption and decryption.
    pe, app 是必须要指定的值
    site默认值为1, prov默认使用defaultProvider

    decrypt parameters

    -pd the name of the configuration element to be decrypted.
    -app identify the application for which the web.config file will be encrypted
    -site identify which Web site the application is a part of
    -prov not need to specify
    在解密时不需要使用prov来指定ProtectedConfigurationProvider,because that information is read from the configProtectionProvider attribute of the protected configuration section.


    Encrypting Website’s Web.config

    在VS Tool中输入以下命令

    aspnet_regiis -pef "connectionStrings" E:\webSite1

    aspnet_regiis -pe "connectionStrings" -app "/WebSite1" -site "WebSite1"

    需要为WebSite1添加虚拟目录

    aspnet_regiss -pe "connectionStrings" -app "/WebSite1" -site "WebSite1" -prov DataProtectionConfigurationProvider

    需要为WebSite1添加虚拟目录,指定Provider


    解密

    aspnet_regiis -pd "connectionStrings" -app "/WebSite1" -site "WebSite1"


    Create a RSA Key Container

    Tool

    aspnet_regiis

    Parameters

    -pc : the name of the key container used by the RsaProtectedConfigurationProvider specified in the configProtectedData section of web.config file
    -exp : ensure that RSA key container can be exported

    Web.config的配置

    <configProtectedData>
        <providers>
            <add name="CustomerProvider" keyContainerName="SampleKeys" useMachineContainer="true" description="Users RsaCryptoSErviceProvider to encrypt and decrypt" type="System.Configuration.RsaProtectedConfigurationProvider, System.Configuration, Version=4.0.0.0, Cultuer=neutral, PublicKeyToken=b03f5f7f11d50a3a">
        </providers>
    </configProtectedData>
    

    以上配置中的KeyContainerName="true",表示使用Machine-level, false表示使用user-level
    加密时使用以下命令

    aspnet_regiis -pe "connectionStrings" -app "/WebSite2" -site "WebSite2" -prov "CustomeProvider"

    Exporting a RSA Key Container

    使用命令

    aspnet_regiis -px "SampleKeys" E:\MachineSmapleKey.xml -pri

    Importing a RSA Key Container

    aspnet_regiis -pi "MyKeys" keys.xml -pku

    Deleting a RSA Key Container

    aspnet_regiis -pz "MyKeys"


    Custome Provider Type

    Implementing a Protected Configuration Provider

    • Algorithm
      an algorithm other than those available with the RSA or DPAPI providers
    • Required Classes
      ProtectedConfigurationProvider class from the System.Configuration namespace
      ProviderBase class from the System.Configuration.Provider namespace
    • Required Members
      Initialize method (from ProviderBase)
      Encrypt method (from ProtectedConfigurationProvider)
      Decrypt method (from ProtectedConfigurationProvider)

    Build Protected Configuration Provider

    • Generate a strong-name key pair

    sn -k keys.snk

    • Create a program file named TripleDESProtectedConfigurationProvider
    using System.Xml;
    using System.Security.Cryptography;
    using System.IO;
    using System.Text;
    using System.Configuration.Provider;
    using System.Collections.Specialized;
    using System.Configuration;
    
    
    namespace AA.BB.ProtectedConfiguration
    {
    
      public class TripleDESProtectedConfigurationProvider : ProtectedConfigurationProvider
      {
    
        private TripleDESCryptoServiceProvider des = new TripleDESCryptoServiceProvider();
    
        private string pKeyFilePath;
        private string pName;
    
        public string KeyFilePath
        {
          get { return pKeyFilePath; }
        }
    
    
        //
        // ProviderBase.Name
        //
    
        public override string Name
        {
          get { return pName; }
        }
    
    
        //
        // ProviderBase.Initialize
        //
    
        public override void Initialize(string name, NameValueCollection config)
        {
          pName = name;
          pKeyFilePath = config["keyFilePath"];
          ReadKey(KeyFilePath);
        }
    
    
        //
        // ProtectedConfigurationProvider.Encrypt
        //
    
        public override XmlNode Encrypt(XmlNode node)
        {
          string encryptedData = EncryptString(node.OuterXml);
    
          XmlDocument xmlDoc = new XmlDocument();
          xmlDoc.PreserveWhitespace = true;
          xmlDoc.LoadXml("<EncryptedData>" + encryptedData + "</EncryptedData>");
    
          return xmlDoc.DocumentElement;
        }
    
    
        //
        // ProtectedConfigurationProvider.Decrypt
        //
    
        public override XmlNode Decrypt(XmlNode encryptedNode)
        {
          string decryptedData = DecryptString(encryptedNode.InnerText);
    
          XmlDocument xmlDoc = new XmlDocument();
          xmlDoc.PreserveWhitespace = true;
          xmlDoc.LoadXml(decryptedData);  
    
          return xmlDoc.DocumentElement;
        }
    
    
        //
        // EncryptString
        //    Encrypts a configuration section and returns the encrypted
        // XML as a string.
        //
    
        private string EncryptString(string encryptValue)
        {
          byte[] valBytes = Encoding.Unicode.GetBytes(encryptValue);
    
          ICryptoTransform transform = des.CreateEncryptor();
    
          MemoryStream ms = new MemoryStream();
          CryptoStream cs = new CryptoStream(ms, transform, CryptoStreamMode.Write);
          cs.Write(valBytes, 0, valBytes.Length);
          cs.FlushFinalBlock();
          byte[] returnBytes = ms.ToArray();
          cs.Close();
    
          return Convert.ToBase64String(returnBytes);
        }
    
    
        //
        // DecryptString
        //    Decrypts an encrypted configuration section and returns the
        // unencrypted XML as a string.
        //
    
        private string DecryptString(string encryptedValue)
        {
          byte[] valBytes = Convert.FromBase64String(encryptedValue);
    
          ICryptoTransform transform = des.CreateDecryptor();
    
          MemoryStream ms = new MemoryStream();
          CryptoStream cs = new CryptoStream(ms, transform, CryptoStreamMode.Write);
          cs.Write(valBytes, 0, valBytes.Length);
          cs.FlushFinalBlock();
          byte[] returnBytes = ms.ToArray();
          cs.Close();
    
          return Encoding.Unicode.GetString(returnBytes);
        }
    
        //
        // CreateKey
        //    Generates a new TripleDES key and vector and writes them
        // to the supplied file path.
        //
    
        public void CreateKey(string filePath)
        {
          des.GenerateKey();
          des.GenerateIV();
    
          StreamWriter sw = new StreamWriter(filePath, false);
          sw.WriteLine(ByteToHex(des.Key));
          sw.WriteLine(ByteToHex(des.IV));
          sw.Close();
        }
    
    
        //
        // ReadKey
        //    Reads in the TripleDES key and vector from the supplied
        // file path and sets the Key and IV properties of the 
        // TripleDESCryptoServiceProvider.
        //
    
        private void ReadKey(string filePath)
        {
          StreamReader sr = new StreamReader(filePath);
          string keyValue = sr.ReadLine();
          string ivValue = sr.ReadLine();
          des.Key = HexToByte(keyValue);
          des.IV = HexToByte(ivValue);
        }
    
    
        //
        // ByteToHex
        //    Converts a byte array to a hexadecimal string.
        //
    
        private string ByteToHex(byte[] byteArray)
        {
          string outString = "";
    
          foreach (Byte b in byteArray)
            outString += b.ToString("X2");
    
          return outString;
        }
    
        //
        // HexToByte
        //    Converts a hexadecimal string to a byte array.
        //
    
        private byte[] HexToByte(string hexString)
        {
          byte[] returnBytes = new byte[hexString.Length / 2];
          for (int i = 0; i < returnBytes.Length; i++)
            returnBytes[i] = Convert.ToByte(hexString.Substring(i*2, 2), 16);
          return returnBytes;
        }
    
      }
    }
    
    • Compile the code and assign the resulting assembly with the strong-name key

    csc /out:TripleDESProtectedConfigurationProvider.dll /t:library TripleDESProtectedConfigurationProvider.cs /r:System.Configuration.dll /keyfile:keys.snk

    • Install the assembly in the GAC(global assembly cach)

      gacutil -i TripleDESProtectedConfigurationProvider.dll


    Use a Custom Provider type

    • Generate Key File

      CreateKey.exe E:\ASP\Keys.txt

    • Modify the configProtectedData Section of the Web.config

    <configProtectedData>
        <providers>
            <add name="SampleProvider"  useMachineContainer="true" type="AA.BB.TripleDESProtectedConfigurationProvider TripleDESProtectedConfigurationProvider  Version=0.0.0.0, Cultuer=neutral  PublicKeyToken=b06675f7f11d50a3a",description="Users RsaCryptoSErviceProvider to encrypt and decrypt" keyFilePath="E:\ASP\Key" >    
        </providers>
    </configProtectedData>
    

    相关文章

      网友评论

          本文标题:ASP.NET Encrypt and Decrypt

          本文链接:https://www.haomeiwen.com/subject/ibzcfqtx.html