AnyCPU로 컴파일 된 .NET 2.0 응용 프로그램의 CryptUIWizDigitalSign 함수를 사용하여 파일에 디지털 서명을 시도합니다. 이 호출은 x86에서 실행 중이지만 x64에서는 실패하고 x86으로 컴파일 될 때 x64 OS에서도 작동합니다. x64에서 더 나은 마샬링이나 전화를하는 방법에 대한 아이디어가 있습니까?x64에서 .NET의 CryptUIWizDigitalSign 호출
반환 된 Win32 예외는 원시 오류 코드 -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;
}
나는 어떤 실수도 보이지 않는다. pSigningCertContext가 초기화 된 것을 볼 수 없습니다. "실패"및 Marshal.GetLastWin32Error 반환 값을 설명하십시오. –