【问题标题】:Calling CryptAcquireContext from C# [closed]从 C# 调用 CryptAcquireContext [关闭]
【发布时间】:2017-06-03 10:10:00
【问题描述】:

我想在 C# 中使用 'CryptAcquireContext' WinAPI 函数。

我有using System.Runtime.InteropServices,我通过以下方式导入DLL:

[DllImport("advapi32.dll", CharSet = CharSet.Auto, SetLastError = true)]
[return: MarshalAs(UnmanagedType.Bool)]
static extern bool CryptAcquireContext(ref IntPtr hProv, string pszContainer, string pszProvider, uint dwProvType, uint dwFlags);

要调用该函数,我使用以下代码:

IntPtr handelTest = new IntPtr();
uint CRYPt_VERIFYCONTEXT = 0xF0000000;
uint PROV_RsA_FULL = 1;
bool res = CryptAcquireContext(ref handelTest, null, "MS_ENHANCED_PROV", PROV_RsA_FULL, CRYPt_VERIFYCONTEXT);
if (!res)
{
    int a = Marshal.GetLastWin32Error();
    Console.WriteLine("Error in Acqired, CryptAcquireContext function\n");
    return;
}
Console.WriteLine("Key Context Acquired\n");

但是,发生错误并res==false。 我的代码有什么问题?

【问题讨论】:

  • c 中的字符串通常以 byte[] 结尾,并以 '\0' 结尾。 C# 字符串/字符是两个字节,具有一个私有属性,用于确定字符是一个字节还是两个字节。在 c# 中,您使用 Encode 方法库方法将字符串转换为字节并将字节转换为字符串,这会自动执行一/两个字节的打包/解包。
  • 当我的参数是字符串时,我如何将字符串更改为字节,那就是错误
  • @jdweng DllImportAttribute 的 CharSet 属性负责处理。
  • a的值是多少?
  • MS_ENHANCED_PROV 是 wincrypt.h 中的 #define 包含实际提供程序名称,但您将其引用为字符串 ...

标签: c# winapi pinvoke


【解决方案1】:

这不是 P/Invoke 问题。参数很糟糕,GetLastError (a) 是 NTE_KEYSET_NOT_DEF / 0x80090019,即“请求的提供程序不存在。”。

传递 null 作为提供程序名称参数以继续,或使用有效的提供程序名称。

但是,请注意我会改为这样定义函数(确保 unicode,第一个参数是 out,而不是 ref):

[DllImport("advapi32.dll", CharSet = CharSet.Unicode, SetLastError = true)]
static extern bool CryptAcquireContext(out IntPtr hProv, string pszContainer, string pszProvider, uint dwProvType, uint dwFlags);

【讨论】:

  • 感谢您的帮助,1. 我将 'ref' 和 Unicode 更改为 'out' 和 'Unicode' 2. 在参数 3 中,提供程序名称我设置为“Microsoft Enhanced Cryptographic Provider v1.0” ,这就成功了,.....
猜你喜欢
  • 1970-01-01
  • 2021-03-26
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-12-19
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多