Beispiel #1
0
def print_keystore(ks_content, password, show_pem=False, list_only=False):
    """Parse a Java KeyStore file and print it"""
    # Header: magic, version, number of aliases
    if ks_content.startswith(MAGIC_NUMBER_JKS):
        store_type = 'jks'
    elif ks_content.startswith(MAGIC_NUMBER_JCEKS):
        store_type = 'jceks'
    else:
        raise ValueError("Not a JKS not a JCEKS")

    version, count = struct.unpack('>II', ks_content[4:0xc])
    if version != 2:
        raise ValueError("Version {} not implemented".format(version))
    print("Keystore (type {}) has {} {}".format(store_type, count, "entries" if count >= 2 else "entry"))

    # Check the password with the integrity hash
    integrity_hash = ks_content[-20:]
    computed_hash = hashlib.sha1(password.encode('utf-16be') + b'Mighty Aphrodite' + ks_content[:-20]).digest()
    if computed_hash == integrity_hash:
        print("* password: {} (integrity hash {})".format(repr(password), xx(integrity_hash)))
    else:
        print("* incorrect password (integrity hash {})".format(xx(integrity_hash)))

    offset = 0xc
    for entry_index in range(count):
        tag, alias_len = struct.unpack('>IH', ks_content[offset:offset + 6])
        offset += 6
        alias = ks_content[offset:offset + alias_len].decode('utf-8', 'replace')
        offset += alias_len
        timestamp, = struct.unpack('>Q', ks_content[offset:offset + 8])
        offset += 8

        timedesc = str(datetime.datetime.fromtimestamp(timestamp / 1000))

        if tag == 1:
            print("[{}] private key {} ({}):".format(entry_index + 1, repr(alias), timedesc))
            offset = print_ks_private_key(ks_content, password, offset=offset, show_pem=show_pem, list_only=list_only)
        elif tag == 2:
            print("[{}] trusted key {} ({}):".format(entry_index + 1, repr(alias), timedesc))
            offset = print_ks_certificate(ks_content, offset=offset, show_pem=show_pem, list_only=list_only)
        elif tag == 3 and store_type == 'jceks':
            print("[{}] secret key {} ({}):".format(entry_index + 1, repr(alias), timedesc))
            offset = print_jceks_secret_key(ks_content, password, offset=offset, list_only=list_only)
        else:
            raise ValueError("Unknown entry tag {}".format(tag))

    if offset + 20 != len(ks_content):
        logger.warning("There remains %d bytes before the integrity hash", len(ks_content) - offset - 20)
Beispiel #2
0
def show_pkcs8_private_key_info(privkey_der,
                                list_only=False,
                                show_pem=False,
                                indent=''):
    """Decode a PKCS#8 PrivateKeyInfo structure in ASN.1 DER format and show it"""
    # PKCS#8 (https://tools.ietf.org/html/rfc5208)
    # PrivateKeyInfo ::= SEQUENCE {
    #     version                   Version,
    #     privateKeyAlgorithm       PrivateKeyAlgorithmIdentifier,
    #     privateKey                PrivateKey,
    #     attributes           [0]  IMPLICIT Attributes OPTIONAL
    # }
    # Version ::= INTEGER
    # PrivateKeyAlgorithmIdentifier ::= AlgorithmIdentifier
    # PrivateKey ::= OCTET STRING
    # Attributes ::= SET OF Attribute
    version, privatekey_algid_der, privatekey_der = decode_sequence(
        privkey_der, 3)
    if version != 0:
        raise ValueError("Unknown PrivateKeyInfo version {}".format(version))
    privatekey_algid = decode_x509_algid(privatekey_algid_der)
    key_value = decode_octet_string(privatekey_der)

    if privatekey_algid == 'DSA':
        print("{}* DSA private key".format(indent))
        util_bin.run_openssl_show_dsa(privkey_der,
                                      list_only=list_only,
                                      show_pem=show_pem,
                                      indent=indent)
    elif privatekey_algid == 'RSA':
        print("{}* RSA private key".format(indent))
        util_bin.run_openssl_show_rsa(privkey_der,
                                      list_only=list_only,
                                      show_pem=show_pem,
                                      indent=indent)
    elif privatekey_algid == 'AES':
        if list_only:
            print("{}* AES key: {} bytes ({} bits)".format(
                indent, len(key_value), 8 * len(key_value)))
        else:
            print("{}* AES key ({} bytes): {}".format(indent, len(key_value),
                                                      util_bin.xx(key_value)))
            print("{}    * repr: {}".format(indent, repr(key_value)))
        return
    else:
        util_bin.run_openssl_asn1parse(privatekey_algid_der)
        raise ValueError(
            "Unknown encryption algorithm {}".format(privatekey_algid))
Beispiel #3
0
def print_p12_keystore(ks_content, password, show_pem=False, list_only=False):
    """Parse a PKCS#12 KeyStore file and print it"""
    # run_process_with_input(['openssl', 'asn1parse', '-i', '-inform', 'DER'], ks_content, fatal=True)

    # PFX (Personal Information Exchange) is defined as:
    # PFX ::= SEQUENCE {
    #     version     INTEGER {v3(3)}(v3,...),
    #     authSafe    ContentInfo,
    #     macData     MacData OPTIONAL
    # }
    version, authsafe_der, macdata_der = util_asn1.decode_sequence(
        ks_content, 3)
    if version != 3:
        raise NotImplementedError(
            "Unimplemented PFX version {}".format(version))

    # ContentInfo ::= SEQUENCE {
    #     contentType ContentType,
    #     content [0] EXPLICIT ANY DEFINED BY contentType OPTIONAL
    # }
    # ContentType ::= OBJECT IDENTIFIER
    authsafe_content_type_der, authsafe_content_der = util_asn1.decode_sequence(
        authsafe_der, 2)
    authsafe_content_type = util_asn1.decode_oid(authsafe_content_type_der)
    if authsafe_content_type != 'pkcs7-data':
        raise NotImplementedError(
            "Unimplemented PFX content type {}".format(authsafe_content_type))
    authsafe_content_der = util_asn1.decode_object(authsafe_content_der)
    authsafe_content = util_asn1.decode_octet_string(authsafe_content_der)

    # MacData ::= SEQUENCE {
    #     mac         DigestInfo,
    #     macSalt     OCTET STRING,
    #     iterations  INTEGER DEFAULT 1
    # }
    macdata_asn1 = util_asn1.decode_sequence(macdata_der)
    if len(macdata_asn1) == 2:
        mac_der, mac_salt_der = macdata_asn1
        mac_iterations = 1
    elif len(macdata_asn1) == 3:
        mac_der, mac_salt_der, mac_iterations = macdata_asn1
    else:
        raise ValueError(
            "Unexpected number of items in ASN.1 MacData sequence")
    mac_salt = util_asn1.decode_octet_string(mac_salt_der)

    # DigestInfo ::= SEQUENCE {
    #     digestAlgorithm DigestAlgorithmIdentifier,
    #     digest Digest
    # }
    # DigestAlgorithmIdentifier ::= AlgorithmIdentifier
    # Digest ::= OCTET STRING
    mac_digest_algorithm_der, mac_digest_der = util_asn1.decode_sequence(
        mac_der, 2)
    mac_digest_algorithm = util_asn1.decode_x509_algid(
        mac_digest_algorithm_der)
    mac_digest = util_asn1.decode_octet_string(mac_digest_der)

    print("* PKCS#12 Keystore MAC:")
    print("    * algorithm: {}".format(mac_digest_algorithm))
    print("    * salt: {}".format(xx(mac_salt)))
    print("    * iterations: {}".format(mac_iterations))
    print("    * HMAC digest: {}".format(xx(mac_digest)))

    mac_key = pkcs12_derivation(alg=mac_digest_algorithm,
                                id_byte=3,
                                password=password,
                                salt=mac_salt,
                                iterations=mac_iterations)

    mac_hmac = hmac.new(key=mac_key,
                        msg=authsafe_content,
                        digestmod=hashlib.sha1).digest()
    if mac_hmac == mac_digest:
        print("    (password: {})".format(repr(password)))
        print("    (HMAC key: {})".format(xx(mac_key)))
    else:
        print("    (computed HMAC: {})".format(xx(mac_hmac)))
        print("    * wrong password (pad HMAC digest)")

    # AuthenticatedSafe ::= SEQUENCE OF ContentInfo
    #     -- Data if unencrypted
    #     -- EncryptedData if password-encrypted
    #     -- EnvelopedData if public key-encrypted
    authsafe_seq = util_asn1.decode_sequence(authsafe_content)
    print("* {} data blocks:".format(len(authsafe_seq)))
    for blk_index, blk_der in enumerate(authsafe_seq):
        blk_content_type_der, blk_content_der = util_asn1.decode_sequence(
            blk_der, 2)
        blk_content_type = util_asn1.decode_oid(blk_content_type_der)
        blk_content_der = util_asn1.decode_object(
            blk_content_der)  # tag "cont[0]"

        if blk_content_type == 'pkcs7-data':
            safe_contents = util_asn1.decode_octet_string(blk_content_der)
            print("  [{}] unencrypted safe contents:".format(blk_index + 1))
            print_p12_safe_contents(safe_contents,
                                    password,
                                    show_pem=show_pem,
                                    list_only=list_only,
                                    indent="    ")
        elif blk_content_type == 'pkcs7-encryptedData':
            print("  [{}] encrypted safe contents:".format(blk_index + 1))
            # EncryptedData ::= SEQUENCE {
            #      version Version,
            #      encryptedContentInfo EncryptedContentInfo
            # }
            encblk_version, encrypted_ci_der = util_asn1.decode_sequence(
                blk_content_der, 2)
            if encblk_version != 0:
                raise NotImplementedError(
                    "Unimplemented PKCS#7 EncryptedData version {}".format(
                        encblk_version))

            # EncryptedContentInfo ::= SEQUENCE {
            #     contentType ContentType,
            #     contentEncryptionAlgorithm ContentEncryptionAlgorithmIdentifier,
            #     encryptedContent [0] IMPLICIT EncryptedContent OPTIONAL
            # }
            # ContentEncryptionAlgorithmIdentifier ::= AlgorithmIdentifier
            # EncryptedContent ::= OCTET STRING
            enc_ctype_der, enc_alg_der, enc_content_der = util_asn1.decode_sequence(
                encrypted_ci_der, 3)
            enc_ctype = util_asn1.decode_oid(enc_ctype_der)
            enc_alg = util_asn1.decode_x509_algid(enc_alg_der)
            enc_content = util_asn1.decode_object(
                enc_content_der)  # tag "cont[0]"
            if enc_ctype != 'pkcs7-data':
                raise NotImplementedError(
                    "Unimplemented PKCS#7 EncryptedData content type {}".
                    format(enc_ctype))
            print("    * encryption algorithm: {}".format(enc_alg))
            safe_contents = try_pkcs12_decrypt(enc_content,
                                               enc_alg,
                                               password,
                                               indent="    ")
            if safe_contents is not None:
                print_p12_safe_contents(safe_contents,
                                        password,
                                        show_pem=show_pem,
                                        list_only=list_only,
                                        indent="    ")
        else:
            raise NotImplementedError(
                "Unimplemented bag content type {}".format(blk_content_type))
Beispiel #4
0
def print_jceks_secret_key(ks_content, password, offset=0, list_only=False):
    """Print a secret key contained in a JCEKS"""
    # Deserialize the com.sun.crypto.provider.SealedObjectForKeyProtector object
    java_obj = SerializedJavaObject(ks_content, offset)
    if java_obj.obj['java_type'] != 'object':
        raise ValueError("Not a serialized Java object: {}".format(repr(java_obj.obj['java_type'])))
    if java_obj.obj['class_desc']['name'] != 'com.sun.crypto.provider.SealedObjectForKeyProtector':
        raise ValueError("Unexpected object class: {}".format(repr(java_obj.obj['class_desc']['name'])))

    # Extract the fields of the object
    encoded_params = java_obj.obj['fields']['encodedParams']
    encrypted_content = java_obj.obj['fields']['encryptedContent']
    params_alg = java_obj.obj['fields']['paramsAlg']
    seal_alg = java_obj.obj['fields']['sealAlg']
    if params_alg != 'PBEWithMD5AndTripleDES':
        raise ValueError("Unexpected alg: {}".format(repr(params_alg)))
    if seal_alg != 'PBEWithMD5AndTripleDES':
        raise ValueError("Unexpected seal alg: {}".format(repr(seal_alg)))

    params = struct.pack('b' * len(encoded_params), *encoded_params)
    encrypted = struct.pack('b' * len(encrypted_content), *encrypted_content)

    # The parameters consist in an ASN.1 sequence of [salt, iterations_count]
    print("  * params ({} bytes: {})".format(len(params), xx(params)))
    # run_process_with_input(['openssl', 'asn1parse', '-i', '-inform', 'DER'], params)
    params_asn1 = Crypto.Util.asn1.DerSequence()
    params_asn1.decode(params)
    assert len(params_asn1) == 2
    salt_obj, iterations = params_asn1
    salt_asn1 = Crypto.Util.asn1.DerObject()
    salt_asn1.decode(salt_obj)
    salt = salt_asn1.payload
    print("    * salt ({} bytes): {}".format(len(salt), xx(salt)))
    print("    * iterations: {}".format(iterations))
    if len(salt) != 8:
        raise ValueError("Unexpected salt length: {}".format(len(salt)))

    print("  * encrypted ({} bytes):".format(len(encrypted)))

    key, iv = PBEWithMD5AndTripleDES_derivation(password, salt, iterations)
    crypto_3des = Crypto.Cipher.DES3.new(key, Crypto.Cipher.DES3.MODE_CBC, iv)
    decrypted = crypto_3des.decrypt(encrypted)
    padlen, = struct.unpack('B', decrypted[-1:])
    # Check PKCS#5 padding
    if not (1 <= padlen <= 0x10) or any(x != decrypted[-1] for x in decrypted[-padlen:]):
        print("    * wrong password (pad PKCS#5 padding)")
    else:
        decrypted = decrypted[:-padlen]

        print("    (password: {})".format(repr(password)))
        # print("    (key: {})".format(xx(key)))
        # print("    (iv: {})".format(xx(iv)))

        # Deserialize the plaintext, again
        decrypted_object = SerializedJavaObject(decrypted)
        if decrypted_object.offset != len(decrypted):
            raise ValueError("Stray data after deserialization of encrypted object")
        if decrypted_object.obj['java_type'] != 'object':
            raise ValueError("Not a serialized Java object: {}".format(repr(decrypted_object.obj['java_type'])))

        dec_class_name = decrypted_object.obj['class_desc']['name']
        print("    * Java class: {}".format(repr(dec_class_name)))

        if dec_class_name == 'java.security.KeyRep':
            dec_algorithm = decrypted_object.obj['fields']['algorithm']
            dec_encoded = decrypted_object.obj['fields']['encoded']
            dec_format = decrypted_object.obj['fields']['format']
            dec_type = decrypted_object.obj['fields']['type']['constant_name']

            value = struct.pack('b' * len(dec_encoded), *dec_encoded)
            print("    * algorithm: {}".format(repr(dec_algorithm)))
            print("    * format: {}".format(repr(dec_format)))
            print("    * type: {}".format(repr(dec_type)))
            if list_only:
                print("    * value: {} bytes ({} bits)".format(len(value), 8 * len(value)))
            else:
                print("    * value ({} bytes): {}".format(len(value), xx(value)))
                print("      * repr: {}".format(repr(value)))
        elif dec_class_name == 'javax.crypto.spec.SecretKeySpec':
            dec_algorithm = decrypted_object.obj['fields']['algorithm']
            dec_key = decrypted_object.obj['fields']['key']
            key_value = struct.pack('b' * len(dec_key), *dec_key)
            print("    * algorithm: {}".format(repr(dec_algorithm)))
            if list_only:
                print("    * key: {} bytes ({} bits)".format(len(key_value), 8 * len(key_value)))
            else:
                print("    * key ({} bytes): {}".format(len(key_value), xx(key_value)))
                print("      * repr: {}".format(repr(key_value)))
        else:
            print("Unknown decrypted object, here is a dump:")
            print(json.dumps(decrypted_object.obj))
            raise ValueError("Unexpected object class: {}".format(repr(decrypted_object.obj['class_desc']['name'])))

    # Return the new offset, after the Java object
    return java_obj.offset
Beispiel #5
0
def print_ks_private_key(ks_content, password, offset=0, show_pem=False, list_only=False):
    """Print a private contained in a JKS or a JCEKS"""
    privkey_size, = struct.unpack('>I', ks_content[offset:offset + 4])
    offset += 4
    privkey = ks_content[offset:offset + privkey_size]
    offset += privkey_size
    print("  * private key ({} bytes)".format(len(privkey)))
    # run_process_with_input(['openssl', 'asn1parse', '-i', '-inform', 'DER'], privkey, fatal=True)

    privkey_type_der, privkey_octetstring_der = util_asn1.decode_sequence(privkey, 2)
    privkey_type_oid_der, privkey_type_params_der = util_asn1.decode_sequence(privkey_type_der)
    privkey_type_oid = util_asn1.decode_oid(privkey_type_oid_der)
    privkey_encrypted = util_asn1.decode_octet_string(privkey_octetstring_der)

    decrypted = None
    if privkey_type_oid == '1.3.6.1.4.1.42.2.17.1.1':
        # OID 1.3.6.1.4.1.42.2.17.1.1 is proprietary JavaSoft algorithm
        # {iso(1) identified-organization(3) dod(6) internet(1) private(4)
        #  enterprise(1) Sun Microsystems (42) products(2) 17 1 1}
        assert privkey_type_params_der == b'\x05\x00'  # NULL in ASN.1 DER notation
        print("    * JKS encryption")
        iv = privkey_encrypted[:20]
        integrity_hash = privkey_encrypted[-20:]
        print("    * IV: {}".format(xx(iv)))
        print("    * SHA1 hash: {}".format(xx(integrity_hash)))

        password_bytes = password.encode('utf-16be')
        keystream = []
        while len(keystream) < len(privkey_encrypted) - 40:
            iv = hashlib.sha1(password_bytes + iv).digest()
            keystream += struct.unpack('20B', iv)

        data_struct_fmt = '{}B'.format(len(privkey_encrypted) - 40)
        enc_data = struct.unpack(data_struct_fmt, privkey_encrypted[20:-20])
        decrypted = struct.pack(data_struct_fmt, *[x ^ k for x, k in zip(enc_data, keystream)])
        computed_hash = hashlib.sha1(password_bytes + decrypted).digest()
        if computed_hash != integrity_hash:
            print("    * wrong password (bad SHA1 hash)")
            decrypted = None

    elif privkey_type_oid == '1.3.6.1.4.1.42.2.19.1':
        # OID 1.3.6.1.4.1.42.2.19.1 is PBE_WITH_MD5_AND_DES3_CBC (JCEKS)
        salt_der, iterations = util_asn1.decode_sequence(privkey_type_params_der, 2)
        salt = util_asn1.decode_octet_string(salt_der)
        print("    * JCEKS encryption")
        print("    * salt ({} bytes): {}".format(len(salt), xx(salt)))
        print("    * iterations: {}".format(iterations))

        key, iv = PBEWithMD5AndTripleDES_derivation(password, salt, iterations)
        crypto_3des = Crypto.Cipher.DES3.new(key, Crypto.Cipher.DES3.MODE_CBC, iv)
        decrypted = crypto_3des.decrypt(privkey_encrypted)
        padlen, = struct.unpack('B', decrypted[-1:])
        # Check PKCS#5 padding
        if not (1 <= padlen <= 0x10) or any(x != decrypted[-1] for x in decrypted[-padlen:]):
            print("    * wrong password (bad PKCS#5 padding)")
            decrypted = None
        else:
            decrypted = decrypted[:-padlen]

    else:
        raise ValueError("Unknown private key with OID {}".format(privkey_type_oid))

    if decrypted:
        print("    (password: {})".format(repr(password)))
        # print("    (key: {})".format(xx(key)))
        # print("    (iv: {})".format(xx(iv)))
        util_asn1.show_pkcs8_private_key_info(decrypted, list_only=list_only, show_pem=show_pem, indent="    ")

    chain_length, = struct.unpack('>I', ks_content[offset:offset + 4])
    offset += 4
    for chain_index in range(chain_length):
        offset = print_ks_certificate(ks_content, offset=offset, show_pem=show_pem, list_only=list_only)
    return offset
Beispiel #6
0
 def __str__(self):
     return "{}(salt={}, iterations={})".format(self.oid_name.strip(':'),
                                                util_bin.xx(self.salt),
                                                self.iterations)
Beispiel #7
0
def decode_oid(der_objectid):
    """Decode an ASN.1 Object ID in DER format"""
    oid_asn1 = Crypto.Util.asn1.DerObjectId()
    try:
        oid_asn1.decode(der_objectid)
    except ValueError as exc:
        logger.error("Unable to decode an ASN.1 object ID: %s (for %s)", exc,
                     util_bin.xx(der_objectid))
        raise
    except TypeError:
        # python-crypto 2.6.1-4ubuntu0.3 is buggy on Ubuntu 14.04:
        #   File "/usr/lib/python2.7/dist-packages/Crypto/Util/asn1.py", line 274, in decode
        #     p = DerObject.decode(derEle, noLeftOvers)
        # TypeError: unbound method decode() must be called with DerObject instance as first argument
        #   (got str instance instead)
        # ... so fallback to a raw DerObject()
        oid_asn1 = Crypto.Util.asn1.DerObject()
        oid_asn1.decode(der_objectid)

    # PyCrypto < 2.7 did not decode the Object Identifier. Let's implement OID decoding
    components = []
    current_val = 0
    for idx, byteval in enumerate(
            struct.unpack('B' * len(oid_asn1.payload), oid_asn1.payload)):
        if idx == 0:
            # The first byte combine the first two digits
            components += [str(v) for v in divmod(byteval, 40)]
        else:
            # 7-bit encoding of variable-length integers with most-significant bit as continuation indicator
            current_val = (current_val << 7) | (byteval & 0x7f)
            if not (byteval & 0x80):
                components.append(str(current_val))
                current_val = 0
    oid_value = '.'.join(components)
    if hasattr(oid_asn1, 'value') and oid_asn1.value != oid_value:
        raise RuntimeError("Failed to decode OID {}: got {} instead".format(
            oid_asn1.value, oid_value))

    # Decode well-known Object IDs
    if oid_value == '1.2.840.10040.4.1':
        # {iso(1) member-body(2) us(840) x9-57(10040) x9algorithm(4) dsa(1)}
        return 'dsaEncryption'
    if oid_value == '1.2.840.113549.1.1.1':
        # {iso(1) member-body(2) us(840) rsadsi(113549) pkcs(1) pkcs-1(1) rsaEncryption(1)}
        # RSAES-PKCS1-v1_5 encryption scheme
        return 'rsaEncryption'

    if oid_value == '1.2.840.113549.1.7.1':
        # {iso(1) member-body(2) us(840) rsadsi(113549) pkcs(1) pkcs-7(7) data(1)}
        return 'pkcs7-data'
    if oid_value == '1.2.840.113549.1.7.2':
        # {iso(1) member-body(2) us(840) rsadsi(113549) pkcs(1) pkcs-7(7) signedData(2)}
        return 'pkcs7-signedData'
    if oid_value == '1.2.840.113549.1.7.3':
        # {iso(1) member-body(2) us(840) rsadsi(113549) pkcs(1) pkcs-7(7) envelopedData(3)}
        return 'pkcs7-envelopedData'
    if oid_value == '1.2.840.113549.1.7.4':
        # {iso(1) member-body(2) us(840) rsadsi(113549) pkcs(1) pkcs-7(7) signedAndEnvelopedData(4)}
        return 'pkcs7-signedAndEnvelopedData'
    if oid_value == '1.2.840.113549.1.7.5':
        # {iso(1) member-body(2) us(840) rsadsi(113549) pkcs(1) pkcs-7(7) digestedData(5)}
        return 'pkcs7-digestedData'
    if oid_value == '1.2.840.113549.1.7.6':
        # {iso(1) member-body(2) us(840) rsadsi(113549) pkcs(1) pkcs-7(7) encryptedData(6)}
        return 'pkcs7-encryptedData'

    if oid_value == '1.2.840.113549.1.9.20':
        # {iso(1) member-body(2) us(840) rsadsi(113549) pkcs(1) pkcs-9(9) friendlyName(20)}
        return 'friendlyName'
    if oid_value == '1.2.840.113549.1.9.21':
        # {iso(1) member-body(2) us(840) rsadsi(113549) pkcs(1) pkcs-9(9) localKeyID(21)}
        return 'localKeyID'
    if oid_value == '1.2.840.113549.1.9.22.1':
        # {iso(1) member-body(2) us(840) rsadsi(113549) pkcs(1) pkcs-9(9) certTypes(22) x509Certificate(1)}
        return 'x509Certificate'

    if oid_value == '1.2.840.113549.1.12.1.1':
        # {iso(1) member-body(2) us(840) rsadsi(113549) pkcs(1) pkcs-12(12) pkcs-12PbeIds(1)
        #  pbeWithSHAAnd128BitRC4(1)}
        return 'pbeWithSHA1And128BitRC4'
    if oid_value == '1.2.840.113549.1.12.1.2':
        # {iso(1) member-body(2) us(840) rsadsi(113549) pkcs(1) pkcs-12(12) pkcs-12PbeIds(1)
        #  pbeWithSHAAnd40BitRC4(2)}
        return 'pbeWithSHA1And40BitRC4'
    if oid_value == '1.2.840.113549.1.12.1.3':
        # {iso(1) member-body(2) us(840) rsadsi(113549) pkcs(1) pkcs-12(12) pkcs-12PbeIds(1)
        #  pbeWithSHAAnd3-KeyTripleDES-CBC(3)}
        return 'pbeWithSHA1And3-KeyTripleDES-CBC'
    if oid_value == '1.2.840.113549.1.12.1.4':
        # {iso(1) member-body(2) us(840) rsadsi(113549) pkcs(1) pkcs-12(12) pkcs-12PbeIds(1)
        #  pbeWithSHAAnd2-KeyTripleDES-CBC(4)}
        return 'pbeWithSHA1And2-KeyTripleDES-CBC'
    if oid_value == '1.2.840.113549.1.12.1.5':
        # {iso(1) member-body(2) us(840) rsadsi(113549) pkcs(1) pkcs-12(12) pkcs-12PbeIds(1)
        #  pbeWithSHAAnd128BitRC2-CBC(5)}
        # In Java: PBE/SHA1/RC2/CBC/PKCS12PBE-5-128 (when using 5 iterations)
        return 'pbeWithSHA1And128BitRC2-CBC'
    if oid_value == '1.2.840.113549.1.12.1.6':
        # {iso(1) member-body(2) us(840) rsadsi(113549) pkcs(1) pkcs-12(12) pkcs-12PbeIds(1)
        #  pbeWithSHAAnd40BitRC2-CBC(6)}
        return 'pbeWithSHA1And40BitRC2-CBC'

    if oid_value == '1.2.840.113549.1.12.10.1.2':
        # {iso(1) member-body(2) us(840) rsadsi(113549) pkcs(1) pkcs-12(12) pkcs-12Version1(10)
        #  pkcs-12BagIds(1) keyBag(1)}
        return 'keyBag'
    if oid_value == '1.2.840.113549.1.12.10.1.2':
        # {iso(1) member-body(2) us(840) rsadsi(113549) pkcs(1) pkcs-12(12) pkcs-12Version1(10)
        #  pkcs-12BagIds(1) pkcs-8ShroudedKeyBag(2)}
        return 'pkcs8ShroudedKeyBag'
    if oid_value == '1.2.840.113549.1.12.10.1.3':
        # {iso(1) member-body(2) us(840) rsadsi(113549) pkcs(1) pkcs-12(12) pkcs-12Version1(10)
        #  pkcs-12BagIds(1) certBag(3)}
        return 'certBag'
    if oid_value == '1.2.840.113549.1.12.10.1.4':
        # {iso(1) member-body(2) us(840) rsadsi(113549) pkcs(1) pkcs-12(12) pkcs-12Version1(10)
        #  pkcs-12BagIds(1) crlBag(4)}
        return 'crlBag'
    if oid_value == '1.2.840.113549.1.12.10.1.5':
        # {iso(1) member-body(2) us(840) rsadsi(113549) pkcs(1) pkcs-12(12) pkcs-12Version1(10)
        #  pkcs-12BagIds(1) secretBag(5)}
        return 'secretBag'
    if oid_value == '1.2.840.113549.1.12.10.1.6':
        # {iso(1) member-body(2) us(840) rsadsi(113549) pkcs(1) pkcs-12(12) pkcs-12Version1(10)
        #  pkcs-12BagIds(1) safeContentsBag(6)}
        return 'safeContentsBag'

    if oid_value == '1.3.14.3.2.26':
        # {iso(1) identified-organization(3) oiw(14) secsig(3) algorithms(2) hashAlgorithmIdentifier(26)}
        return 'sha1'

    if oid_value == '2.16.840.1.101.3.4.1':
        # {joint-iso-itu-t(2) country(16) us(840) organization(1) gov(101) csor(3) nistAlgorithm(4) aes(1)}
        return 'aes'

    return oid_value