Подтвердить что ты не робот

Извлечь публичный сертификат из сообщения SMIME (подпись pkcs7) с помощью OpenSSL

Как я могу извлечь открытый сертификат из сообщения smime (pkcs7-signature) с помощью OpenSSL?

4b9b3361

Ответ 1

С помощью средства командной строки, предполагая, что само сообщение S/MIME находится в файле message:

openssl smime -verify -in message -noverify -signer cert.pem -out textdata

Это записывает сертификат подписчика (как встроенный в подпись) в cert.pem и текстовые данные сообщения в файле textdata.

В качестве альтернативы вы можете сохранить подпись blob как независимый файл (это просто своего рода вложение, поэтому любое приложение или библиотека почтовой программы должно это сделать. Затем, предположив, что указанный blob находится в файле с именем smime.p7s, используйте:

openssl pkcs7 -in smime.p7s -inform DER -print_certs

который распечатает все сертификаты, встроенные в подпись PKCS # 7. Обратите внимание, что может быть несколько: сам сертификат подписчика и любые дополнительные сертификаты, которые подписывающий счел нужным включить (например, промежуточные сертификаты ЦС, которые могут помочь в проверке его сертификата).

Ответ 2

Или просто:

cat message.eml | openssl smime -pk7out | openssl pkcs7 -print_certs > senders-cert.pem

Ответ 3

Если вы пишете C/С++, этот фрагмент кода поможет

    //...assuming you have valid pkcs7, st1, m_store etc......

    verifyResult = PKCS7_verify( pkcs7, st1, m_store, content, out, flags);
    if(verifyResult != 1) {
        goto exit_free;
    }

    //Obtain the signers of this message. Certificates from st1 as well as any found included
    //in the message will be returned.
    signers = PKCS7_get0_signers(pkcs7, st1, flags);
    if (!save_certs(env, signerFilePath, signers)) {
        //Error log
    }

//This method will write the signer certificates into a file provided
int save_certs(JNIEnv *env, jstring signerFilePath, STACK_OF(X509) *signers)
{
    int result = 0;
    int i;
    BIO *tmp;
    int num_certificates = 0;

    if (signerFilePath == NULL) {
        return 0;
    }

    const char *signerfile = (const char *)env->GetStringUTFChars(signerFilePath, 0);
    tmp = BIO_new_file(signerfile, "w");
    if (!tmp) {
        //error. return
    }
    num_certificates = sk_X509_num(signers);
    for(i = 0; i < num_certificates; i++) {
        PEM_write_bio_X509(tmp, sk_X509_value(signers, i));
    }
    result = 1;

    exit_free:
    BIO_free(tmp);
    if (signerfile) {
        env->ReleaseStringUTFChars(signerFilePath, signerfile);
        signerfile = 0;
    }
    return result;
}