【问题标题】:C++ Importing RSA public keys from modulus and exponent with CNGC++ 使用 CNG 从模数和指数导入 RSA 公钥
【发布时间】:2017-05-30 15:45:13
【问题描述】:

我正在尝试使用 CNG 使用作为参数给出的公钥加密一些数据。调用 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;

我做错了什么?

【问题讨论】:

    标签: c++ cryptography cng


    【解决方案1】:

    RSA 公钥 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)
    

    【讨论】:

      【解决方案2】:

      BitLength 值是“密钥的大小”,对于 RSA,它的意思是“模数值的大小”。所以它与 cbModulus 有点多余,但是 c'est la vie。

      如果您在计算 BitLength 时删除 + 3,它可能会开始工作。与 .NET 为 RSACng.ImportParameters 构建 blob 相比:http://source.dot.net/#System.Security.Cryptography.Cng/Common/System/Security/Cryptography/RSACng.ImportExport.cs,79

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2015-06-22
        • 2018-06-10
        • 2015-10-13
        • 1970-01-01
        • 2023-03-21
        • 2012-07-17
        • 2022-11-22
        相关资源
        最近更新 更多