阿不

潜水

  博客园 :: 首页 :: 博问 :: 闪存 :: 新随笔 :: 联系 :: 订阅 订阅 :: 管理 ::

         昨天在使用Cryptography Block时出现一个问题,详见: 使用Cryptography BlockIIS下运行出现的的问题 也请教过一些朋友,一直都没有解决。因为有一点怀疑是.NET的加密类库或者是Cryptography BlockBUG,所以今天早上特别反编译了加密类库,查看了内部代码和Cryptography Block的源代码。发现异常虽然是ProtectedDataUnprotect方法抛出的,而是在Cryptography BlockProtectedKey类中被调用的?ProtectedKey类?经过了解和分析,它是为对称加密,解密提供密钥的类。那么为什么调用它的Unprotect方法却会出错?百思不得其解。刚刚在调试程序过程中,脑子突然间就开窍了一下。对密钥进行解密?那什么时候对密钥加密的呢?调试过程中一直都没有找到对密钥进行加密的地方,唯一能够确定的就是用ProtectedData. Unprotect 方法进行解密,查阅了一下MSDN,发现它是.NET 2.0中的一个新的类型,提供对DPAPI加密的封装。用DPAPI进行加密?没错,就是DPAPI,问题就出在这里!

昨天也有提到如果用DPAPI进行加密在IIS中是不会出错的。因为使用DPAPI加密,我们不用人为的对加密密钥进行管理,系统用根据当前用户和应用程序的一些特征自动产生和管理加密密钥,也就是说DPAPI加密和解密是执行应用程序的用户息息相关的,加密用一个用户,而解密使用的却是另一个用户,自然就会出错了。而DPAPI是操作系统本身提供的一个API,这也解释了我昨天关于“英文版本的.NET Framework,中文操作系统,异常信息怎么会是中文提示呢?”的疑问。总结问题就是:在配置Cryptography Block时会生成一个密钥文件,而这个密钥文件本身也是进行过加密的,它用的是DPAPI加密,这个密钥文件的路径会被记录在symmetricCryptoProviders配置节的protectedKeyFilename属性中。在用户使用Cryptography Block进行加密,解密数据时再找到这个文件,解密出密钥,对需要加密的数据进行加密。

简单回顾一下如何配置Cryptography Block

打开web.config(app.config),右击鼠标

cry1.jpg 1

选择“Cryptography Application Block”新建一个加密配置节

cry2.jpg 2

分为两个大类的加密算法,分别是不可逆和可逆(又可分为对称加密和不对称加密)算法。选择Symmetric Providers 右击鼠标添加一个对称加密

cry3.jpg 3

 

上图的第二个项就是添加一个DPAPI的对称加密Provider,第二项目是使用常规的对称加密算法。选择第三项就会弹出加密算法选择窗口,里面已经提供了系统内部写好一些算法,当然如果有自定义算法可以通过“Load an Assembly”加载自定义自算法类型。

cry4.jpg 4

 

各种算法的特点这边不多深入,可以随便选择一种算法。单OK后会弹出一个小窗口,问你是新建一个密钥,还是使用已有的使用DPAPI加密过的密钥文件。第三个选项是导入一个被密码加密过的密钥文件,如果选择这项需要提供密钥文件和加密密钥文件的密码,并且最终它生成的密钥文件也是被DPAPI加密过的密钥文件。

cry5.jpg 5

选择第一个项,下一步出提示生成一个密钥。单击“Generate”后进行下一步,会让我们选择将加密后的密钥文件存放在哪里,选择一个存放路径后下一步。

cry6.jpg6

 

接下去这步就是我出错的根源所在了,这边有两个选项,一个是用户模式,一个是机器模式。如果选择了用户模式,那么这个密钥就只能用当前用户运行的程序才能被正确解密,比如当前配置的用户是Administrator,那么就只能是Administrator用户运行的程序才能正常使用,而如果是其它用户执行的程序,比如在IIS下执行的Web程序就不能使用了它默认不是用Administrator用户的。那么使用机器模式,就可以解决如上的问题了,就是这里的密钥文件在当前机器下的所有用户都能正常解密,但是当我将这个加密过的密钥文件放到其它机器上就不能用了,这就给开发和部署带来极大的不便了,每个开发机器都要创建一个与机器相关的加密后的密钥文件。如何创建稍后简单介绍一下。

cry7.jpg7

Finish完成配置向导。这样就完成了Cryptography Block配置了。生成的配置文件如下:

<configuration>

    <configSections>

        <section name="securityCryptographyConfiguration" type="Microsoft.Practices.EnterpriseLibrary.Security.Cryptography.Configuration.CryptographySettings, Microsoft.Practices.EnterpriseLibrary.Security.Cryptography, Version=2.0.0.0, Culture=neutral, PublicKeyToken=97c16f8550e236d6" />

    </configSections>

    <securityCryptographyConfiguration>

        <symmetricCryptoProviders>

            <add algorithmType="System.Security.Cryptography.RijndaelManaged, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"

                protectedKeyFilename="C:\Documents and Settings\Administrator\妗岄潰\1.key"

                protectedKeyProtectionScope="LocalMachine" type="Microsoft.Practices.EnterpriseLibrary.Security.Cryptography.SymmetricAlgorithmProvider, Microsoft.Practices.EnterpriseLibrary.Security.Cryptography, Version=2.0.0.0, Culture=neutral, PublicKeyToken=97c16f8550e236d6"

                name="RijndaelManaged" />

        </symmetricCryptoProviders>

    </securityCryptographyConfiguration>

</configuration>

程序中的使用如下

using Microsoft.Practices.EnterpriseLibrary.Security.Cryptography;

Cryptographer.EncryptSymmetric("RijndaelManaged", "hello");

 

但是这边还可以看到protectedKeyFilename使用的路径是绝对路径,尝试过使用相对路径,但是它却到 c:\windows\system32\inetsrv 路径下去找文件(只对Web 而言,WinForm应用程序会在运行目录下找)。这也开发带来不小的影响,每个开发人员的web.config文件要不一样,或者就直接把这个密钥文件放在c:\windows\system32\inetsrv

接下来简单记录一下如何导入密钥文件,在每台机器上创建不同的与机器相关的加密密钥文件。右击配置好的对称加密Provider出现:

cry8.jpg8

选择“Export Key”在弹出的窗口提供文件名和密码,就可以导出密钥了。

cry9.jpg9

 

然后到需要使用Cryptography Block的机器上导入生成一个与机器相关的加密密钥文件(图5中选择第三项)。

总结一下,出现昨天的错误主要是自己对新的(2.0)Cryptography Block包括对整个企业库的了解还不够深入,因为在以前1.1下的加密都没有出现这样的问题,当然这也就说明了对一项技术,实践跟了解,知道是完全两个不同层次上的认识,没有实践过就没办法真正掌握正确的使用方法甚至可能出现的问题。还有一点就是自己的知识和理解能力还有很大的不足。

posted on 2006-04-07 13:49  阿不  阅读(3537)  评论(14编辑  收藏  举报