《ASP.NET本质论》 ASP.NET中的加密与解密

        在ASP.NET中设计两个方面的加密和解密:一个是针对配置文件中配置节的加密和解密,另外一个是针对ASP.NET中数据的加密和解密
        在 .NET 中,加密和解密的技术可以分为两种。一种是加密和解密使用同样的密钥和算法,我们称之为密钥加密或者对称加密,这个方法的特点是非常快。另外一种加密方式为公钥加密或者成为非对称加密,这种加密算法对于加密和解密使用不同的密钥,通常有连个密钥A和B,使用密钥A加密数据得到密文,只有密钥B可以进行解码操作;而使用密钥B加密数据得到密文,只有密钥A可以解密。这两个密钥分别称为四要和公钥。非对称加密强度大,但是处理速度比较慢。
       与此相关还有两个概念:数字签名和散列。公钥算法还可用于构成数字签名,用来验证信息发送方的身份(如果您信任发送方的密钥)并帮助保护数据的完整性。散列算法将任意长度的二进制值映射为固定长度的较小二进制值,这个小的二进制值成为散列之。散列函数来确保消息的完整性。


    machineKey

        在ASP.NET中的很多加密和解密都要依赖于密钥,密钥保存在配置文件的machineKey里面。默认情况下,ASP.NET通过动态生成来创建网站所使用的密钥,如果单台服务器当然没问题,但是如果网站采用多台服务器负载均衡,machineKey还采用动态生成的方式,那么,每台服务器上的machineKey的值不一致,会导致加密出来的结果也不一致,不能共享验证和ViewState,所以对于多台服务器负载均衡的情况,一定要在每台站点配置相同的machineKey。
        ASP.NET中,machineKey用于以下三种用途:
          使用 forms authentication时的cookie数据的加密和解密,以确保这部分数据不会被篡改。
          viewstate数据的加密和解密,以确保这部分数据不会被篡改。
          使用进程外session(out-of-process session)时,对话状态标识进行验证。
        ASP.NET使用的密钥保存在配置文件中,配置节machineKey用于设置加密和解密哦参数,代码如下所示:

<machineKey 
   validationKey="AutoGenerate|value[,IsolateApps]"
   decryptionKey="AutoGenerate|value[,IsolateApps]"
   validation="[SHA1|MD5|3DES]"
   decryption="[Auto|]"
/>

http://msdn.microsoft.com/zh-cn/library/w8h3skw9(v=vs.80).aspx

        其中,AutoGenerate修饰符指定ASP.NET生成随机密钥并将其存储在本地安全机构(LSA)中。IsolateApps修饰符指定ASP.NEt使用应用程序ID为每个应用程序生成唯一的密钥。IsolateApps作为一部分包含在默认值中。
        为了防止篡改ViewState,散列的消息验证码(HMAC)被用于ViewState,并在后继的请求中用来比较检查。这个操作使用machineKey配置参数中validataion设置的验证算法,默认的验证算法是SHA1,并使用validationKey作为验证。
        对于敏感的页面,通过设置页面的ViewStateEncryptionMode="Always"来强制对页面的ViewState进行加密。
        decryptionKey用来对数据进行加密和解密。例如,表单验证、角色管理和匿名标识都使用它来加密和解密数据,在validataion设置为AES或者3DES的时候,ASP.NET还用它来加密和解密ViewState数据。
        对于validataionKey来说,可以指定一个手动分配的密钥。该值必须手动设置为十六进制字符串,以确保在整个网络场中保持一致。在使用AES加密时,密钥长度必须为64位十六进制字符串;在使用MD5加密时,密钥长度必须为32为十六进制字符串;使用SHA1加密时,密钥长度必须为40位十六进制字符串;使用3DES时,密钥长度必须为48位十六进制字符串;使用HMACSHA256时,使用长度为64位十六进制字符串;使用HMACSHA384时,使用长度为96位十六进制字符串;使用HMACSHA512时,使用长度为128位十六进制字符串。
        对于decryptionKey来说,可以指定一个手动分配的密钥。该值必须手动设置为十六进制字符串,以确保配置在整个网络场中保持一致。使用DES加密时,密钥长度应该为16位十六进制字符串;而使用三重DES(3DES)或AES加密时,密钥长度应该为48位十六进制字符串。当使用AES时,密钥长度可以是32个字符(128位),48个字符(192位),也可以是64个字符(256位)。首选项是使用64个字符,以便提供解密强度。
       使用RNGCryptoServiceProvider可以帮助我们创建比Random更加随机的随机数,RNGCryptoServiceProvider类产生的随机数更加随机,即使有人知道了这个类,并得到最生成的随机序列,也无法计算后续序列。这个类定义在命名空间System.Security.Cryptography中,定义如下:

           public seald class RNGCryptoServiceProvider:RandomNumberGenerator

        我们通常使用这个对象的GetBytes方法类获得一组随机数,GetBytes会通过将随机数填充到我们通过参数传递的数组来创建随机数。
               public override void GetBytes( byte[] data) 

        例如,我们可以通过下面的方法来创建指定字节的随机数:
public static string CreateKey(int len)
{
    byte[] bytes = new byte[len];
    RNGCryptoServiceProvider provider = new RNGCryptoServiceProvider();
    provider.GetBytes(bytes);

    StringBuilder sb = new StringBuilder();
    for (int i = 0; i < bytes.Length; i++)
    {
        sb.Append(string.Format("{0:X2}", bytes[i]));
    }

    return sb.ToString();
}

    


    加密服务

        CSP(Cryptographic Sevice Provider,加密服务模块)是一个真正执行加密功能的独立模块,典型的CSP有微弱RSA Base Provider。 CSP既可以由软件实现也可以由硬件实现,但是必须符合CryptoAPI接口规范。
        每个CSP都有一个名字和一个类型。每个CSP的名字是唯一的,这样便于CryptoAPI找到对应的CSP。每个CSP有一个密钥库,密钥库用于存储密钥。而每个密钥包括一个或多个密钥容器( Key Containers )。每个密钥容器中包含属于一个特定用户的所有密钥对,并被赋予一个唯一的名字。
        加密和解密XML格式的配置文件需要设置一些RSA方面的知识。RsaProtectedConfigurationProvider类提供使用RSA加密对配置数据进行加密和解密,RSA使用密钥容器来管理密钥,RsaProtectedConfigurationProvider类可以使用计算机级别或用户级别的RSA密钥容器。Microsoft Windows 为所有用户提供计算机级别的密钥容器,而用户级别的密钥容器只能供创建(或导入)了该密钥容器的用户使用。
        用户级别的RSA密钥容器存储在特定用户的Windows用户配置文件中,并且可以用于加密和解密在该特定用户标识下运行的应用程序的信息。如果希望确保在移除Windows用户配置文件时同时移除RSA密钥信息,则用户级别的RSA密钥容器非常有用。但是,由于登录时必须使用特定的用户帐户(该账户将利用用户级别的RSA密钥勇气来加密或解密受保护的配置节),因此他们使用起来不太方便。
        默认情况下,计算机级别的RSA密钥容器对于所有可以登录到计算机的用户都可用,而且由于使用管理员帐号登录时可以使用这些密钥容器加密或解密受保护的配置节,因此他们是最有用的。计算机级别的RSA密钥是容器可以用于为单个应用程序,一台服务器上的所有应用程序或者服务器上在同一用户表示下运行的一组应用程序提供信息保护。计算机级别的RSA密钥容器对所有的用户都可访问,不过也可以使用NTFS访问控制列表(ACL)保护这些密钥容器,以便只有需要的用户才能访问它们。
         在.NET中可以比较方便地管理密钥容器,定义在命名空间System.Sercurity.Cryptography中的RSACryptoServiceProvider和表示传递给执行加密计算的加密服务提供程序(CSP)的参数CspParameters可以用来创建和删除密钥容器。
CspParameters cp = new CspParameters();
    cp.KeyContainerName = ContainerName;
    RSACryptoServiceProvider rsa = new RSACryptoServiceProvider(cp);

        创建和读取密钥容器都使用上述代码,如果密钥容器不存在,则会自动创建,并将RSA产生的密钥容器存入其中;如果已经存在,则会读取其中的密钥给RSA。
        删除密钥容器使用RSACryptoServiceProvider的Clear方法完成。
CspParameters cp = new CspParameters();
    cp.KeyContainerName = ContainerName;
    RSACryptoServiceProvider rsa = new RSACryptoServiceProvider(cp);
    rsa.PersistKeyInCsp = false;
    rsa.Clear();





    配置节的加密和解密
      
        在配置文件的configProtectedData节中指定受保护配置提供程序。如果要使用自定义设置指定自己的提供程序,可以使用providers元素的add元素声明新的提供程序实例。可以使用configProtectedData元素的defaultProvider特性将该提供程序实例表示为默认的提供程序。
       默认情况下,Machine.config文件中指定了下列受保护配置提供程序。
      1)名为:RsaProtectedConfigurationProvider 的RsaProtectedConfigurationProvider实例。该提供程序配置为默认提供程序。
http://msdn.microsoft.com/zh-cn/library/system.configuration.rsaprotectedconfigurationprovider(VS.80).aspx
      2)名为 DataProtectionConfigurationProvider的DpapiProtectedConfigurationProvider实例
http://msdn.microsoft.com/zh-cn/library/system.configuration.dpapiprotectedconfigurationprovider(v=VS.80).aspx
</configSections>
	<configProtectedData defaultProvider="RsaProtectedConfigurationProvider">
		<providers>
			<add name="RsaProtectedConfigurationProvider" type="System.Configuration.RsaProtectedConfigurationProvider,System.Configuration, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" description="Uses RsaCryptoServiceProvider to encrypt and decrypt" keyContainerName="NetFrameworkConfigurationKey" cspProviderName="" useMachineContainer="true" useOAEP="false"/>
			<add name="DataProtectionConfigurationProvider" type="System.Configuration.DpapiProtectedConfigurationProvider,System.Configuration, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" description="Uses CryptProtectData and CryptUnProtectData Windows APIs to encrypt and decrypt" useMachineProtection="true" keyEntropy=""/>
		</providers>
	</configProtectedData>

        在ASP.NET中,默认使用 RsaProtectedConfigurationProvider 来加密存储在配置文件中的敏感信息,防止对这些信息进行为授权的访问。keyContainerName属性指定了使用的密钥容器,由于RsaProtectedConfigurationProvider需要访问密钥容器来使用密钥,所以,必须保证这个密钥容器存在,并且当前的Windows用户具有访问的权限。


      常见参数如下:

-pc

在指定密钥容器中创建RSA公钥/私钥对。如果密钥容器不存在,则创建密钥容器。

-exp

参数指定可以导出私钥。

-pz

删除指定的密钥容器。

-px

将RSA公钥/私钥对从指定的容器导入指定的XML文件。

-pi

将RSA公钥/私钥对从指定的XML file导入指定的容器。

-pe

加密配置节。

-pd

解密配置节。

-pef

加密物理目录,非虚拟目录中的web.config中的配置节。

-pdf

解密物理目录,而非虚拟目录中的web.config中的配置节。

-pa

未指定用户或组account授予访问指定项container的权限。

-pr

移除指定的用户或组account对指定的项container的访问权限。

-pri

可以在XML文件中包括私钥。


        例如,授予NT AUTHORITY\NETWORK SERVICE 用户访问密钥容器NetFramerworkConfigurationKey的全新.
                aspnet_regiis -pa "NetFrameworkConfigurationKey" "NT AUTHORITY\NETWORK SERVICE"
       如果自定义了密钥容器,例如,通过下面的命名创建的新密钥容器,希望在ASP.NET中使用。为确保可以导出新创建的RSA密钥容器,必须包括 -exp选项。该容器是可导出的计算机级密钥容器。
                aspnet_regiis -pc "MyConfigurationKey" -exp
       那么,可以在配置文件中如下设置所使用的密钥容器。
      

<configProtectedData defaultProvider="RsaProtectedConfigurationProvider">
		<providers>
			<add name="RsaProtectedConfigurationProvider" type="System.Configuration.RsaProtectedConfigurationProvider,System.Configuration, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" description="Uses RsaCryptoServiceProvider to encrypt and decrypt" keyContainerName="MyConfigurationKey" cspProviderName="" useMachineContainer="true" useOAEP="false"/>
			<add name="DataProtectionConfigurationProvider" type="System.Configuration.DpapiProtectedConfigurationProvider,System.Configuration, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" description="Uses CryptProtectData and CryptUnProtectData Windows APIs to encrypt and decrypt" useMachineProtection="true" keyEntropy=""/>
		</providers>
	</configProtectedData>

        可以将密钥导出到XML文件中。
                     aspnet_regiis -px "MyConfigurationKey" "MyConfigurationKey.xml"
       这个命令只导出公钥,因此以后只能用于加密,而无法解密。使用pri参数之后,可以将私钥一起导出。
                     aspnet_regiis -px "MyConfigurationKey"
                                               -pri "MyConfigurationKey.xml"

       删除密钥容器
                    aspnet_regiis -pz "MyConfigurationKey"
       从XML文件中导入密钥容器
                   aspnet_regiis -pi "MyConfigurationKey" "MyConfigurationKey.xml" 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值