代码之家  ›  专栏  ›  技术社区  ›  rIPPER

在x64上从.NET调用CryptUIWizDigitalSign

  •  0
  • rIPPER  · 技术社区  · 16 年前

    我试图使用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;
    }
    
    1 回复  |  直到 16 年前
        1
  •  0
  •   maxwellb    16 年前

    您说过在编译到x86时它“起作用”。你能这么做吗?这让我相信cryptui.dll在您的搜索路径中是一个32位DLL。