Windows XP 与 Vista/7 上的 MS Crypto API 行为

2023-11-25

我试图了解如何在 XP、Vista 和 Windows 7 上从 PEM 格式(示例包含在下面的代码中)导入公钥。示例代码将在 XP 和 Windows Vista/7 上导入密钥,但不会一样的方法。

在 Windows XP 上,字符串“(原型)”加密提供者的名称中必需的,并允许传递对 CryptImportPublicKeyInfo 的调用。

在 Windows 7 上,“(原型)”提供程序显然存在,但不支持对 CryptImportPublicKeyInfo 的调用,这令人困惑。

这些操作系统之间的正确实现是什么样的?是否有必要检测XP并请求名称“(原型)”,并且对于其他操作系统没有它?是否有可能在某些 XP 系统上仍然会失败?

或者,有没有办法检测这种令人困惑的行为并选择哪个加密提供程序将支持必要的调用?

Windows 7 上的输出:

ANALYZING CRYPTOGRAPHIC SUPPORT FOR:
     "Microsoft Enhanced RSA and AES Cryptographic Provider"
     CryptAcquireContext success.
     CryptAcquireContext.1 success.
     CryptStringToBinary.2 success.
     CryptDecodeObjectEx success.
     CryptImportPublicKeyInfo success.
     SUCCESS.
ANALYZING CRYPTOGRAPHIC SUPPORT FOR:
     "Microsoft Enhanced RSA and AES Cryptographic Provider (Prototype)"
     CryptAcquireContext success.
     CryptAcquireContext.1 success.
     CryptStringToBinary.2 success.
     CryptDecodeObjectEx success.
     CryptImportPublicKeyInfo FAILED****.

Windows XP 上的输出:

ANALYZING CRYPTOGRAPHIC SUPPORT FOR:
     "Microsoft Enhanced RSA and AES Cryptographic Provider"
     CryptAcquireContext success.
     CryptAcquireContext.1 success.
     CryptStringToBinary.2 success.
     CryptDecodeObjectEx success.
     CryptImportPublicKeyInfo FAILED****.
ANALYZING CRYPTOGRAPHIC SUPPORT FOR:
     "Microsoft Enhanced RSA and AES Cryptographic Provider (Prototype)"
     CryptAcquireContext success.
     CryptAcquireContext.1 success.
     CryptStringToBinary.2 success.
     CryptDecodeObjectEx success.
     CryptImportPublicKeyInfo success.
     SUCCESS.

产生该输出的 C++ 源代码:(需要 crypt32.lib)

#include <stdio.h>
#include <tchar.h>
#include <windows.h>
#include <wincrypt.h>

bool windowsAcquireProviderContext(HCRYPTPROV *pHandleProv, LPCTSTR pProviderName);
bool analyzeCryptographicSupport(LPCTSTR pProviderName);

int _tmain(int argc, _TCHAR* argv[])
{
    analyzeCryptographicSupport(MS_ENH_RSA_AES_PROV);
    analyzeCryptographicSupport(L"Microsoft Enhanced RSA and AES Cryptographic Provider (Prototype)");
    return 0;
}

bool windowsAcquireProviderContext(HCRYPTPROV *pHandleProv, LPCTSTR pProviderName) {
    WCHAR *pContainerName = L"blah blah blah";
    if(!CryptAcquireContext(pHandleProv, pContainerName, pProviderName, PROV_RSA_AES, CRYPT_SILENT)) {
        if(GetLastError() == NTE_BAD_KEYSET) {
            if(CryptAcquireContext(pHandleProv, pContainerName, pProviderName, PROV_RSA_AES, CRYPT_NEWKEYSET|CRYPT_SILENT)) {
                return true;
            }
        } 
    }
    return true;
}

LPCWSTR pwszPemPublicKey = 
    L"-----BEGIN PUBLIC KEY-----\r\n"
    L"MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQC6GUVcbn92bahlwOskKi8XkG9q\r\n"
    L"Vq863+C4cOWC6HzJojc011pJFFIBu8/pG1EI8FZJdBmTrFaJTriYw1/SpbOH0QqE\r\n"
    L"eHanT8qWn+S5m9xgDJoWTBJKcnu3OHOvJJU3c8jOHQQnRWLfghJH4vnwStdiwUUY\r\n"
    L"SMWpwuHObsNelGBgEQIDAQAB\r\n"
    L"-----END PUBLIC KEY-----\r\n";
int pemPublicKeySize = wcslen(pwszPemPublicKey);

bool analyzeCryptographicSupport(LPCTSTR pProviderName) {

    printf("ANALYZING CRYPTOGRAPHIC SUPPORT FOR:\r\n");
    wprintf(L"\t \"%s\"\r\n", pProviderName);

    HCRYPTPROV hProv;
    if(!windowsAcquireProviderContext(&hProv, pProviderName)) {
        wprintf(L"\t CryptAcquireContext FAILED.\r\n");
        return false;
    }
    wprintf(L"\t CryptAcquireContext success.\r\n");

    DWORD blobSize;

    if(!CryptStringToBinary(pwszPemPublicKey, pemPublicKeySize, CRYPT_STRING_BASE64_ANY,  NULL, &blobSize, NULL, NULL)) {
        CryptReleaseContext(hProv, 0);
        wprintf(L"\t CryptStringToBinary.1 FAILED****.\r\n");
        return false;
    }
    wprintf(L"\t CryptAcquireContext.1 success.\r\n");

    BYTE *pBlob = (BYTE *)malloc(blobSize);

    if(!CryptStringToBinary(pwszPemPublicKey, pemPublicKeySize, CRYPT_STRING_BASE64_ANY,  pBlob, &blobSize, NULL, NULL)) {
        free(pBlob);
        CryptReleaseContext(hProv, 0);
        wprintf(L"\t CryptStringToBinary.2 FAILED****.\r\n");
        return false;
    }
    wprintf(L"\t CryptStringToBinary.2 success.\r\n");

    CERT_PUBLIC_KEY_INFO *publicKeyInfo;
    DWORD publicKeyInfoLen;
    HCRYPTKEY hPublicKey;

    if(!CryptDecodeObjectEx(X509_ASN_ENCODING|PKCS_7_ASN_ENCODING, X509_PUBLIC_KEY_INFO, pBlob, blobSize, CRYPT_DECODE_ALLOC_FLAG, NULL, &publicKeyInfo, &publicKeyInfoLen)) {
        free(pBlob);
        CryptReleaseContext(hProv, 0);
        wprintf(L"\t CryptDecodeObjectEx FAILED****.\r\n");
        return false;
    }
    wprintf(L"\t CryptDecodeObjectEx success.\r\n");

    if(!CryptImportPublicKeyInfo(hProv, X509_ASN_ENCODING|PKCS_7_ASN_ENCODING, publicKeyInfo, &hPublicKey)) {
        LocalFree(publicKeyInfo);
        free(pBlob);
        CryptReleaseContext(hProv, 0);
        wprintf(L"\t CryptImportPublicKeyInfo FAILED****.\r\n");
        return false;
    }
    wprintf(L"\t CryptImportPublicKeyInfo success.\r\n");

    CryptDestroyKey(hPublicKey);
    LocalFree(publicKeyInfo);
    free(pBlob);
    CryptReleaseContext(hProv, 0);

    wprintf(L"\t SUCCESS.\r\n");
    return true;
}

你所描述的问题的原因很简单:Microsoft 更名为 AES 加密提供商 from

  • "Microsoft Enhanced RSA and AES Cryptographic Provider (Prototype)"在 Windows XP 中
  • "Microsoft Enhanced RSA and AES Cryptographic Provider"在更高版本的操作系统中。

In WinCrypt.h定义相应的常数为MS_ENH_RSA_AES_PROV and MS_ENH_RSA_AES_PROV_XP您可以使用它。

如果您不想测试操作系统的版本,您可以使用地穴获取上下文 with NULL as pszProvider(并继续使用PROV_RSA_AES as the dwProvType)。在您的代码中您可以包含analyzeCryptographicSupport(NULL);.

您还可以检查注册表项的“名称”值

HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Cryptography\Defaults\Provider Types\Type 024

查看默认名称PROV_RSA_AES提供者。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Windows XP 与 Vista/7 上的 MS Crypto API 行为 的相关文章

  • 编译时运算符

    有人可以列出 C 中可用的所有编译时运算符吗 C 中有两个运算符 无论操作数如何 它们的结果始终可以在编译时确定 它们是sizeof 1 and 2 当然 其他运算符的许多特殊用途可以在编译时解决 例如标准中列出的那些整数常量表达式 1 与
  • EF Core Group By 翻译支持条件总和

    听说 EF Core 2 1 将支持翻译小组 我感到非常兴奋 我下载了预览版并开始测试它 但发现我在很多地方仍然没有得到翻译分组 在下面的代码片段中 对 TotalFlagCases 的查询将阻止翻译分组工作 无论如何 我可以重写这个以便我
  • C 编程 - 文件 - fwrite

    我有一个关于编程和文件的问题 while current NULL if current gt Id Doctor 0 current current gt next id doc current gt Id Doctor if curre
  • “构建”构建我的项目,“构建解决方案”则不构建

    我刚刚开始使用VS2010 我有一个较大的解决方案 已从 VS2008 成功迁移 我已将一个名为 Test 的控制台应用程序项目添加到解决方案中 选择构建 gt 构建解决方案不编译新项目 选择构建 gt 构建测试确实构建了项目 在失败的情况
  • 为什么两个不同的 Base64 字符串的转换会返回相等的字节数组?

    我想知道为什么从 base64 字符串转换会为不同的字符串返回相同的字节数组 const string s1 dg const string s2 dq byte a1 Convert FromBase64String s1 byte a2
  • 在哪里可以找到列出 SSE 内在函数操作的官方参考资料?

    是否有官方参考列出了 GCC 的 SSE 内部函数的操作 即 头文件中的函数 除了 Intel 的 vol 2 PDF 手册外 还有一个在线内在指南 https www intel com content www us en docs in
  • 不支持将数据直接绑定到存储查询(DbSet、DbQuery、DbSqlQuery)

    正在编码视觉工作室2012并使用实体模型作为我的数据层 但是 当页面尝试加载时 上面提到的标题 我使用 Linq 语句的下拉控件往往会引发未处理的异常 下面是我的代码 using AdventureWorksEntities dw new
  • 用于登录 .NET 的堆栈跟踪

    我编写了一个 logger exceptionfactory 模块 它使用 System Diagnostics StackTrace 从调用方法及其声明类型中获取属性 但我注意到 如果我在 Visual Studio 之外以发布模式运行代
  • HTTPWebResponse 响应字符串被截断

    应用程序正在与 REST 服务通信 Fiddler 显示作为 Apps 响应传入的完整良好 XML 响应 该应用程序位于法属波利尼西亚 在新西兰也有一个相同的副本 因此主要嫌疑人似乎在编码 但我们已经检查过 但空手而归 查看流读取器的输出字
  • 关于 C++ 转换:参数 1 从“[some_class]”到“[some_class]&”没有已知的转换

    我正在研究 C 并且遇到了一个错误 我不知道确切的原因 我已经找到了解决方案 但仍然想知道原因 class Base public void something Base b int main Base b b something Base
  • 不同枚举类型的范围和可转换性

    在什么条件下可以从一种枚举类型转换为另一种枚举类型 让我们考虑以下代码 include
  • 将多个表映射到实体框架中的单个实体类

    我正在开发一个旧数据库 该数据库有 2 个具有 1 1 关系的表 目前 我为每个定义的表定义了一种类型 1Test 1Result 我想将这些特定的表合并到一个类中 当前的类型如下所示 public class Result public
  • 显示UnityWebRequest的进度

    我正在尝试使用下载 assetbundle统一网络请求 https docs unity3d com ScriptReference Networking UnityWebRequest GetAssetBundle html并显示进度 根
  • 如何设计以 char* 指针作为类成员变量的类?

    首先我想介绍一下我的情况 我写了一些类 将 char 指针作为私有类成员 而且这个项目有 GUI 所以当单击按钮时 某些函数可能会执行多次 这些类是设计的单班在项目中 但是其中的某些函数可以执行多次 然后我发现我的项目存在内存泄漏 所以我想
  • 什么时候虚拟继承是一个好的设计? [复制]

    这个问题在这里已经有答案了 EDIT3 请务必在回答之前清楚地了解我要问的内容 有 EDIT2 和很多评论 有 或曾经 有很多答案清楚地表明了对问题的误解 我知道这也是我的错 对此感到抱歉 嗨 我查看了有关虚拟继承的问题 class B p
  • 如何使用 C# / .Net 将文件列表从 AWS S3 下载到我的设备?

    我希望下载存储在 S3 中的多个图像 但目前如果我只能下载一个就足够了 我有对象路径的信息 当我运行以下代码时 出现此错误 遇到错误 消息 读取对象时 访问被拒绝 我首先做一个亚马逊S3客户端基于我的密钥和访问配置的对象连接到服务器 然后创
  • 对现有视频添加水印

    我正在寻找一种用 C 在视频上加水印的方法 就像在上面写文字一样 图片或文字标签 我该怎么做 谢谢 您可以使用 Nreco 视频转换器 代码看起来像 NReco VideoConverter FFMpegConverter wrap new
  • WPF/C# 将自定义对象列表数据绑定到列表框?

    我在将自定义对象列表的数据绑定到ListBox in WPF 这是自定义对象 public class FileItem public string Name get set public string Path get set 这是列表
  • 为什么编译时浮点计算可能不会得到与运行时计算相同的结果?

    In the speaker mentioned Compile time floating point calculations might not have the same results as runtime calculation
  • 通过指向其基址的指针删除 POD 对象是否安全?

    事实上 我正在考虑那些微不足道的可破坏物体 而不仅仅是POD http en wikipedia org wiki Plain old data structure 我不确定 POD 是否可以有基类 当我读到这个解释时is triviall

随机推荐

  • 内存泄漏调试

    如果没有跟踪工具 有哪些检测 调试内存泄漏的技术 拦截所有分配和释放内存的函数 根据平台的不同 列表可能如下所示 malloc calloc realloc strdup getcwd free 除了执行这些函数最初执行的操作之外 还将有关
  • 如何强制 ssh 从命令行接受新的主机指纹?

    我得到了标准 WARNING REMOTE HOST IDENTIFICATION HAS CHANGED IT IS POSSIBLE THAT SOMEONE IS DOING SOMETHING NASTY Someone could
  • 使下拉菜单可滚动

    我正在尝试使用 CSS 和 jquery 在 HTML 页面中实现下拉菜单 以下是 HTML 和 JavaScript 代码的示例
  • Chrome tabs.onActivated.addListener 抛出“未定义”TypeError

    我正在做一个 chrome 扩展 文档中有这个说法 about chrome tabs onActivated 每当我尝试放置chrome tabs onActivated addListener 它说Uncaught TypeError
  • 使用 HTMLAgilityPack 仅提取页面文本

    好的 我对 HTMLAgilityPack 中使用的 XPath 查询非常陌生 所以让我们考虑这个页面http health yahoo net articles healthcare what your favorite flavor s
  • Qt - 没有这样的信号错误

    我试图在双击可拖动小部件之一时触发信号冰箱贴示例 以下是我对示例源代码所做的更改 拖动标签 class DragLabel public QLabel public DragLabel const QString text QWidget
  • 如何在Python中使用BeautifulSoup解析google搜索结果

    我正在尝试解析谷歌搜索结果的第一页 具体来说 是提供的标题和小摘要 这是我到目前为止所拥有的 from urllib request import urlretrieve import urllib parse from urllib pa
  • 获取特定用户的last_login时间? (姜戈)

    我有代码User objects values list last login flat True 这为我提供了所有用户最后一次登录的列表 但我不确定您如何精简对特定用户所做的操作 我尝试了以下代码User objects get user
  • 将浮点数序列化为 32 位整数的可移植方法

    我一直在努力寻找一种可移植的方法来序列化 C 和 C 中的 32 位浮点变量 以便将其发送到微控制器或从微控制器发送 我希望格式定义得足够好 以便序列化 反序列化也可以从其他语言完成 而不需要太多的努力 相关问题有 C 中 double f
  • PDO 多重查询

    从 PHP 版本 5 3 开始PDO MYSQL驱动程序已被替换为有利于PDO MYSQLND 它引入了对多个查询的支持 不过 如果有多个结果集 我不知道如何获得两个结果集SELECT查询已通过 两个查询都已执行 不可能是第二个查询刚刚被转
  • 删除 UICollectionView 边缘的单元格 - 滚动后单元格不会立即出现

    考虑一个标准的垂直滚动流布局 其中填充了足够的单元格以引起滚动 当滚动到底部时 如果删除一个项目 使得集合视图的内容大小必须缩小以容纳新的项目数 即删除底行的最后一个项目 则从滚动到底部的单元格行顶部被隐藏 在删除动画结束时 顶行出现时没有
  • 如何在angularjs中将html数据导出为pdf

    这是我渲染所有内容的 html 代码json数据来自 js文件但得到 类型错误 无法将未定义或 null 转换为对象 在Function keys 处 在 DocMeasure measureNode pdfmake js 15647 在
  • matlab中的3D体素显示

    我有一个网格 它是 3D 的并且存储一个数字 这是我的网格的示例 如果它是 2 2 2 1 gt 0 0 0 0 2 gt 0 0 0 0 如果那里不存在体素 数字 0 通常是我想用颜色或 nan 表示的数字 我想做的是用 matlab 显
  • 是否可以使 display:table-cell 布局响应式?

    在我的代码中 有一个表 其中有一个分区 其中的表行由水平的复选框组成 这是我的示例代码 完整的代码在小提琴中Here HTML table cellpadding 0 border 0 width 100 cellspacing 0 tr
  • BouncyCastle 上的椭圆曲线与数字签名算法 (ECDSA) 实施

    我正在尝试实现 ECDSA 椭圆曲线数字签名算法 但我在 Java 中找不到任何使用 Bouncy Castle 的示例 我创建了密钥 但我真的不知道应该使用什么样的函数来创建签名并验证它 public static KeyPair Gen
  • numpy.rint 可以返回 Int32 吗?

    我正在做 ret np rint y 4 return ret 我希望它回来Int32 我尝试添加dtype Int32 但它错误地说 TypeError No loop matching the specified signature a
  • 如何使用 OpenCV 制作反向填充透明矩形?

    我想在这张图片中制作一个反向填充的矩形 我的代码 import cv2 lena cv2 imread lena png output lena copy cv2 rectangle lena 100 100 200 200 0 0 255
  • ReportLab 图片链接

    有没有办法在 ReportLab 中向 Platypus 图像对象添加 href 链接 我知道如何在段落中的文本上添加链接 但我似乎找不到有关添加图像链接的任何信息 这可以通过以下方式轻松实现超链接图像类米斯梅利提出 from report
  • C 中允许的静态数组的最大大小是多少?

    在我的算法中 我知道使用静态数组 而不是动态数组 但我有时 达到堆栈的极限 我对吗 静态数组存储在堆栈中 哪些参数会影响一个 C 程序的最大堆栈大小 是否有许多系统参数影响最大数组大小 最大没有 元素的数量取决于数组类型 它取决于系统 RA
  • Windows XP 与 Vista/7 上的 MS Crypto API 行为

    我试图了解如何在 XP Vista 和 Windows 7 上从 PEM 格式 示例包含在下面的代码中 导入公钥 示例代码将在 XP 和 Windows Vista 7 上导入密钥 但不会一样的方法 在 Windows XP 上 字符串 原