2010-05-17 3 views
0

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; 
} 
+0

나는 어떤 실수도 보이지 않는다. pSigningCertContext가 초기화 된 것을 볼 수 없습니다. "실패"및 Marshal.GetLastWin32Error 반환 값을 설명하십시오. –

답변

0

응용 프로그램 anycpu를 목표로 컴파일 할 때, 그들은 것 32 비트 OS에서는 32 비트, 64 비트 OS에서는 64 비트로로드됩니다. 64 비트 프로세스에서 32 비트 DLL을로드 할 수 없습니다.

x86으로 컴파일 할 때 "작동"한다고 말했습니다. 너 그냥 할 수있어? 이로 인해 검색 경로에있는 cryptui.dll이 32 비트 DLL이라고 생각하게됩니다.