在企业正式服务器上部署产品时,遇到的2个特殊问题的原因与解决方案
最近有2个客户在使用预定系统book和帮助台helpdesk时,出现了错误(算作很罕见吧),这里把错误的原因和对策写下来,如果你遇到这里错误
可供参考(不代表是最佳解决方法)
错误1:This implementation is not part of the Windows Platform FIPS validated cryptographic algorithms.
FIPS,Federal Information Processing Standards(美国)联邦信息处理标准,错误的原因是:系统执行的加密不是FIPS的技术标准。
当初出现这个错误第一个感觉就baidu/google一下,很快找到了解决方案,在运行里,输入组策略gpedit.msc,在安全选项里,禁用
FIPS功能即可,我后来在自己的机器上测试都成功,但是部署到服务器上始终不行。
后来我又认为,该公司所有服务器都在域控里,所以就算服务器的策略临时改变了,但是会在下次同步时,还是会自动重置,换言之
即使你现在更改了这个策略为“禁用”,那么服务器可能会在下次电脑重启时又自动设置为“启用”。他们可不愿意为了一个小系统而更改整个
全公司的策略。
接下来,再看看有没有其他的解决方法,有用户提出修改注册表regedit,在HKLM的Softeare选项里,将enforceFIPSPolicy 的值由1修改为0,做了仍然没效果
其实,上面2个方法本质上应该是一样的,因为所谓修改策略最终执行的还是修改注册表。
接下来又用户建议在web.config里增加
<configuration> <runtime> <enforceFIPSPolicy enabled=”0” /> <!-- or maybe ="false" --> </runtime> </configuration>
当.NET运行时,会先检查enforceFIPSPolicy ,如果此处设置为false将不再强制使用FIPS,看似很完美,但是结果真的采用次方法时,仍然出错。后来说修改的位置放置到machine.config也不行。
最后找到微软给的解决方案,在web.config增加machineKey,我认为他这个配置是针对加密身份证验证票cookie的,采用这个方法也不行。
<machineKey validationKey="AutoGenerate,IsolateApps" decryptionKey="AutoGenerate,IsolateApps" validation="3DES" decryption="3DES" />
原本以为10分钟能够解决的问题,折磨了一上午仍然没有解决,下午时,不再搜索,执行看了一下错误代码:
System.Security.Cryptography.SHA1Managed
系统是在这里出错的,想了一下,错误的原因很简单了,在我的程序里,使用了Hash值,当时为了方便使用了
GetHash()方法,当调用次此方法时,.NET自动根据组策略FIPS来检查该方法是否是FIPS的一部分。
既然无法修改FIPS,所以只好另行生产随机数,最后使用Guid.NewGuid(),后来程序可以运行了。
当然,这个解决方法还是比较悬的,我这里面可以使用Guid替代Hash,如果你程序里无法用Guid替代,就不好处理了。
第二个错误是System.ArgumentOutOfRangeException: Specified argument was out of the range of valid values.
Parameter name: utcDate,看错误提示是,utdDate,在helpdesk里,所有功能运行正常,但是就是axd资源无法访问。
程序里使用了treeview控件,难道是这个控件造成的?应该不会吧,这个用在很多项目都没有出错,因此自己查看了一下错误的原因:
System.Web.HttpCachePolicy.UtcSetLastModified(DateTime utcDate)
是在缓存里出现了错误,该用户使用的是windows2008,后来在日期里发现了客户启用了“自动到internet服务器上同步时间”功能。
看到这里,我后来禁用了此功能,然后运行helpdesk仍然不可以,最后我手动把今天的日期修改为明天,再访问就正常了,最后又修改为今天的日期
也可以了。
后来感觉的原因是,系统使用了缓存,例如当前服务器是2012.2.28 18:00时,用户访问了helpdesk,缓存的时间就是2012.2.28 18:00,当下一个用户访问时
UtcSetLastModified的值一定是在这个时间之前。但是可能是用户的标准时间快了而服务器又启用了自动到internet同步标准时间“绝对时间”,导致同步后的时间可能是2012.2.28日 17:59分,这样,UtcSetLastModified获取的最新修改时间反而是“将来的时间”,因此出错。
因此通过将日期更改为明天,将缓存重置后,再修改回来即可。