用戶最近在使用我的軟件時報告了一個奇怪的錯誤。我使用DSA簽名來驗證許可證。當軟件導入的公鑰來驗證簽名,將DSA提供商的FromXmlString方法拋出一個CryptographicException記載着「鍵不適於在指定狀態下使用。」從一個用戶導入xml字符串的DSA密鑰失敗。權限?破碎的安裝?壞的KSP?
這樣看來,所謂的_OpenCSP方法從System.Security.Cryptography.Utils.CreateProvHandle返回一個NTE_BAD_KEY_STATE(0x8009000b)。這是任何人第一次向我報告這個錯誤,並且該代碼多年來沒有改變。
這可能是什麼原因造成的?蒙面的權限錯誤?破損的CAPI安裝?被.net信任/權限設置阻止?由密鑰存儲提供商存儲的垃圾或KSP將意外事件返回給cryptoapi?
我用Google搜索錯誤代碼/說明/等,但在任何真正的答案是什麼可能會導致這樣沒來......
失敗的代碼分離的版本是在這裏: http://forum.huagati.com/getattachment.ashx?fileid=78
using System;
using System.Security.Cryptography;
using System.Reflection;
public class Test
{
public static void Main()
{
try
{
string key = "<DSAKeyValue><P>wrjxUnfKvH/1s5cbZ48vuhTjflRT5PjOFnr9GeUPZSIoZhYATYtME4JRKrXBtSkyioRNtE1xgghbGAyvAJ5jOWw88fLBF+P1ilsZyq72G1YcbB+co8ImQhAbWKmdCicO9/66Th2MB+7kms/oY3NaCzKEuR7J3b23dGrFpp4ccMM=</P><Q>xmxoSErIJCth91A3dSMjC6yQCu8=</Q><G>bwOLeEaoJHwSiC3i3qk9symlG/9kfzcgrkhRSWHqWhyPAfzqdV1KxJboMpeRoMoFr2+RqqKHgcdbzOypmTeN4QI/qh4nSsl5iEfVerarBOrFuRdOVcJO0d8WE233XQznd1K66nXa5L8d9SNZrM6umZ1YuBjhVsTFdPlIXKfGYhk=</G><Y>wZnEEdMUsF3U3NBQ8ebWHPOp37QRfiBn+7h5runN3YDee1e9bC7JbJf+Uq0eQmU8zDs+avEgD68NpxTKEHGr4nQ3rW6qqacj5SDbwO7nI6eN3wWrVhvrWcQm0tUO93m64HsEJREohfoL+LjqgrqIjZVT4D1KXE+k/iAb6WKAsIA=</Y><J>+zmcCCNm2kn1EXH9T45UcownEe7JH+gl3Lw2lhVzXuX/dYp5sGCA2lK119iQ+m3ogjOuwABATCVFLo6J66DsSlMd0I8WSD5WKPvypQ7QjY0Iv71J2N0FW0ZXpMlk/CE8zq4Z7arM1N564mNe</J><Seed>QDrZrUFowquY5Uay8YtUFOXnv28=</Seed><PgenCounter>Gg==</PgenCounter></DSAKeyValue>";
DSACryptoServiceProvider csp2 = new DSACryptoServiceProvider();
csp2.FromXmlString(key);
Console.WriteLine("Success!");
}
catch (Exception ex)
{
int hResult = 0;
try
{
PropertyInfo pi = typeof(Exception).GetProperty("HResult", BindingFlags.NonPublic | BindingFlags.Instance);
hResult = (int)pi.GetValue(ex, null);
}
catch (Exception ex2)
{
Console.WriteLine("HResult lookup failed: " + ex2.ToString());
}
Console.WriteLine("Initializing CSP failed: " + ex.ToString() + "\r\nHResult: " + hResult.ToString("x"));
}
Console.WriteLine("\r\nPress Enter to continue");
Console.ReadLine();
}
}
...和受影響用戶的機器上,它返回:
Initializing CSP failed: System.Security.Cryptography.CryptographicException: Ke
y not valid for use in specified state.
at System.Security.Cryptography.Utils.CreateProvHandle(CspParameters paramete
rs, Boolean randomKeyContainer)
at System.Security.Cryptography.Utils.get_StaticDssProvHandle()
at System.Security.Cryptography.DSACryptoServiceProvider.ImportParameters(DSA
Parameters parameters)
at System.Security.Cryptography.DSA.FromXmlString(String xmlString)
at Test.Main()
HResult: 8009000b
Updat e:在同一臺機器上運行.net fx 2.0時,相同的代碼工作正常,但在.net fx 4.0下失敗。
更新2:即使使用現有密鑰進行初始化,似乎DSA提供程序也會查找存儲在%APPDATA%\ Microsoft \ Crypto \ DSS \ [SID]下的密鑰。這個機制會不會有衝突?任何人都知道更多關於這個關鍵存儲器的操作方式,以及爲什麼從字符串中加載公鑰時碰到它?
增加了一個賞金... – KristoferA 2010-11-27 06:00:16