- android - RelativeLayout 背景可绘制重叠内容
- android - 如何链接 cpufeatures lib 以获取 native android 库?
- java - OnItemClickListener 不起作用,但 OnLongItemClickListener 在自定义 ListView 中起作用
- java - Android 文件转字符串
我正在尝试了解如何在 XP、Vista 和 Windows 7 中获取从 PEM 格式(示例包含在下面的代码中)导入的公钥。示例代码将在 XP 和 Windows Vista/7 上导入 key , 但方式不同。
在 Windows XP 上,密码提供者的名称中需要字符串 "(Prototype)",并允许对 CryptImportPublicKeyInfo 的调用通过。
在 Windows 7 上,"(Prototype)" 提供程序显然存在,但不支持对 CryptImportPublicKeyInfo 的调用,这令人困惑。
这些操作系统之间的正确实现是什么样的?是否有必要检测 XP 并请求带有 "(Prototype)" 的名称,而没有它用于其他操作系统?是否有可能在某些 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 renamed AES Cryptographic Provider from
Windows XP 中的“Microsoft 增强型 RSA 和 AES 加密提供程序(原型(prototype))”
“Microsoft Enhanced RSA and AES Cryptographic Provider”
在更高版本的操作系统中。 在 WinCrypt.h
中定义了相应的常量作为 MS_ENH_RSA_AES_PROV
和 MS_ENH_RSA_AES_PROV_XP
可以使用。
如果你不想测试操作系统的版本你可以使用CryptAcquireContext使用 NULL
作为 pszProvider
(并继续使用 PROV_RSA_AES
作为 dwProvType
)。在您的代码中,您可以包含 analyzeCryptographicSupport(NULL);
。
您还可以检查注册表项的“名称”值
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Cryptography\Defaults\Provider Types\Type 024
查看默认 PROV_RSA_AES
提供商的名称。
关于c++ - Windows XP 与 Vista/7 上的 MS Crypto API 行为,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4495247/
我正在尝试更新一些较旧的代码以消除警告。我已经升级了一些使用加密模块的代码。然而,webpack 5.88.2没有识别新的语法。我的新导入内容如下所示:。完整的错误如下所示。这表明我可能需要另一个插件
是否有任何 C 或 C++ 函数可以产生与此 python 代码相同的输出(SHA512 with salt)? import crypt; crypt.crypt('test', '$6$Salte
我正在开发一个使用 Crypto++ 使用 RSA 加密一些数据的项目。 这是我的 Crypto++ 代码: string plain = "Text123", encoded, cipher; st
收到错误,因为 require 不是一个函数,尝试在 typescript 组件中使用加密 js 函数 // Load modules 'use strict'; var Crypto = requi
我正在尝试将下面的java代码转换为nodejs。 public static String encrypt(String accessToken) throws Exception {
我有一个旨在在 Node.js 中使用的签名方法,但我想使用 crypto-js 在客户端实现它。它应该可以在最新的 Chrome 版本中运行。 我尝试遵循以下一些答案:Decode a Base64
我想知道 Crypto.Signature.PKCS1_v1_5 和 Crypto.Signature.pkcs1_15 有什么区别? 在documentation他们使用此函数 Crypto.Sig
我们有一个使用 Crypto++ 库的 ECC 部分的 C++ 解决方案,但必须转移到 .NET 解决方案。由于 Microsoft 的 ECC 代码的文档最少,我目前正在试验文档最少的 Bouncy
我在验证 Web Crypto API 创建的签名时遇到问题。 这是我用来在浏览器中生成 RSA key 的代码: let keys; const generateKeys = async () =>
嗨,所以我有一个运行 Crypto 的服务器,它工作得很好。我使用 electrojs 作为客户端,并且加密应该内置到 Node 中。当我尝试使用该模块时,它返回“crypto.scryptSync
使用 Apple 的 Common Crypto 和 Crypto++ 使用相同的 key 加密相同的文件(二进制数据)时,我得到了不同的结果。我使用的算法是 AES。 这是使用 Common Cry
如何存储 crypto.createHash('sha1') 的当前状态(在它被 hash.update(buffer) 填充后)以在另一个地方使用它http请求可能发生在node.js的不同进程?
我正在使用 NodeJS 的捆绑 crypto服务器端的 SHA256 哈希模块。在客户端,我使用一个名为 Crypto-JS 的 javascript 库. 我将 SHA256 哈希值用于使用基于经
我想编写一个使用 linux crypto-api 进行数字签名的 C 程序。不幸的是,我找不到关于 linux api 和 linux/crypto.h 中定义的函数的良好文档(谷歌搜索没有帮助,这
我正在尝试使用 JUNIT 在实际执行 AES 加密的方法中模拟 cipher.doFinal()。我在启动 JUNIT 测试用例时遇到异常 "Tried to access class javax.
您好,我在Liferay dxp项目中使用Paytm校验和依赖项 但我得到error :com.sun.crypto.provider.AESCipher$General cannot be cast
我正在尝试使用 crypto-js javascript 库加密数据,并尝试使用 Node 加密库在 Nodejs 端解密相同的加密文本。我正在使用 AES 256 加密算法和 CTR 模式,没有填充
我想了解 javax.crypto.Mac 之间的区别和 javax.crypto.Cipher 。这两个类看起来非常相似(它们具有相似的方法,但是这两个类并不互相继承)。 这两个类之间的根本区别是什
我正在尝试在设备上生成 SHA256 和 HmacSHA512 哈希值,不幸的是,该设备不支持标准 Node crypto 库。所以我正在调整代码以使用 CryptoJS 代替。但是,CryptoJS
我正在使用 Android FingerPrintManager API 并使用 KeyPairGenerator 创建 key 对,我想使用公钥加密密码,然后在用户通过输入 fingerPrint
我是一名优秀的程序员,十分优秀!