【问题标题】:how to decrypt ASN.1 DER encoded CMS file using the openssl API?如何使用 openssl API 解密 ASN.1 DER 编码的 CMS 文件?
【发布时间】:2013-10-14 16:09:12
【问题描述】:

我有一个 DER 编码的 CMS 文件,我想使用 openssl API 对其进行解密。

我找到了API进行解密:

CMS_decrypt(cms_content, pkey, cert, NULL, out, NULL);

我找到了读取 pkey 和 cert PEM 文件以及设置输出 BIO 的示例,但我不知道如何读取 cms 文件。

问题:如何将 ASN.1 DER 编码文件读入 cms_content 类型为 CMS_ContentInfo 的变量?


编辑:感谢Camille's answer,我设法让它工作:

#include <stdio.h>

#include <openssl/ssl.h>
#include <openssl/err.h>
#include <openssl/cms.h>

int main (int argc, char **argv)
{
    char pkeypath[] = "recipient_prvkey.pem";
    char certpath[] = "sender_cert.pem";
    char cmspath[] = "encrypted.der";
    char decpath[] = "decrypted.zip";

    BIO *in = NULL, *out = NULL, *tbio = NULL;
    CMS_ContentInfo *cms = NULL;

    EVP_PKEY *pkey;
    X509 *cert;

    OpenSSL_add_all_algorithms();
    ERR_load_crypto_strings();

    tbio = BIO_new_file(pkeypath, "r");
    pkey = PEM_read_bio_PrivateKey(tbio, NULL, 0, NULL);
    if (pkey == NULL) {
        printf("error reading private key");
        return EXIT_FAILURE;
    }
    BIO_free(tbio);

    tbio = BIO_new_file(certpath, "r");
    cert = PEM_read_bio_X509(tbio, NULL, 0, NULL);
    if (cert == NULL) {
        printf("error reading private key");
        return EXIT_FAILURE;
    }

    in = BIO_new_file(cmspath, "r");
    cms = d2i_CMS_bio(in, NULL);
    BIO_free(in);

    out = BIO_new_file(decpath, "w");

    if (!CMS_decrypt_set1_pkey(cms, pkey, cert))
    {
        fprintf(stderr, "set1_pkey error\n");
        return EXIT_FAILURE;
    }

    if (!CMS_decrypt(cms, NULL, NULL, NULL, out, CMS_BINARY))
    {
        int error = ERR_get_error();

        fprintf(stderr, "error: %s :: %s :: %s\n",
                ERR_reason_error_string(error),
                ERR_func_error_string(error),
                ERR_lib_error_string(error)
                );
    }
    BIO_free(out);

    return 0;
}

【问题讨论】:

    标签: c openssl


    【解决方案1】:

    我刚刚复制了适用于 PEM 的 OpenSSL cms_dec 示例,并将其改编为 DER 编码的 CMS 文件

    BIO *in = NULL, *out = NULL, *tbio = NULL;
    X509 *cert= NULL;
    EVP_PKEY *rkey = NULL;
    CMS_ContentInfo *cms = NULL;
    int ret = 1;
    
    OpenSSL_add_all_algorithms();
    ERR_load_crypto_strings();
    
    /* Read in recipient certificate and private key */
    tbio = BIO_new_file("yourCMS.der", "r");
    rcert = i2d_x509_bio(tbio, NULL);
    BIO_reset(tbio);
    i2d_PrivateKey_bio(tbio, rkey);
    
    /* Open S/MIME message to decrypt */
    in = BIO_new_file("smencr.txt", "r");
    
    /* Parse message */
    cms = SMIME_read_CMS(in, NULL);
    
    out = BIO_new_file("decout.txt", "w");
    
    /* Decrypt S/MIME message */
    CMS_decrypt(cms, rkey, rcert, out, NULL, CMS_BINARY) //Edit : Added Flags for DER.
    ...
    

    【讨论】:

    • 当我用 DER 编码文件尝试这个 in = BIO_new_file("smencr.txt", "r"); 时,openssl 无法处理它。在SMIME_read_CMS 文档中,声明了以下内容:解析器假定 CMS_ContentInfo 结构始终是 base64 编码的,并且不会处理它是二进制格式或使用引用的可打印格式的情况。跨度>
    • @Chris 好的...所以我想这可能是不可能的。但是你为什么不使用 PEM 编码的 CMS 文件呢?
    • 尝试:CMS_decrypt(cms, rkey, rcert, out, NULL, CMS_BINARY)
    猜你喜欢
    • 2011-11-11
    • 2015-04-30
    • 2013-11-17
    • 2022-01-22
    • 1970-01-01
    • 2015-12-10
    • 2017-06-29
    • 2010-11-19
    • 2011-04-07
    相关资源
    最近更新 更多