我在 Silverlight 中获取文件的数字签名时遇到了一些问题。
我正在使用 crypt32.dll 函数来获取签名哈希,但由于 CryptSignMessage 方法,我对意外错误感到困惑 - “参数不正确”。
这是我的代码:
public byte[] SignData(IntPtr certContext, string signingText)
{
IntPtr buffer = IntPtr.Zero;
Crypt32.CRYPT_SIGN_MESSAGE_PARA param = new Crypt32.CRYPT_SIGN_MESSAGE_PARA();
Byte[] result = null;
try
{
byte[] data = System.Text.Encoding.Unicode.GetBytes(signingText);
IntPtr[] rgpbToBeSigned = new IntPtr[1];
int[] rgcbToBeSigned = new int[1];
IntPtr pSignerCert = certContext;
buffer = Ole32.CoTaskMemAlloc((uint)(Marshal.SizeOf(data[0]) * data.Length));
Marshal.Copy(data, 0, buffer, data.Length);
rgpbToBeSigned[0] = buffer;
rgcbToBeSigned[0] = 1;
int resultlength = 0;
param.dwMsgEncodingType = Crypt32.Constants.X509_ASN_ENCODING;
param.pSigningCert = certContext;
param.cbSize = Marshal.SizeOf(param);
param.HashAlgorithm.pszObjId = "1.2.643.2.2.9";
param.HashAlgorithm.Parameters.cbData = 0;
param.HashAlgorithm.Parameters.pbData = null;
param.pvHashAuxInfo = IntPtr.Zero;
param.cMsgCert = 1;
param.rgpMsgCert = kernel32.GlobalAlloc(0, (UIntPtr)(IntPtr.Size));
Marshal.StructureToPtr(certContext, param.rgpMsgCert, false);
if (Crypt32.CryptSignMessage(ref param, true, (int)1, rgpbToBeSigned, rgcbToBeSigned, result, ref resultlength) == false)
throw new DB_Win32Exception(); //throws a string with error message from Getlastresult()
}
finally
{
if (!(param.rgpMsgCert == IntPtr.Zero))
kernel32.LocalFree(param.rgpMsgCert);
if (!(buffer == IntPtr.Zero))
Ole32.CoTaskMemFree(buffer);
}
这是我的外部方法声明:
[DllImport("Crypt32.dll", SetLastError = true)]
public static extern Boolean CryptSignMessage(
ref CRYPT_SIGN_MESSAGE_PARA pSignPara,
Boolean fDetachedSignature,
Int32 cToBeSigned,
IntPtr[] rgpbToBeSigned,
Int32[] rgcbToBeSigned,
Byte[] pbSignedBlob,
ref Int32 pcbSignedBlob
);
[StructLayout(LayoutKind.Sequential)]
public struct CRYPT_ALGORITHM_IDENTIFIER
{
[MarshalAs(UnmanagedType.LPStr, SizeConst = 100)] //???
public String pszObjId;
public CRYPTOAPI_BLOB Parameters;
}
[StructLayout(LayoutKind.Sequential)]
public struct CRYPT_SIGN_MESSAGE_PARA
{
public Int32 cbSize;
public Int32 dwMsgEncodingType;
public IntPtr pSigningCert;
public CRYPT_ALGORITHM_IDENTIFIER HashAlgorithm;
public IntPtr pvHashAuxInfo;
public Int32 cMsgCert;
public IntPtr rgpMsgCert;
public Int32 cMsgCrl;
public IntPtr rgpMsgCrl;
public Int32 cAuthAttr;
public IntPtr rgAuthAttr;
public Int32 cUnauthAttr;
public IntPtr rgUnauthAttr;
public Int32 dwFlags;
public Int32 dwInnerContentType;
}
public struct CRYPTOAPI_BLOB
{
public Int32 cbData;
[MarshalAs(UnmanagedType.ByValArray,SizeConst=999)] // ???
public Byte[] pbData;
}
有谁知道我如何确定问题出在哪里?