C++ 使用 CNG 从模数和指数导入 RSA public 密钥
C++ Importing RSA public keys from modulus and exponent with CNG
我正在尝试使用 CNG 通过作为参数提供的 public 密钥来加密一些数据。调用 NCryptImportKey 函数时,出现 NTE_BAD_DATA 错误 which isn't listed in the msdn page.
我的代码:
#include <iostream>
#include <Windows.h>
#include <Bcrypt.h>
#include <Ntstatus.h>
#include <string>
#include <vector>
#include "base64.h"
using std::string;
using std::vector;
struct MyRSAPublicBlob {
BCRYPT_RSAKEY_BLOB blob;
BYTE exponent[3];
BYTE modulus[128];
MyRSAPublicBlob(const vector<BYTE>& mod, const vector<BYTE>& exp)
{
blob.BitLength = (128 + 3) * 8;
blob.Magic = BCRYPT_RSAPUBLIC_MAGIC;
blob.cbModulus = 128;
blob.cbPublicExp = 3;
for (size_t i = 0; i < mod.size(); ++i) //copy BigEndian
modulus[i] = mod[mod.size() - 1 - i];
for (size_t i = 0; i < exp.size(); ++i) //copy BigEndian
exponent[i] = exp[exp.size() - 1 - i];
}
MyRSAPublicBlob() { ; }
};
MyRSAPublicBlob b;
bool RSA_encrypt() {
SECURITY_STATUS stat;
NCRYPT_PROV_HANDLE hProv;
NCRYPT_KEY_HANDLE hKey;
stat = NCryptOpenStorageProvider(&hProv, MS_KEY_STORAGE_PROVIDER, 0);
if (ERROR_SUCCESS != stat) {
std::cout << "failed in NCryptOpenStorageProvider: " << GetLastError() << std::endl;
return false;
}
stat = NCryptImportKey(hProv,
NULL,
BCRYPT_RSAPUBLIC_BLOB,
NULL,
&hKey,
(PBYTE)&b.blob,
sizeof(b),
0);
if (ERROR_SUCCESS != stat) {
std::cout << "failed in NCryptImportKey: " << GetLastError() << std::endl;
return false;
}
我如何构造 MyRSAPublicBlob 的示例:
string PubKeyModulus = "yVUndgQFuB5Z5FgC0/WgWCg6Y8VuB582avGjQDdeoJDa1+RBKCyXo700sAMSGjM/bVakOlFqvCsVFNBysx1CH731CDb2DR1a0bsmYmDQ9d0ZHX+AOohVDIx9mc7bkDQZoEFpe9NqFsu95Y9yktpl1JKPmKyLOFgufGJYYvQyoOM=";
string PubKeyExp = "AQAB";
vector<BYTE> PubKeyModulus_bin = base64_decode(PubKeyModulus);
vector<BYTE> PubKeyExp_bin = base64_decode(PubKeyExp);
struct MyRSAPublicBlob c(PubKeyModulus_bin, PubKeyExp_bin);
b = c;
我做错了什么吗?
BitLength
值是 "size of the key",对于 RSA 来说意味着 "the size of the Modulus value"。所以 cbModulus 有点多余,但 c'est la vie。
如果您在计算 BitLength 时删除 + 3
,它可能会开始工作。与为 RSACng.ImportParameters
构建 blob 的 .NET 相比:http://source.dot.net/#System.Security.Cryptography.Cng/Common/System/Security/Cryptography/RSACng.ImportExport.cs,79
RSA public 密钥 BLOB (BCRYPT_RSAPUBLIC_BLOB) 在 连续 内存中具有以下格式。尝试使用#pragma pack 来避免任何填充问题。例如,
#pragma pack(push, 1)
struct MyRSAPublicBlob {
BCRYPT_RSAKEY_BLOB blob;
BYTE exponent[3];
BYTE modulus[32];
...};
#pragma pack(pop)
我正在尝试使用 CNG 通过作为参数提供的 public 密钥来加密一些数据。调用 NCryptImportKey 函数时,出现 NTE_BAD_DATA 错误 which isn't listed in the msdn page.
我的代码:
#include <iostream>
#include <Windows.h>
#include <Bcrypt.h>
#include <Ntstatus.h>
#include <string>
#include <vector>
#include "base64.h"
using std::string;
using std::vector;
struct MyRSAPublicBlob {
BCRYPT_RSAKEY_BLOB blob;
BYTE exponent[3];
BYTE modulus[128];
MyRSAPublicBlob(const vector<BYTE>& mod, const vector<BYTE>& exp)
{
blob.BitLength = (128 + 3) * 8;
blob.Magic = BCRYPT_RSAPUBLIC_MAGIC;
blob.cbModulus = 128;
blob.cbPublicExp = 3;
for (size_t i = 0; i < mod.size(); ++i) //copy BigEndian
modulus[i] = mod[mod.size() - 1 - i];
for (size_t i = 0; i < exp.size(); ++i) //copy BigEndian
exponent[i] = exp[exp.size() - 1 - i];
}
MyRSAPublicBlob() { ; }
};
MyRSAPublicBlob b;
bool RSA_encrypt() {
SECURITY_STATUS stat;
NCRYPT_PROV_HANDLE hProv;
NCRYPT_KEY_HANDLE hKey;
stat = NCryptOpenStorageProvider(&hProv, MS_KEY_STORAGE_PROVIDER, 0);
if (ERROR_SUCCESS != stat) {
std::cout << "failed in NCryptOpenStorageProvider: " << GetLastError() << std::endl;
return false;
}
stat = NCryptImportKey(hProv,
NULL,
BCRYPT_RSAPUBLIC_BLOB,
NULL,
&hKey,
(PBYTE)&b.blob,
sizeof(b),
0);
if (ERROR_SUCCESS != stat) {
std::cout << "failed in NCryptImportKey: " << GetLastError() << std::endl;
return false;
}
我如何构造 MyRSAPublicBlob 的示例:
string PubKeyModulus = "yVUndgQFuB5Z5FgC0/WgWCg6Y8VuB582avGjQDdeoJDa1+RBKCyXo700sAMSGjM/bVakOlFqvCsVFNBysx1CH731CDb2DR1a0bsmYmDQ9d0ZHX+AOohVDIx9mc7bkDQZoEFpe9NqFsu95Y9yktpl1JKPmKyLOFgufGJYYvQyoOM=";
string PubKeyExp = "AQAB";
vector<BYTE> PubKeyModulus_bin = base64_decode(PubKeyModulus);
vector<BYTE> PubKeyExp_bin = base64_decode(PubKeyExp);
struct MyRSAPublicBlob c(PubKeyModulus_bin, PubKeyExp_bin);
b = c;
我做错了什么吗?
BitLength
值是 "size of the key",对于 RSA 来说意味着 "the size of the Modulus value"。所以 cbModulus 有点多余,但 c'est la vie。
如果您在计算 BitLength 时删除 + 3
,它可能会开始工作。与为 RSACng.ImportParameters
构建 blob 的 .NET 相比:http://source.dot.net/#System.Security.Cryptography.Cng/Common/System/Security/Cryptography/RSACng.ImportExport.cs,79
RSA public 密钥 BLOB (BCRYPT_RSAPUBLIC_BLOB) 在 连续 内存中具有以下格式。尝试使用#pragma pack 来避免任何填充问题。例如,
#pragma pack(push, 1)
struct MyRSAPublicBlob {
BCRYPT_RSAKEY_BLOB blob;
BYTE exponent[3];
BYTE modulus[32];
...};
#pragma pack(pop)