我试图使用CryptUIWizDigitalSign函数对编译到AnyCPU的.net2.0应用程序中的文件进行数字签名。该调用在x86上运行时工作正常,但在x64上失败,在x64操作系统上编译为x86时也可以工作。有什么更好的马歇尔或从x64打电话吗?
返回的Win32exception是“在对文件进行数字签名时遇到错误…”,本机错误代码为-2146762749。
准则的相关部分包括:
[StructLayout(LayoutKind.Sequential)]
public struct CRYPTUI_WIZ_DIGITAL_SIGN_INFO {
public Int32 dwSize;
public Int32 dwSubjectChoice;
[MarshalAs(UnmanagedType.LPWStr)]
public string pwszFileName;
public Int32 dwSigningCertChoice;
public IntPtr pSigningCertContext;
[MarshalAs(UnmanagedType.LPWStr)]
public string pwszTimestampURL;
public Int32 dwAdditionalCertChoice;
public IntPtr pSignExtInfo;
}
[DllImport("Cryptui.dll", CharSet=CharSet.Unicode, SetLastError=true)]
public static extern bool CryptUIWizDigitalSign(int dwFlags, IntPtr hwndParent, string pwszWizardTitle, ref CRYPTUI_WIZ_DIGITAL_SIGN_INFO pDigitalSignInfo, ref IntPtr ppSignContext);
CRYPTUI_WIZ_DIGITAL_SIGN_INFO digitalSignInfo = new CRYPTUI_WIZ_DIGITAL_SIGN_INFO();
digitalSignInfo = new CRYPTUI_WIZ_DIGITAL_SIGN_INFO();
digitalSignInfo.dwSize = Marshal.SizeOf(digitalSignInfo);
digitalSignInfo.dwSubjectChoice = 1;
digitalSignInfo.dwSigningCertChoice = 1;
digitalSignInfo.pSigningCertContext = pSigningCertContext;
digitalSignInfo.pwszTimestampURL = timestampUrl;
digitalSignInfo.dwAdditionalCertChoice = 0;
digitalSignInfo.pSignExtInfo = IntPtr.Zero;
digitalSignInfo.pwszFileName = filepath;
CryptUIWizDigitalSign(1, IntPtr.Zero, null, ref digitalSignInfo, ref pSignContext));
下面是如何检索SigningCertContext(减去各种错误处理)
public IntPtr GetCertContext(String pfxfilename, String pswd)
IntPtr hMemStore = IntPtr.Zero;
IntPtr hCertCntxt = IntPtr.Zero;
IntPtr pProvInfo = IntPtr.Zero;
uint provinfosize = 0;
try {
byte[] pfxdata = PfxUtility.GetFileBytes(pfxfilename);
CRYPT_DATA_BLOB ppfx = new CRYPT_DATA_BLOB();
ppfx.cbData = pfxdata.Length;
ppfx.pbData = Marshal.AllocHGlobal(pfxdata.Length);
Marshal.Copy(pfxdata, 0, ppfx.pbData, pfxdata.Length);
hMemStore = Win32.PFXImportCertStore(ref ppfx, pswd, CRYPT_USER_KEYSET);
pswd = null;
if (hMemStore != IntPtr.Zero) {
Marshal.FreeHGlobal(ppfx.pbData);
while ((hCertCntxt = Win32.CertEnumCertificatesInStore(hMemStore, hCertCntxt)) != IntPtr.Zero) {
if (Win32.CertGetCertificateContextProperty(hCertCntxt, CERT_KEY_PROV_INFO_PROP_ID, IntPtr.Zero, ref provinfosize))
pProvInfo = Marshal.AllocHGlobal((int)provinfosize);
else
continue;
if (Win32.CertGetCertificateContextProperty(hCertCntxt, CERT_KEY_PROV_INFO_PROP_ID, pProvInfo, ref provinfosize))
break;
}
}
finally {
if (pProvInfo != IntPtr.Zero)
Marshal.FreeHGlobal(pProvInfo);
if (hMemStore != IntPtr.Zero)
Win32.CertCloseStore(hMemStore, 0);
}
return hCertCntxt;
}