Wie konvertiert man ein Zertifikat von einer GIDS-Karte in eine crt-Datei?

Ich arbeite an einer Low-Level-Android-Software für einen Smartcard-Leser. Ich versuche, Unterstützung für GIDS-Geräte hinzuzufügen, und habe einige Probleme bei der Verwendung der Zertifikate, die ich von der Karte abrufen kann.

PIV-Karten speichern die Zertifikate so, dass die Umwandlung von Hex- in Byte-Arrays ein Array liefert, das openSSL erkennt.

Derselbe Prozess funktioniert nicht für die Zertifikatsdateien von der GIDS-Karte, die als die folgende Hex-Zeichenfolge wiederhergestellt wird.

DF2482042E0100930478DA336862E93768622A6712895C5DA3A0EF71AAE4A82C0F93FC0
98EA3BC86396F0C78D938B5DA3CDABEF3323272B33218541A721B70B23187B2B0093385
061BF21A7083381C3C2CFE1999F9868206FC202E3B0F87737E4E696E5269B1A180011F4
8888B87DD35B7A028B3381526C2CCC35E925A5CA29B9C68A862A004B78593514C342935
AFB0B824312F27B5D2213D373133472F393FD7404E9CD7C8C8C0DCC8D4D0CCC0D0C0220
AC83536040A40B9068D7D94BB8D1FE85FA008370F5B6E7E52664EAAA1888110C4B1DCC9
3999A97940E7A6169510E9E0264625E4E0636465606E62E467008A7331353132321CFA3
27FE982EDE7E2004004259C61009CF833FD6631E9B78A67EA705E167C1839FBE79F8917
EDDD6F26591E56FBE9BE325FF850A9CEDA25E95D3AB377DEE1E03678B5C5EE6DE626C3
C669DD01AF5A393E05AFBAFF78EBBF67E1E99EFBCDB9EFBD9EB56661D2D450A3F72FD9
599A7DD7FDFF7425C6E75FF4B7A6E525C1A9011E5BF7C69D4BF55EA7EDBF7286F9FAFF
394E07976A261E923F78472E20727F7BE2D613EAD73C9F4D8AE7652DB89DADBF4C6D79
C84FF3D65B534FA4F054F42C90A9D9D9F875DF17855ED32FD5697B7607EFCA150ADFF7
E3C4C7731C367A37FC637FCE1714FBC89599CD52EA7132C0ED55D33A833F2CCE21DE22B
DC22C851585524AA5055782ECEE9C7EBA4EF48DCFDEFE2E0020FEF833FD6631E9B78A67
EA705E167C1839FBE79F8917EDDD6F26591E56FBE9BE325FF850A9CEDA25E95D3AB377D
EE1E03678B5C5EE6DE626C3C669DD01AF5A393E05AFBAFF78EBBF67E1E99EFBCDB9EFBD
9EB56661D2D450A3F72FD9599A7DD7FDFF7425C6E75FF4B7A6E525C1A9011E5BF7C69D4
BF55EA7EDBF7286F9FAFF394E07976A261E923F78472E20727F7BE2D613EAD73C9F4D8A
E7652DB89DADBF4C6D79C84FF3D65B534FA4F054F42C90A9D9D9F875DF17855ED32FD56
97B7607EFCA150ADFF7E3C4C7731C367A37FC637FCE1714FBC89599CD52EA7132C0ED55
D33A833F2CCE21DE22BDC22C851585524AA5055782ECEE9C7EBA4EF48DCFDEFE2E00400
4D7FBAF3833093231333230A22530E6262646863D9D674B3ECB46DD2F7FACF3F190C2BA
A8AA8D87ED2DDD8C77256FDAF7558449D2533EE727EF97D2270DF2EDAFEF8BBED45E513
B7FFAD64AF5D5BF1B7FEA245CF9F3C48EFBCBA53D1B4F2F107AA53B7DDADC734C1B18CB
4ED86DF0765DB92E82A74486834DDBF5E8849F8F79EB7F5FBA1EB5E6C9C4BC306BD5430
E97197AECAB9CCF181FBBA251B8F1FAE3C32797D92CB25BB8E3D42B83B553D6DAF557CA
38CE9CB954E778BB43E96D4E3ED9A012B9BB67BCBFFF3B34277A6569135BBD45E482A37
36CEDAFA92F33BFB769A34579DDEEF0258EF21C0ED7A758313DF53DEF792FDBA8D1D384
A35F23E3D2DDE72B19004004D70496DC8E5A6673E1EB17C36DF327C835F6D8C5BCDBB0F
E44917F6100F3866D7D5B8A1E3ED1AE293DDA3321F07C4DF814EBCDF5D3EFEF89FAFD5C
72DA2426FE1329317C2FEC3955CD2EF07F105B68B43F2CEACE46AF99A691DAB37345A71
854CDDE227DE6EAB99BACE5B593EE68D81D0E3876877FCBEA68DE987B02CA69F3852747
EA1EF6F09F782BB3E296C19113EACA4FE746B04EE05CB079CBF72B1F15B973C257DD8BA
9E9F75D39B9F4DBEA4F1D2F1FA6319EE4B4797B59F87E84F4E9BCFDA6AB7DEBBCED35A5
B7AB6D69D3DB1C1C9651E16AD6F0CAF2A59E6AD9DE59473516DA1B72331C9A9471DCAF8
9F907D35CE15711DB6BF3259A75334EE6C430EE460020FE96DC8E5A6673E1EB17C36DF3
27C835F6D8C5BCDBB0FE44917F6100F3866D7D5B8A1E3ED1AE293DDA3321F07C4DF814E
BCDF5D3EFEF89FAFD5C72DA2426FE1329317C2FEC3955CD2EF07F105B68B43F2CEACE46
AF99A691DAB37345A71854CDDE227DE6EAB99BACE5B593EE68D81D0E3876877FCBEA68D
E987B02CA69F3852747EA1EF6F09F782BB3E296C19113EACA4FE746B04EE05CB079CBF7
2B1F15B973C257DD8BA9E9F75D39B9F4DBEA4F1D2F1FA6319EE4B4797B59F87E84F4E9B
CFDA6AB7DEBBCED35A5B7AB6D69D3DB1C1C9651E16AD6F0CAF2A59E6AD9DE59473516DA
1B72331C9A9471DCAF89F907D35CE15711DB6BF3259A75334EE6C430EE460040043BBDB
87DEB9DEACD41DA728722263C3D62EC2F7A4C91D9FA61CF6D272B6679CD4DF773857C04
67C5DCDB7977F6FAEBFD0063BED744

TL;DR-Zusammenfassung: Ich muss den obigen Hex-Code in ein x509-Zertifikat in Java umwandeln. Lesen Sie unten für einige zusätzliche Recherchen, die ich durchgeführt habe.

Ich habe im pkcs15-tool.c-Code von OpenSC herumgegraben und festgestellt, dass sie einige ziemlich komplizierte Manipulationen an den Daten vornehmen. Ich bin jedoch nicht sehr versiert in C/C++, daher fiel es mir schwer, ihm zu folgen.

parse_x509_cert von pkcs15-cert.c

static int
parse_x509_cert(sc_context_t *ctx, struct sc_pkcs15_der *der, struct sc_pkcs15_cert *cert)
{
    int r;
    struct sc_algorithm_id sig_alg;
    struct sc_pkcs15_pubkey *pubkey = NULL;
    unsigned char *serial = NULL, *issuer = NULL, *subject = NULL, *buf =  der->value;
    size_t serial_len = 0, issuer_len = 0, subject_len = 0, data_len = 0, buflen = der->len;
    struct sc_asn1_entry asn1_version[] = {
        { "version", SC_ASN1_INTEGER, SC_ASN1_TAG_INTEGER, 0, &cert->version, NULL },
        { NULL, 0, 0, 0, NULL, NULL }
    };
    struct sc_asn1_entry asn1_extensions[] = {
        { "x509v3",     SC_ASN1_OCTET_STRING,    SC_ASN1_TAG_SEQUENCE | SC_ASN1_CONS, SC_ASN1_OPTIONAL| SC_ASN1_ALLOC, &cert->extensions, &cert->extensions_len },
        { NULL, 0, 0, 0, NULL, NULL }
    };
    struct sc_asn1_entry asn1_tbscert[] = {
        { "version",        SC_ASN1_STRUCT,    SC_ASN1_CTX | 0 | SC_ASN1_CONS, SC_ASN1_OPTIONAL, asn1_version, NULL },
        { "serialNumber",   SC_ASN1_OCTET_STRING, SC_ASN1_TAG_INTEGER, SC_ASN1_ALLOC, &serial, &serial_len },
        { "signature",      SC_ASN1_STRUCT,    SC_ASN1_TAG_SEQUENCE | SC_ASN1_CONS, 0, NULL, NULL },
        { "issuer",     SC_ASN1_OCTET_STRING, SC_ASN1_TAG_SEQUENCE | SC_ASN1_CONS, SC_ASN1_ALLOC, &issuer, &issuer_len },
        { "validity",       SC_ASN1_STRUCT,    SC_ASN1_TAG_SEQUENCE | SC_ASN1_CONS, 0, NULL, NULL },
        { "subject",        SC_ASN1_OCTET_STRING, SC_ASN1_TAG_SEQUENCE | SC_ASN1_CONS, SC_ASN1_ALLOC, &subject, &subject_len },
        /* Use a callback to get the algorithm, parameters and pubkey into sc_pkcs15_pubkey */
        { "subjectPublicKeyInfo",SC_ASN1_CALLBACK, SC_ASN1_TAG_SEQUENCE | SC_ASN1_CONS, 0, sc_pkcs15_pubkey_from_spki_fields,  &pubkey },
        { "extensions",     SC_ASN1_STRUCT,    SC_ASN1_CTX | 3 | SC_ASN1_CONS, SC_ASN1_OPTIONAL, asn1_extensions, NULL },
        { NULL, 0, 0, 0, NULL, NULL }
    };
    struct sc_asn1_entry asn1_cert[] = {
        { "tbsCertificate", SC_ASN1_STRUCT,    SC_ASN1_TAG_SEQUENCE | SC_ASN1_CONS, 0, asn1_tbscert, NULL },
        { "signatureAlgorithm", SC_ASN1_ALGORITHM_ID, SC_ASN1_TAG_SEQUENCE | SC_ASN1_CONS, 0, &sig_alg, NULL },
        { "signatureValue", SC_ASN1_BIT_STRING, SC_ASN1_TAG_BIT_STRING, 0, NULL, NULL },
        { NULL, 0, 0, 0, NULL, NULL }
    };
    struct sc_asn1_entry asn1_serial_number[] = {
        { "serialNumber", SC_ASN1_OCTET_STRING, SC_ASN1_TAG_INTEGER, SC_ASN1_ALLOC, NULL, NULL },
        { NULL, 0, 0, 0, NULL, NULL }
    };
    struct sc_asn1_entry asn1_subject[] = {
        { "subject", SC_ASN1_OCTET_STRING, SC_ASN1_TAG_SEQUENCE | SC_ASN1_CONS, SC_ASN1_ALLOC, NULL, NULL },
        { NULL, 0, 0, 0, NULL, NULL }
    };
    struct sc_asn1_entry asn1_issuer[] = {
        { "issuer", SC_ASN1_OCTET_STRING, SC_ASN1_TAG_SEQUENCE | SC_ASN1_CONS, SC_ASN1_ALLOC, NULL, NULL },
        { NULL, 0, 0, 0, NULL, NULL }
    };

    const u8 *obj;
    size_t objlen;

    LOG_FUNC_CALLED(ctx);

    memset(cert, 0, sizeof(*cert));
    obj = sc_asn1_verify_tag(ctx, buf, buflen, SC_ASN1_TAG_SEQUENCE | SC_ASN1_CONS, &objlen);
    if (obj == NULL)
        LOG_TEST_RET(ctx, SC_ERROR_INVALID_ASN1_OBJECT, "X.509 certificate not found");

    data_len = objlen + (obj - buf);
    cert->data.value = malloc(data_len);
    if (!cert->data.value)
        LOG_FUNC_RETURN(ctx, SC_ERROR_OUT_OF_MEMORY);
    memcpy(cert->data.value, buf, data_len);
    cert->data.len = data_len;

    r = sc_asn1_decode(ctx, asn1_cert, obj, objlen, NULL, NULL);
    cert->key = pubkey;
    cert->version++;

    LOG_TEST_GOTO_ERR(ctx, r, "ASN.1 parsing of certificate failed");

    if (!pubkey)
        LOG_TEST_GOTO_ERR(ctx, SC_ERROR_INVALID_ASN1_OBJECT, "Unable to decode subjectPublicKeyInfo from cert");


    if (serial && serial_len)   {
        sc_format_asn1_entry(asn1_serial_number + 0, serial, &serial_len, 1);
        r = sc_asn1_encode(ctx, asn1_serial_number, &cert->serial, &cert->serial_len);
        LOG_TEST_GOTO_ERR(ctx, r, "ASN.1 encoding of serial failed");
    }

    if (subject && subject_len)   {
        sc_format_asn1_entry(asn1_subject + 0, subject, &subject_len, 1);
        r = sc_asn1_encode(ctx, asn1_subject, &cert->subject, &cert->subject_len);
        LOG_TEST_GOTO_ERR(ctx, r, "ASN.1 encoding of subject");
    }

    if (issuer && issuer_len)   {
        sc_format_asn1_entry(asn1_issuer + 0, issuer, &issuer_len, 1);
        r = sc_asn1_encode(ctx, asn1_issuer, &cert->issuer, &cert->issuer_len);
        LOG_TEST_GOTO_ERR(ctx, r, "ASN.1 encoding of issuer");
    }

err:
    /* not used for anything */
    sc_asn1_clear_algorithm_id(&sig_alg);
    free(serial);
    free(subject);
    free(issuer);

    LOG_FUNC_RETURN(ctx, r);
}

sc_asn1_verify_tag-Methode:

const u8 *sc_asn1_verify_tag(sc_context_t *ctx, const u8 * buf, size_t buflen,
                 unsigned int tag_in, size_t *taglen_out)
{
    return sc_asn1_skip_tag(ctx, &buf, &buflen, tag_in, taglen_out);
}

sc_asn1_skip_tag-Methode:

const u8 *sc_asn1_skip_tag(sc_context_t *ctx, const u8 ** buf, size_t *buflen,
               unsigned int tag_in, size_t *taglen_out)
{
    const u8 *p = *buf;
    size_t len = *buflen, taglen;
    unsigned int cla = 0, tag;

    if (sc_asn1_read_tag((const u8 **) &p, len, &cla, &tag, &taglen) != SC_SUCCESS
            || p == NULL)
        return NULL;
    switch (cla & 0xC0) {
    case SC_ASN1_TAG_UNIVERSAL:
        if ((tag_in & SC_ASN1_CLASS_MASK) != SC_ASN1_UNI)
            return NULL;
        break;
    case SC_ASN1_TAG_APPLICATION:
        if ((tag_in & SC_ASN1_CLASS_MASK) != SC_ASN1_APP)
            return NULL;
        break;
    case SC_ASN1_TAG_CONTEXT:
        if ((tag_in & SC_ASN1_CLASS_MASK) != SC_ASN1_CTX)
            return NULL;
        break;
    case SC_ASN1_TAG_PRIVATE:
        if ((tag_in & SC_ASN1_CLASS_MASK) != SC_ASN1_PRV)
            return NULL;
        break;
    }
    if (cla & SC_ASN1_TAG_CONSTRUCTED) {
        if ((tag_in & SC_ASN1_CONS) == 0)
            return NULL;
    } else
        if (tag_in & SC_ASN1_CONS)
            return NULL;
    if ((tag_in & SC_ASN1_TAG_MASK) != tag)
        return NULL;
    len -= (p - *buf);  /* header size */
    if (taglen > len) {
        sc_debug(ctx, SC_LOG_DEBUG_ASN1,
             "too long ASN.1 object (size %"SC_FORMAT_LEN_SIZE_T"u while only %"SC_FORMAT_LEN_SIZE_T"u available)\n",
             taglen, len);
        return NULL;
    }
    *buflen -= (p - *buf) + taglen;
    *buf = p + taglen;  /* point to next tag */
    *taglen_out = taglen;
    return p;
}

sc_asn1_read_tag-Methode:

int sc_asn1_read_tag(const u8 ** buf, size_t buflen, unsigned int *cla_out,
             unsigned int *tag_out, size_t *taglen)
{
    const u8 *p = *buf;
    size_t left = buflen, len;
    unsigned int cla, tag, i;

    *buf = NULL;

    if (left == 0 || !p)
        return SC_ERROR_INVALID_ASN1_OBJECT;
    if (*p == 0xff || *p == 0) {
        /* end of data reached */
        *taglen = 0;
        *tag_out = SC_ASN1_TAG_EOC;
        return SC_SUCCESS;
    }

    /* parse tag byte(s)
     * Resulted tag is presented by integer that has not to be
     * confused with the 'tag number' part of ASN.1 tag.
     */
    cla = (*p & SC_ASN1_TAG_CLASS) | (*p & SC_ASN1_TAG_CONSTRUCTED);
    tag = *p & SC_ASN1_TAG_PRIMITIVE;
    p++;
    left--;
    if (tag == SC_ASN1_TAG_PRIMITIVE) {
        /* high tag number */
        size_t n = SC_ASN1_TAGNUM_SIZE - 1;
        /* search the last tag octet */
        do {
            if (left == 0 || n == 0)
                /* either an invalid tag or it doesn't fit in
                 * unsigned int */
                return SC_ERROR_INVALID_ASN1_OBJECT;
            tag <<= 8;
            tag |= *p;
            p++;
            left--;
            n--;
        } while (tag & 0x80);
    }

    /* parse length byte(s) */
    if (left == 0)
        return SC_ERROR_INVALID_ASN1_OBJECT;
    len = *p;
    p++;
    left--;
    if (len & 0x80) {
        len &= 0x7f;
        unsigned int a = 0;
        if (len > sizeof a || len > left)
            return SC_ERROR_INVALID_ASN1_OBJECT;
        for (i = 0; i < len; i++) {
            a <<= 8;
            a |= *p;
            p++;
            left--;
        }
        len = a;
    }

    *cla_out = cla;
    *tag_out = tag;
    *taglen = len;
    *buf = p;

    if (len > left)
        return SC_ERROR_ASN1_END_OF_CONTENTS;

    return SC_SUCCESS;
}

Diese Methoden werden alle beim Lesen von Zertifikaten von der Karte mit OpenSC verwendet. Ich muss dies auf Android erreichen, also wäre jeder Java-Code, der es repliziert, hilfreich.

Ich würde mich auch über ein Dokument freuen, das erklärt, was das ist/wie dieses Zertifikat codiert oder formatiert ist.

Edit: TLV-Aufschlüsselung

Irgendwelche Ideen, was die zusätzlichen Portionen am Ende sein könnten?

🤔 А знаете ли вы, что...
C++ позволяет создавать многопоточные приложения с использованием стандартной библиотеки потоков.


3
51
1

Antwort:

Gelöst

Das Verfahren sollte wie folgt funktionieren (unter Verwendung von Daten aus GidsApplet Unit Test):

Nehmen Sie DO-Rohdaten:

DF2482029F0100AA0278DA3368625A66D0C4D8B7809989918949C0523340E6B55BCE0AA79E87FCDCC545BD06BC6C9C5A6D1E6DDF7919195959190CF80D790DB8D998435998855942528B4B0CE4C4790DCD0C0C0D0D80A49189619438AF113217534313A312B2A18CAC0CCC4D8CFC0C40712EA626464686750BEBDE18D606B7F19DD5FD2EF52029FA2CDBCFC58B8C3D8A0E8BB37F56D3FB663CF1A8C484377D6BCB738F569778E7C85F733EE2977A55527B5666F2ACFF539F335F7BF1A3596E41F65ECD428615FF66E8F4E6DF76505F7538EAEB65E1355F594A27F47D8C4F5917FCC659E84C6089BDC397CFDCF737689C9A2B6BB26521CFBE177B75941D6C26542B6E8FBD74F78356B14992EEB93C877F9686672FDD9E7E3759313771F7AC8575DFCF4CE03B71F241E5F9536EF2E91E1A69C50D7593AAE7D63558355C13EDAD497A9B25BD67BFF4DD8B55356A91BF8FF5DFE6EF0B5B921F1177C3ED9B7ED7BFBD6606EF756E369AAFE7FD72EA42C98BD90F6E2E70B6BC5F7D9E69DFCD495D8211AB8B7F2D8E6462666460440B766650C04C6557F81D107E38FA97CFF2E6CA2946BEAA5ED94C533CBCE748D4CD0D63B0FDCDF8FAD7F39E7BBC594F9AD294B77C8FFE54911138F9BB77C0A21FFFF6BC5891F6E193CDD4FF01B50F367B3EABBF5574B772AAA878C97A739B1D67734DB7B2DEB60F08779E707FE1DE951BBF735D68E5DDD15FC060FAD9FBDF16AEA7E7C2F93A5EED927FEEB4F1F49B99B213CE250A4F3DDDD99DDE97E3DE33C1E98984F88E3F06E5893C931DCB4F74A8738A3104ACEAB34875BDBA60E3E3052DFF97F7FD67EBFC5EBD30FCD06583A5C20C6E6FFB5F3BDD33E0F83747222CF9D9F2577DB72C56C44DE87DFB44F4973A5BE3ECF8DF2C3FD7F6F1BFE95E7550E32A9F9D4BC3FE6C56875291774772B996DEFDEFBC341C004D16293D

Als BER-TLV parsen (z.B. mit einem Online-Tool):

DF24 Unknown tag
    0100AA0278DA3368625A66D0C4D8B7809989918949C0523340E6B55BCE0AA79E87FCDCC545BD06BC6C9C5A6D1E6DDF7919195959190CF80D790DB8D998435998855942528B4B0CE4C4790DCD0C0C0D0D80A49189619438AF113217534313A312B2A18CAC0CCC4D8CFC0C40712EA626464686750BEBDE18D606B7F19DD5FD2EF52029FA2CDBCFC58B8C3D8A0E8BB37F56D3FB663CF1A8C484377D6BCB738F569778E7C85F733EE2977A55527B5666F2ACFF539F335F7BF1A3596E41F65ECD428615FF66E8F4E6DF76505F7538EAEB65E1355F594A27F47D8C4F5917FCC659E84C6089BDC397CFDCF737689C9A2B6BB26521CFBE177B75941D6C26542B6E8FBD74F78356B14992EEB93C877F9686672FDD9E7E3759313771F7AC8575DFCF4CE03B71F241E5F9536EF2E91E1A69C50D7593AAE7D63558355C13EDAD497A9B25BD67BFF4DD8B55356A91BF8FF5DFE6EF0B5B921F1177C3ED9B7ED7BFBD6606EF756E369AAFE7FD72EA42C98BD90F6E2E70B6BC5F7D9E69DFCD495D8211AB8B7F2D8E6462666460440B766650C04C6557F81D107E38FA97CFF2E6CA2946BEAA5ED94C533CBCE748D4CD0D63B0FDCDF8FAD7F39E7BBC594F9AD294B77C8FFE54911138F9BB77C0A21FFFF6BC5891F6E193CDD4FF01B50F367B3EABBF5574B772AAA878C97A739B1D67734DB7B2DEB60F08779E707FE1DE951BBF735D68E5DDD15FC060FAD9FBDF16AEA7E7C2F93A5EED927FEEB4F1F49B99B213CE250A4F3DDDD99DDE97E3DE33C1E98984F88E3F06E5893C931DCB4F74A8738A3104ACEAB34875BDBA60E3E3052DFF97F7FD67EBFC5EBD30FCD06583A5C20C6E6FFB5F3BDD33E0F83747222CF9D9F2577DB72C56C44DE87DFB44F4973A5BE3ECF8DF2C3FD7F6F1BFE95E7550E32A9F9D4BC3FE6C56875291774772B996DEFDEFBC341C004D16293D

Angesichts des OpenSC-Quellcodes sollten die Daten im Tag so aussehen:

  • 0x0100 .. um die zlib-Komprimierung anzuzeigen

  • 0xLLLL (hier 0xAA02) .. Angabe der unkomprimierten Datenlänge (hier 682 Bytes)

  • der Rest ist ein zlib-komprimierter Datenstrom (hier 667 Bytes 78DA33..16293D)

Dann können Sie zlib-Daten dekomprimieren, um Folgendes zu erhalten:

308202a63082018ea00302010202103929501ceb466ca8428ce10f0b73728d300d06092a864886f70d0101050500300f310d300b0603550403130454657374301e170d3136303131303136303234315a170d3236303131303136303234315a300f310d300b060355040313045465737430820122300d06092a864886f70d01010105000382010f003082010a0282010100aea17eec317d53860ecd2df71ae0625bcd06f9a3a2334872c31707f3262ef63391c51890ec8ead776dc57b744b6c1fd643c44e65d5192b9a69639aff95e703d6e8f8831ea06bbd297100a8fe982c8d6fdb4027aac35af5d313acf50475908ef15f64ae53ec4312cc51743f40f4f30bdfb028ca9d1d34b4a10cbee8bd2c23403c907b21b75dd2ddf02a7334622dce6e40fe3931cdd2db97dd63216d61bb9aa17ef7cc900ec8c9e079cfca461f6748286673807e927b9d7e803a80d6158d7c62ed6a1bbcbf1bddd17a7c2659fbc68fdb0f8e56a46f585ed846f62f8afebd3630ef2cd98137af0df4cad074e89be0d9a04339df7bcf02bed9928a1158ab73faa3590203010001300d06092a864886f70d01010505000382010100950720fb5057c35bfa4ca7837994324d254a6b0294484b9c187e9d56003dfb01ebfae78cde0d6ae4826623b4f75bf278685193f74b50a2f8febce8a866f0f23c95ff507de0b349e67fda72dd7995151774af373cb8cd6d35b505db3f50574390dfa1bda9b1f70ad0850db88f700035f34bfeb40ae5ce570e88eaba1fe742b1cbec991d90ce611395cb898b678e6c478c9042e41817b8fc3077610c934177c8882709160050aa8e386545d5a0b1e3a084ffa78eff0689f77ba157c2d330a5130046ed8feb42de3008fe9c185663e6a7ea8eda38a85e908dede415fa2706819b5ffb04f9ad8e0fec8baac128d50e3e4480bf6b05407514eec46d0aa5ddff43a557

Das ist ein DER-codiertes X.509-Zertifikat:

Certificate:
    Data:
        Version: 3 (0x2)
        Serial Number:
            39:29:50:1c:eb:46:6c:a8:42:8c:e1:0f:0b:73:72:8d
    Signature Algorithm: sha1WithRSAEncryption
        Issuer: CN = Test
        Validity
            Not Before: Jan 10 16:02:41 2016 GMT
            Not After : Jan 10 16:02:41 2026 GMT
        Subject: CN = Test
        Subject Public Key Info:
            Public Key Algorithm: rsaEncryption
                Public-Key: (2048 bit)
                Modulus:
                    00:ae:a1:7e:ec:31:7d:53:86:0e:cd:2d:f7:1a:e0:
                    62:5b:cd:06:f9:a3:a2:33:48:72:c3:17:07:f3:26:
                    2e:f6:33:91:c5:18:90:ec:8e:ad:77:6d:c5:7b:74:
                    4b:6c:1f:d6:43:c4:4e:65:d5:19:2b:9a:69:63:9a:
                    ff:95:e7:03:d6:e8:f8:83:1e:a0:6b:bd:29:71:00:
                    a8:fe:98:2c:8d:6f:db:40:27:aa:c3:5a:f5:d3:13:
                    ac:f5:04:75:90:8e:f1:5f:64:ae:53:ec:43:12:cc:
                    51:74:3f:40:f4:f3:0b:df:b0:28:ca:9d:1d:34:b4:
                    a1:0c:be:e8:bd:2c:23:40:3c:90:7b:21:b7:5d:d2:
                    dd:f0:2a:73:34:62:2d:ce:6e:40:fe:39:31:cd:d2:
                    db:97:dd:63:21:6d:61:bb:9a:a1:7e:f7:cc:90:0e:
                    c8:c9:e0:79:cf:ca:46:1f:67:48:28:66:73:80:7e:
                    92:7b:9d:7e:80:3a:80:d6:15:8d:7c:62:ed:6a:1b:
                    bc:bf:1b:dd:d1:7a:7c:26:59:fb:c6:8f:db:0f:8e:
                    56:a4:6f:58:5e:d8:46:f6:2f:8a:fe:bd:36:30:ef:
                    2c:d9:81:37:af:0d:f4:ca:d0:74:e8:9b:e0:d9:a0:
                    43:39:df:7b:cf:02:be:d9:92:8a:11:58:ab:73:fa:
                    a3:59
                Exponent: 65537 (0x10001)
    Signature Algorithm: sha1WithRSAEncryption
         95:07:20:fb:50:57:c3:5b:fa:4c:a7:83:79:94:32:4d:25:4a:
         6b:02:94:48:4b:9c:18:7e:9d:56:00:3d:fb:01:eb:fa:e7:8c:
         de:0d:6a:e4:82:66:23:b4:f7:5b:f2:78:68:51:93:f7:4b:50:
         a2:f8:fe:bc:e8:a8:66:f0:f2:3c:95:ff:50:7d:e0:b3:49:e6:
         7f:da:72:dd:79:95:15:17:74:af:37:3c:b8:cd:6d:35:b5:05:
         db:3f:50:57:43:90:df:a1:bd:a9:b1:f7:0a:d0:85:0d:b8:8f:
         70:00:35:f3:4b:fe:b4:0a:e5:ce:57:0e:88:ea:ba:1f:e7:42:
         b1:cb:ec:99:1d:90:ce:61:13:95:cb:89:8b:67:8e:6c:47:8c:
         90:42:e4:18:17:b8:fc:30:77:61:0c:93:41:77:c8:88:27:09:
         16:00:50:aa:8e:38:65:45:d5:a0:b1:e3:a0:84:ff:a7:8e:ff:
         06:89:f7:7b:a1:57:c2:d3:30:a5:13:00:46:ed:8f:eb:42:de:
         30:08:fe:9c:18:56:63:e6:a7:ea:8e:da:38:a8:5e:90:8d:ed:
         e4:15:fa:27:06:81:9b:5f:fb:04:f9:ad:8e:0f:ec:8b:aa:c1:
         28:d5:0e:3e:44:80:bf:6b:05:40:75:14:ee:c4:6d:0a:a5:dd:
         ff:43:a5:57
-----BEGIN CERTIFICATE-----
MIICpjCCAY6gAwIBAgIQOSlQHOtGbKhCjOEPC3NyjTANBgkqhkiG9w0BAQUFADAP
MQ0wCwYDVQQDEwRUZXN0MB4XDTE2MDExMDE2MDI0MVoXDTI2MDExMDE2MDI0MVow
DzENMAsGA1UEAxMEVGVzdDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEB
AK6hfuwxfVOGDs0t9xrgYlvNBvmjojNIcsMXB/MmLvYzkcUYkOyOrXdtxXt0S2wf
1kPETmXVGSuaaWOa/5XnA9bo+IMeoGu9KXEAqP6YLI1v20AnqsNa9dMTrPUEdZCO
8V9krlPsQxLMUXQ/QPTzC9+wKMqdHTS0oQy+6L0sI0A8kHsht13S3fAqczRiLc5u
QP45Mc3S25fdYyFtYbuaoX73zJAOyMngec/KRh9nSChmc4B+knudfoA6gNYVjXxi
7WobvL8b3dF6fCZZ+8aP2w+OVqRvWF7YRvYviv69NjDvLNmBN68N9MrQdOib4Nmg
Qznfe88CvtmSihFYq3P6o1kCAwEAATANBgkqhkiG9w0BAQUFAAOCAQEAlQcg+1BX
w1v6TKeDeZQyTSVKawKUSEucGH6dVgA9+wHr+ueM3g1q5IJmI7T3W/J4aFGT90tQ
ovj+vOioZvDyPJX/UH3gs0nmf9py3XmVFRd0rzc8uM1tNbUF2z9QV0OQ36G9qbH3
CtCFDbiPcAA180v+tArlzlcOiOq6H+dCscvsmR2QzmETlcuJi2eObEeMkELkGBe4
/DB3YQyTQXfIiCcJFgBQqo44ZUXVoLHjoIT/p47/Bon3e6FXwtMwpRMARu2P60Le
MAj+nBhWY+an6o7aOKhekI3t5BX6JwaBm1/7BPmtjg/si6rBKNUOPkSAv2sFQHUU
7sRtCqXd/0OlVw==
-----END CERTIFICATE-----

Dieses Verfahren funktioniert leider nicht mit Ihren Daten (deshalb habe ich Sie gebeten, es zu bestätigen -- AFAIK sollte der zlib-Stream mit 0x78 beginnen).

Viel Glück mit Ihrem Projekt!

BEARBEITEN>

Zur Qualität der GIBS-Spezifikation (unter Berufung auf OpenSC-Kommentar):

Einige Funktionen sind nicht dokumentiert, wie das zum Speichern von Zertifikaten verwendete Format. Sie wurden rückentwickelt.