我想更改调用需要智能卡PIN的CryptoApi操作时显示的文本。当前提示非常通用(并且使用系统语言),"请输入您的身份验证PIN":
此对话框显示在COM对象中调用CryptSignMessage
时,但调用是从C#WPF桌面应用程序(.NET 4.5)进行的。如何自定义对话框?我找到PP_PIN_PROMPT_STRING
函数的CryptSetProvParam
参数,但该函数需要HCRYPTPROV
而我没有这个句柄。我所拥有的只是读者的姓名和签名证书。只是无法绕过它。
是否可以从C ++或C#(最好是C#)自定义PIN对话框?
答案 0 :(得分:1)
我相信以下内容应该有效。因为我没有任何设置来测试收集我无法验证的信息。
[DllImport("advapi32.dll", SetLastError = true, CharSet = CharSet.Auto)]
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool CryptAcquireContext(out IntPtr phProv, string pszContainer, string pszProvider, uint dwProvType, uint dwFlags);
[DllImport("advapi32.dll", SetLastError = true, CharSet = CharSet.Auto)]
[return: MarshalAs(UnmanagedType.Bool)]
static extern bool CryptSetProvParam(IntPtr hProv, uint dwParam, [In] byte[] pbData, uint dwFlags);
[DllImport("advapi32.dll")]
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool CryptReleaseContext(IntPtr hProv, uint dwFlags);
const string MS_DEF_PROV = "Microsoft Base Cryptographic Provider v1.0";
const uint NTE_BAD_KEYSET = 0x80090016;
const uint PROV_RSA_FULL = 1;
const uint CRYPT_VERIFYCONTEXT = 0xF0000000;
const uint CRYPT_NEWKEYSET = 0x00000008;
const uint PP_PIN_PROMPT_STRING = 0x2C;
public unsafe void SetPinText(string text)
{
byte[] data = Encoding.UTF8.GetBytes(text);
IntPtr hCryptProv;
try
{
if (!CryptAcquireContext(out hCryptProv, null, MS_DEF_PROV, PROV_RSA_FULL, CRYPT_VERIFYCONTEXT))
{
if (Marshal.GetLastWin32Error() == NTE_BAD_KEYSET)
{
if (!CryptAcquireContext(out hCryptProv, null, null, PROV_RSA_FULL, CRYPT_NEWKEYSET))
throw new Exception("Unable to acquire crypt context.");
}
else
{
throw new Exception("Unable to acquire crypt context.");
}
}
if (!CryptSetProvParam(hCryptProv, PP_PIN_PROMPT_STRING, DataColumn, 0))
throw new Exception("Unable to set prompt string.");
}
finally
{
if (hCryptProv != IntPtr.Zero)
{
CryptReleaseContext(hCryptProv, 0);
}
}
}