如何加密数据(char *)在C ++中的Windows crypto API和Pem密钥中使用rsa

时间:2018-12-17 08:53:24

标签: c++ encryption rsa

我必须从网站创建配对密钥(公共和私有(1024)): http://travistidwell.com/jsencrypt/demo/

例如这里是我的公共密钥:

-----BEGIN PUBLIC KEY-----
MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCGGKlBoNlzTJXoHGkRLum1kpsv
YRZEhZYpj3H2zfPAHLx6C5ElwbZHMBFarPl0lhP/Ydge3K9KeVmfahyGAz6Hq8LE
GnL5GYP+ef1ov5aMXSVxaWEkiu4BjvyRps5BedTWoyL6Tw7p15wVoxxO4c+mTlxz
6dxHFGpysm3mMAoajwIDAQAB
-----END PUBLIC KEY-----

这是我的私钥:

-----BEGIN RSA PRIVATE KEY-----
MIICXQIBAAKBgQCGGKlBoNlzTJXoHGkRLum1kpsvYRZEhZYpj3H2zfPAHLx6C5El
wbZHMBFarPl0lhP/Ydge3K9KeVmfahyGAz6Hq8LEGnL5GYP+ef1ov5aMXSVxaWEk
iu4BjvyRps5BedTWoyL6Tw7p15wVoxxO4c+mTlxz6dxHFGpysm3mMAoajwIDAQAB
AoGAJB9EiM9BhFOfFhWBIAXZIvZJI2wtyWuK1cs0Ud2MybVz+BRhlyAlb+u84QYz
dHpxDJxY0Yd1GMSzpcO5x0fccd8yPBXIY6Mk3fWZgwx9LcDASpAcaHwzOXFTAF6t
pjxDRry7aiFU6lggHrI09LYeFuBuet+ODLTrHlMuxodcFmECQQDNcoDgU0gxptTe
bKlr28BMpMoe1XrpPsi5VmeJmcukSkZdiYgIFoN9WrFMXQihzKfuQIyNmAJoFcNd
0m++5dGZAkEApxeh3C3/VW0Ga+xEnrJEXY9eDjUcuz1HU9vo1dwi3GSOeT/nqow6
MlAkWxo9edR1zDzNUPFKOj1g2M+kLRC2ZwJAONWeVXB0nle6t7VzwQTP0+QajiEc
mX3m5W7DwcssDM0HXkT3vtULlxgJyEhMZQZKxpxQxbLxp32tyDy48SR+sQJBAJlI
o7LR+4+Jgb+VsmmHDhJqSBVugdn+4CU88v7lgJGAKfdvOX4KQAUR4hg1HTpbPmlL
Seq8P6Tn06Vx7qFs2HcCQQCY2Od7cDSSm8cCJi1s3IL+Rtisnxvg45WqatZAORzM
ovkmQz2yai0gEnP826hrwNMsWe/tbsyCKb84B/Vh9v3d
-----END RSA PRIVATE KEY-----

最后是我的数据。

const char* Data = "Encrypt me";

现在我必须尝试使用​​RSA公钥对我的char *数据进行加密,仅使用c ++中的Windows加密api,并在加密后将加密的数据转换为BASE64编码。

然后想用我的私钥解密base64编码的加密数据。

如果您不知道,请不要回答或谈论cng!

这是我复制,编写,编辑的代码。现在不了解DWORD * outLength是什么问题

HCRYPTPROV _ServerContextHandle;
    HCRYPTKEY _EncryptionKeyHandle;

    char* inPublicKeyByPemFormat = (char*)"-----BEGIN PUBLIC KEY-----MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAjLqxm/bYHTwmjj9OT6vJH6BqghLSv4mLJ2AW8EKbmmYSLhv8jDu6GJTjKfrqeXaRXVtz5CxcWgb7f9y7PnAYEsp6GzLMn2SvHF/Q2HxQmBvw2bH0uXM9RC9wneqZcPW8x/qhhxBq3Ux+HQth3KpDdf24c6Ut2+6r6DBqrrFbJs73RwPukuFLNzbi/bWxh3Ib4pti0OoSHGylZRddwdGlqL0SEpuWt7ZdJYEHOQM4jFs/T6ThDTEsPytxYAEHWrckRcMIUIylMppCGy28ysguql5pZo+JHoyL+ZfOgPTzBwM8keXunCfPEaYn4fwjwWyFQHlZkMy6npyCD1zZ0Ke2FQIDAQAB-----END PUBLIC KEY-----";

    HCRYPTPROV serverContextHandle;

    bool result = CryptAcquireContextW(&serverContextHandle, NULL, NULL, PROV_RSA_FULL, CRYPT_VERIFYCONTEXT) == TRUE;

    if (result)
    {
        _ServerContextHandle = serverContextHandle;

        BYTE derPublicKey[2048];
        DWORD derPublicKeyLength = 2048;

        result = CryptStringToBinaryA(inPublicKeyByPemFormat, 0, CRYPT_STRING_BASE64HEADER, derPublicKey, &derPublicKeyLength, NULL, NULL) == TRUE;

        CERT_PUBLIC_KEY_INFO* publicKeyInfo = NULL;
        DWORD publicKeyInfoLength;

        if (result)
        {
            result = CryptDecodeObjectEx(X509_ASN_ENCODING | PKCS_7_ASN_ENCODING, X509_PUBLIC_KEY_INFO, derPublicKey, derPublicKeyLength, CRYPT_ENCODE_ALLOC_FLAG, NULL, &publicKeyInfo, &publicKeyInfoLength) == TRUE;
        }

        HCRYPTKEY encryptionKeyHandle;

        if (result)
        {
            result = CryptImportPublicKeyInfo(_ServerContextHandle, X509_ASN_ENCODING, publicKeyInfo, &encryptionKeyHandle) == TRUE;
        }

        LocalFree(publicKeyInfo);

        if (result)
        {
            _EncryptionKeyHandle = encryptionKeyHandle;
        }
    }
    BYTE* inData = (BYTE*)"Hello!";
    DWORD inDataLength = 6;
    DWORD* outLength = 0;

    BYTE* resulte = NULL;

    //*outLength = 0;

    DWORD length = inDataLength;

    result = inData;

    if (!CryptEncrypt(_EncryptionKeyHandle, NULL, TRUE, 0, resulte, &length, length))
    {
        delete resulte;

        result = new BYTE[length];

        resulte = inData;

        *outLength = inDataLength;

        if (!CryptEncrypt(_EncryptionKeyHandle, NULL, TRUE, 0, resulte, outLength, length))
        {
            delete resulte;

            resulte = NULL;

            *outLength = 0;
        }
    }
    else
    {
        *outLength = length;
    }

2 个答案:

答案 0 :(得分:0)

  

Cryptography API: Next Generation

     

密码学API:下一代(CNG)是长期的替代品   用于CryptoAPI。 CNG被设计为可在多个级别进行扩展,并且   密码学与行为无关。

该网站建议所有现有和新服务应开始使用此新API而不是CryptoAPI。 -Ref

编辑: 如果仅希望使用 old 第一代,则文档页面上有此example。这应该对您有帮助。 (代表人数少,所以我不允许发表评论)

答案 1 :(得分:0)

CryptAcquireContextCryptImportKeyCryptEncrypt

CryptoAPI导入不支持

Base64编码的密钥,您必须另存为DER。 您为什么仍然对所有这些旧东西感兴趣? CNG好多了。如果您来自类似openssl的公司,那么crypto和CNG API中的情况就大不相同了。

如果(在我看来)这是工作或学校的工作,那么您距离了解实际发生的事情还有点距离。