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)
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))
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))
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
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
def __str__(self): return "{}(salt={}, iterations={})".format(self.oid_name.strip(':'), util_bin.xx(self.salt), self.iterations)
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