代码改变世界

Asp.net页面的编码格式引起的"密钥集不存在"错误

2011-11-16 09:14  slmk  阅读(1481)  评论(3编辑  收藏  举报

"密钥集不存在 ",英文"Keyset does not exist"

堆栈跟踪:

at System.Security.Cryptography.CryptographicException.ThrowCryptogaphicException(Int32 hr)    
at System.Security.Cryptography.SafeProvHandle._FreeCSP(IntPtr pProvCtx)
at System.Security.Cryptography.SafeProvHandle.ReleaseHandle()
at System.Runtime.InteropServices.SafeHandle.InternalFinalize()
at System.Runtime.InteropServices.SafeHandle.Dispose(Boolean disposing)
at System.Runtime.InteropServices.SafeHandle.Finalize()

这通常是因为我们使用微软的非对称加密类"RSACryptoServiceProvider ",同时我们又启用了IIS的模拟用户造成的。(对称加密不会出现这种错误,因为Keyset是对非对称加密而言的,也就是我们说的“公钥”和“私钥”的统称)

具体原因:

1、我们以模拟用户身份使用了RSACryptoServiceProvider

2、我们没有调用RSA的clear方法,释放掉密钥集

3、当GC进行垃圾回收时,并不是以模拟身份运行的,通常是Network Service帐号下,于是没有了上下文或者没有了访问权限

4、总而言之,就出了这个错

 解决方法:

每次加密或解密后,调用RSACryptoServiceProvider 的clear方法就好了。

网上好像还有一种方法:

赋予Network Service(也可能是别的)帐号对文件夹“C:\Documents and Settings\All Users\Application Data\Microsoft\Crypto\RSA"的完全访问权限。

 

--------------------------------------------------历史分割线-----------------------------------------

以下我碰到的情况可能只有对我自己有用, 我想大多数人不会碰到:

Google"密钥集不存在"错误的解决方案不能解决我的问题。此错误是一个未处理的异常,然而用户代码无法捕捉此异常,只能通过事件查看器观察到。此错误着实让我的团队困扰了几天,因为如果出现此错误,必将引起Web服务器进程w3wp.exe意外关闭,然后重新启动,造成的结果是Session很快过期,进程结束,Session变量当然不复存在。

事件ID1334、5000、4096有规律的依次发生。

客户电话不断打来,只好换回以前的备份,结果此错误消失。问题肯定是最近的程序修改造成的,然而仔细对照程序代码,没有发现任何问题。

无意间想到了编码格式,因为有很多莫名其妙的问题都是文件的编码格式造成的。用记事本打开最近修改的一个文件a.aspx,“文件另存为”,发现是ANSI格式,然而其他文件都是Utf-8格式,忽然想起在修改a.aspx文件时,是从Utf-8文件中复制了一段代码到a.aspx中。这样会不会造成IIS异常发生?

 

于是将文件保存为UTF-8编码格式,然后复制代码,发布后问题解决,错误没有再次出现。然而这种错误平常很少出现,都是UTF-8格式的,出现了可能也不在意,只是简单的归结于RP问题。希望对遇到相同问题的朋友有所帮助。

警示:一段文本用肉眼看不出有什么区别,但是它是带有编码格式的。

 

提供Silverlight打印全套解决方案--支持打印预览、页面设置(横向纵向,页边距,纸张大小、字体大小)、自动分页和多页连续打印