14

我正在做一些密码学实验。现在我有了接收者的公钥,我想加密一些数据并传递给接收者。

我想使用 RSAES-OAEP 算法。SHA-256 作为散列函数,MGF1 作为掩码生成函数。

我想使用 openssl 来做到这一点。我找到了一个RSA_public_encrypt()带有这个函数的函数,我们可以指定填充。可用的填充选项之一是

RSA_PKCS1_OAEP_PADDING
EME-OAEP 在 PKCS #1 v2.0 中定义,带有 SHA-1 , MGF1 。

他们正在使用sha-1。

我想重新配置函数以使用 SHA256 作为散列函数和 MGF1 作为散列函数。我该怎么做 ?

4

5 回答 5

5

以下摘录允许将 OAEP 与 SHA256 一起用于 MGF 和散列函数。使用 OpenSSL 1.0.2L 测试

int flags = CMS_BINARY | CMS_PARTIAL | CMS_KEY_PARAM;
cms = CMS_encrypt(NULL, in, cipher, flags)
ri = CMS_add1_recipient_cert(cms, cert, flags);
pctx = CMS_RecipientInfo_get0_pkey_ctx(ri);
EVP_PKEY_CTX_set_rsa_padding(pctx, RSA_PKCS1_OAEP_PADDING);
EVP_PKEY_CTX_set_rsa_oaep_md(pctx, EVP_sha256());
EVP_PKEY_CTX_set_rsa_mgf1_md(pctx, EVP_sha256());
于 2017-08-23T16:42:18.457 回答
4

使用较新的 OpenSSL 1.0.2+,您可以使用以下命令执行此操作:

openssl pkeyutl -in PlaintextKeyMaterial.bin -out EncryptedKeyMaterial.bin -inkey PublicKey.bin -keyform DER -pubin -encrypt -pkeyopt rsa_padding_mode:oaep -pkeyopt rsa_oaep_md:sha256

这取自 AWS KMS 文档:https ://aws.amazon.com/es/premiumsupport/knowledge-center/invalidciphertext-kms/

于 2018-07-07T23:02:11.490 回答
3

OpenSSL 使用来自PKCS #1 v2.0的定义,因此默认为EME-OAEPisSHA-1MGF1. 如果需要使用SHA-256,则需要自己进行编码。然而,这并不是非常困难,有关详细信息,请参阅PKCS #1 v2.2 PDF第 18 页。

于 2013-07-22T19:11:51.367 回答
1

上面提到的 PKCS#1 文档更具数学性,没有给出编码示例,CMS 的答案是针对 ASN.1/SMIME 数据的,与所提出的问题并不真正相关,即如何替换RSA_public_encrypt()处理简单二进制的问题/文本数据。我花了一整天的时间反复试验和在线搜索以找到答案,并最终通过查看“openssl pkeyutl”的源代码得到了答案(即使用 OpenSSL 的 EVP API)——一旦我发现它并不难。

在我的情况下,我希望RSA_private_decrypt()使用私钥替换解密,这就是如何做到这一点 - 基于此将 RSA_public_encrypt() 替换放在一起应该很容易:

EVP_PKEY    *privKey = NULL;
BIO         *bioPrivKey;
int         outLen = 0, ret;

if ((bioPrivKey = BIO_new(BIO_s_mem())))
{
    // Read the private key from the RSA context into the memory BIO,
    // then convert it to an EVP_PKEY:
    if ((ret = PEM_write_bio_RSAPrivateKey(bioPrivKey, rsaCtxt, NULL, NULL, 0, NULL, NULL)) &&
        (privKey = PEM_read_bio_PrivateKey(bioPrivKey, NULL, NULL, NULL)))
    {
        EVP_PKEY_CTX *ctx = EVP_PKEY_CTX_new(privKey, NULL);

        EVP_PKEY_free(privKey);

        if (ctx)
        {
            if (EVP_PKEY_decrypt_init(ctx) > 0)
            {
                EVP_PKEY_CTX_ctrl_str(ctx, "rsa_padding_mode", "oaep");
                EVP_PKEY_CTX_ctrl_str(ctx, "rsa_oaep_md", "sha256");
                EVP_PKEY_CTX_ctrl_str(ctx, "rsa_mgf1_md", "sha256");

                outLen = dataOutMax;
                ret = EVP_PKEY_decrypt(ctx, dataOut, &outLen, dataIn, inDataLen);
                if (ret > 0 && outLen > 0 && outLen <= dataOutMax)
                {
                    // Success :-)
                }
            }
            EVP_PKEY_CTX_free(ctx);
        }
    }

    BIO_free_all(bioPrivKey);
}

您可以使用 ERR_get_error() 为失败案例添加错误处理。

于 2019-03-22T18:04:37.613 回答
1

在最新版本的 Openssl(1.0.2k) 中,API 的签名发生了变化,这给了我们更多的灵活性。请在下面找到详细信息,

int RSA_padding_check_PKCS1_OAEP_mgf1(unsigned char *to,int tlen,const unsigned char *from,int flen,int num,const unsigned char *param,int plen,const EVP_MD *md,const EVP_MD *mgf1md)

您可以传递 EVP_MD 结构以使用它调用 SHA-256 散列。

于 2017-03-07T14:17:58.823 回答