c++ 和 node.js 之间的 RSA 加密

RSA encryption between c++ and node.js

我必须通过网络 (websocket) 发送一些加密数据

我使用以下 node.js 模块生成了密钥对:

https://github.com/juliangruber/keypair

我的 public 密钥如下所示:

-----BEGIN RSA PUBLIC KEY-----
MIIBCgKCAQEAlUiMDQsBgj5P/T86w/eg9MXUj8M4WMVihP8YzmDxMqCFb7D+w4N/1XcxWxQT
....
Wo+SRCsr6npfp1ctDhMtkXIeNT4lKf3qUGhP5tbx/TreaNF/d8zCeinGR/KeBGadMwIDAQAB
-----END RSA PUBLIC KEY-----

在 C++ 代码中,我通过 char*

读取 public 密钥生成了一个 RSA class
const char rsaKey1[] = "-----BEGIN RSA PUBLIC KEY-----\n"
"MIIBCgKCAQEAlUiMDQsBgj5P/T86w/eg9MXUj8M4WMVihP8YzmDxMqCFb7D+w4N/1XcxWxQT\n"
....
"Wo+SRCsr6npfp1ctDhMtkXIeNT4lKf3qUGhP5tbx/TreaNF/d8zCeinGR/KeBGadMwIDAQAB\n"
"-----END RSA PUBLIC KEY-----\n";


BIO* bio = BIO_new_mem_buf( rsaKey1, strlen(rsaKey1)); 

m_rsaPubKey = PEM_read_bio_RSAPublicKey(bio, NULL, NULL, NULL);

使用 m_rsaPubKey 签名,我可以用加密数据生成 std::vector 的无符号字符

 std::vector<u8> Rsa::encrypt(std::string & msg)
 {

    std::vector<u8> encryptedData;

    char *encrypt = new char[RSA_size(m_rsaPubKey)];

    int encryptLen;

    if (encryptLen = RSA_public_encrypt(msg.size() + 1, (unsigned 
    char*)msg.c_str(), (unsigned char*)encrypt, m_rsaPubKey, 
    RSA_PKCS1_OAEP_PADDING) == -1)
    {
        LogOutSys("error encoding string");
    }

    for (u32 i = 0; i < strlen(encrypt); i++)
    {
        encryptedData.push_back(encrypt[i]);
    }

    delete encrypt;

    return encryptedData;
}

我在读取 public 密钥或加密我的数据时没有收到任何错误,所以我认为加密是正确的。

然后数据通过 websocket 并通过 node.js

接收

私钥是这样读的:

var rsa = new RSA(fs.readFileSync("./rsa-keys/sj_private_1.pem"),
{encryptionScheme :'pkcs8'})

和解码

 var decrypted = rsa.decrypt(data)

其中数据是长度和内容相同的缓冲区(通过 websocket 发送时没有损坏)

c++ 方面:

encrypted len 256, first bytes 117 125 58 109

节点大小:

Buffer(256) [117, 125, 58, 109, 38, 229, 7, 189, …]

rsa.decrypt 生成异常:

TypeError: Cannot read property 'length' of null

我尝试了几个 encryptionScheme 选项(包括默认的,但总是得到相同的错误或不正确的密钥或数据

由于 OAEP 中的随机填充,解决加密问题有时会有些棘手。

要进一步排除故障,请使用以下清单来解决潜在问题:

  • 确保您在两端使用相同的加密机制。在您的 C++ 代码中,您使用的是 RSA_PKCS1_OAEP_PADDING 但问题中的 JavaScript 行并未说明您在那里使用的机制。
  • 确保机制在 C++ 和 Node 库中的实现方式相同。在两种实现中使用相同的散列方法和 MGF1(掩码生成函数)至关重要。这是我在职业生涯中见过的最典型的失败点之一。
  • 由于您使用的是字节数组,请确保字节顺序没有任何问题。换句话说,确保两端在字节顺序方面使用相同的语言(自学:https://www.cs.umd.edu/class/sum2003/cmsc311/Notes/Data/endian.html)。