Code Monkey home page Code Monkey logo

pyjks's Introduction

pyjks

A pure python Java KeyStore file parser, including private/secret key decryption. Can read JKS, JCEKS, BKS and UBER (BouncyCastle) key stores.

The best way to utilize a certificate stored in a jks file up to this point has been to use the java keytool command to transform to pkcs12, and then openssl to transform to pem.

This is better:

  • no security concerns in passwords going into command line arguments, or unencrypted files being left around
  • no dependency on a JVM

Requirements:

  • Python 2.6+ or Python 3.3+
  • pyasn1 0.3.5+
  • pyasn1_modules 0.0.8+
  • javaobj-py3 0.1.4+
  • pycryptodomex, if you need to read JCEKS, BKS or UBER keystores
  • twofish, if you need to read UBER keystores

Usage examples:

Reading a JKS or JCEKS keystore and dumping out its contents in the PEM format:

from __future__ import print_function
import sys, base64, textwrap
import jks

def print_pem(der_bytes, type):
    print("-----BEGIN %s-----" % type)
    print("\r\n".join(textwrap.wrap(base64.b64encode(der_bytes).decode('ascii'), 64)))
    print("-----END %s-----" % type)

ks = jks.KeyStore.load("keystore.jks", "XXXXXXXX")
# if any of the keys in the store use a password that is not the same as the store password:
# ks.entries["key1"].decrypt("key_password")

for alias, pk in ks.private_keys.items():
    print("Private key: %s" % pk.alias)
    if pk.algorithm_oid == jks.util.RSA_ENCRYPTION_OID:
        print_pem(pk.pkey, "RSA PRIVATE KEY")
    else:
        print_pem(pk.pkey_pkcs8, "PRIVATE KEY")

    for c in pk.cert_chain:
        print_pem(c[1], "CERTIFICATE")
    print()

for alias, c in ks.certs.items():
    print("Certificate: %s" % c.alias)
    print_pem(c.cert, "CERTIFICATE")
    print()

for alias, sk in ks.secret_keys.items():
    print("Secret key: %s" % sk.alias)
    print("  Algorithm: %s" % sk.algorithm)
    print("  Key size: %d bits" % sk.key_size)
    print("  Key: %s" % "".join("{:02x}".format(b) for b in bytearray(sk.key)))
	print()

Transforming an encrypted JKS/JCEKS file into an OpenSSL context:

import OpenSSL
import jks

_ASN1 = OpenSSL.crypto.FILETYPE_ASN1

def jksfile2context(jks_file, passphrase, key_alias, key_password=None):
    keystore = jks.KeyStore.load(jks_file, passphrase)
    pk_entry = keystore.private_keys[key_alias]
    # if the key could not be decrypted using the store password, decrypt with a custom password now
    if not pk_entry.is_decrypted():
        pk_entry.decrypt(key_password)

    pkey = OpenSSL.crypto.load_privatekey(_ASN1, pk_entry.pkey)
    public_cert = OpenSSL.crypto.load_certificate(_ASN1, pk_entry.cert_chain[0][1])
    trusted_certs = [OpenSSL.crypto.load_certificate(_ASN1, cert.cert) for alias, cert in keystore.certs]

    ctx = OpenSSL.SSL.Context(OpenSSL.SSL.TLSv1_METHOD)
    ctx.use_privatekey(pkey)
    ctx.use_certificate(public_cert)
    ctx.check_privatekey() # want to know ASAP if there is a problem
    cert_store = ctx.get_cert_store()
    for cert in trusted_certs:
        cert_store.add_cert(cert)
    return ctx

pyjks's People

Contributors

castrapel avatar danpker avatar elias5000 avatar frugalguy avatar kuldeep-mishra avatar kurtbrose avatar magnuswatn avatar mahmoud avatar mindw avatar neonbunny avatar vail130 avatar voetsjoeba avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

pyjks's Issues

OSError: The stream is not java serialized object. Invalid stream header: E112A27B

Hello
Working with python 3.6.8 and pyjks 19.0.0, I regularly, but randomly get this error : OSError: The stream is not java serialized object. Invalid stream header: E112A27B



DEBUG	OpCode: 0x73 -- TC_OBJECT (at offset 0x4)	
DEBUG	[object]	
DEBUG	java_object.annotations just after instantiation: []	
DEBUG	  OpCode: 0x72 -- TC_CLASSDESC (at offset 0x5)	
DEBUG	  [classdesc]	
DEBUG	  Class name: com.sun.crypto.provider.SealedObjectForKeyProtector	
DEBUG	  ## New reference handle 0x7E0000: JavaClass -> [com.sun.crypto.provider.SealedObjectForKeyProtector:0x-32A835A618CF44AD]	
DEBUG	  Serial: 0x-32A835A618CF44AD / -3650226485480866989 - classDescFlags: 0x2 SC_SERIALIZABLE	
DEBUG	  Fields num: 0x0	
DEBUG	  OpCode: 0x78 -- TC_ENDBLOCKDATA (classAnnotation)	
DEBUG	  Reading Super Class of com.sun.crypto.provider.SealedObjectForKeyProtector	
DEBUG	    OpCode: 0x72 -- TC_CLASSDESC (at offset 0x47)	
DEBUG	    [classdesc]	
DEBUG	    Class name: javax.crypto.SealedObject	
DEBUG	    ## New reference handle 0x7E0001: JavaClass -> [javax.crypto.SealedObject:0x3E363DA6C3B75470]	
DEBUG	    Serial: 0x3E363DA6C3B75470 / 4482838265551344752 - classDescFlags: 0x2 SC_SERIALIZABLE	
DEBUG	    Fields num: 0x4	
DEBUG	    > Reading field encodedParams	
DEBUG	      OpCode: 0x74 -- TC_STRING (at offset 0x7E)	
DEBUG	      [string]	
DEBUG	      ## New reference handle 0x7E0002: JavaString -> '[B'	
DEBUG	    < FieldName: 0x5B Name:encodedParams Type:[B ID:0	
DEBUG	    > Reading field encryptedContent	
DEBUG	      OpCode: 0x71 -- TC_REFERENCE (at offset 0x96)	
DEBUG	      ## Reference handle: 0x7E0002	
DEBUG	      ###-> Type: <class 'javaobj.core.JavaString'> - Value: [B	
DEBUG	    < FieldName: 0x5B Name:encryptedContent Type:[B ID:1	
DEBUG	    > Reading field paramsAlg	
DEBUG	      OpCode: 0x74 -- TC_STRING (at offset 0xA7)	
DEBUG	      [string]	
DEBUG	      ## New reference handle 0x7E0003: JavaString -> 'Ljava/lang/String;'	
DEBUG	    < FieldName: 0x4C Name:paramsAlg Type:Ljava/lang/String; ID:2	
DEBUG	    > Reading field sealAlg	
DEBUG	      OpCode: 0x71 -- TC_REFERENCE (at offset 0xC6)	
DEBUG	      ## Reference handle: 0x7E0003	
DEBUG	      ###-> Type: <class 'javaobj.core.JavaString'> - Value: Ljava/lang/String;	
DEBUG	    < FieldName: 0x4C Name:sealAlg Type:Ljava/lang/String; ID:3	
DEBUG	    OpCode: 0x78 -- TC_ENDBLOCKDATA (classAnnotation)	
DEBUG	    Reading Super Class of javax.crypto.SealedObject	
DEBUG	      OpCode: 0x70 -- TC_NULL (at offset 0xCC)	
DEBUG	    Super Class for javax.crypto.SealedObject: None	
DEBUG	  Super Class for com.sun.crypto.provider.SealedObjectForKeyProtector: [javax.crypto.SealedObject:0x3E363DA6C3B75470]	
DEBUG	## New reference handle 0x7E0004: JavaObject -> <javaobj:com.sun.crypto.provider.SealedObjectForKeyProtector>	
DEBUG	Constructing class...	
DEBUG	  Class: com.sun.crypto.provider.SealedObjectForKeyProtector	
DEBUG	  Class: javax.crypto.SealedObject	
DEBUG	    [B encodedParams - [B encryptedContent - Ljava/lang/String; paramsAlg - Ljava/lang/String; sealAlg	
DEBUG	Values count: 4	
DEBUG	Prepared list of values: ['encodedParams', 'encryptedContent', 'paramsAlg', 'sealAlg']	
DEBUG	Prepared list of types: ['[B', '[B', 'Ljava/lang/String;', 'Ljava/lang/String;']	
DEBUG	Reading field: [B - encodedParams	
DEBUG	  OpCode: 0x75 -- TC_ARRAY (at offset 0xCD)	
DEBUG	  [array]	
DEBUG	    OpCode: 0x72 -- TC_CLASSDESC (at offset 0xCE)	
DEBUG	    [classdesc]	
DEBUG	    Class name: [B	
DEBUG	    ## New reference handle 0x7E0005: JavaClass -> [[B:0x-530CE807F9F7AB20]	
DEBUG	    Serial: 0x-530CE807F9F7AB20 / -5984413125824719648 - classDescFlags: 0x2 SC_SERIALIZABLE	
DEBUG	    Fields num: 0x0	
DEBUG	    OpCode: 0x78 -- TC_ENDBLOCKDATA (classAnnotation)	
DEBUG	    Reading Super Class of [B	
DEBUG	      OpCode: 0x70 -- TC_NULL (at offset 0xDF)	
DEBUG	    Super Class for [B: None	
DEBUG	  ## New reference handle 0x7E0006: JavaArray -> []	
DEBUG	  size: 17	
DEBUG	* [ encodedParams: <javaobj:[B>	
DEBUG	Reading field: [B - encryptedContent	
DEBUG	  OpCode: 0x75 -- TC_ARRAY (at offset 0xF5)	
DEBUG	  [array]	
DEBUG	    OpCode: 0x71 -- TC_REFERENCE (at offset 0xF6)	
DEBUG	    ## Reference handle: 0x7E0005	
DEBUG	    ###-> Type: <class 'javaobj.core.JavaClass'> - Value: [[B:0x-530CE807F9F7AB20]	
DEBUG	  ## New reference handle 0x7E0007: JavaArray -> []	
DEBUG	  size: 136	
DEBUG	* [ encryptedContent: <javaobj:[B>	
DEBUG	Reading field: Ljava/lang/String; - paramsAlg	
DEBUG	  OpCode: 0x74 -- TC_STRING (at offset 0x187)	
DEBUG	  [string]	
DEBUG	  ## New reference handle 0x7E0008: JavaString -> 'PBEWithMD5AndTripleDES'	
DEBUG	* L paramsAlg: 'PBEWithMD5AndTripleDES'	
DEBUG	Reading field: Ljava/lang/String; - sealAlg	
DEBUG	  OpCode: 0x74 -- TC_STRING (at offset 0x1A0)	
DEBUG	  [string]	
DEBUG	  ## New reference handle 0x7E0009: JavaString -> 'PBEWithMD5AndTripleDES'	
DEBUG	* L sealAlg: 'PBEWithMD5AndTripleDES'	
DEBUG	>>> java_object: <javaobj:com.sun.crypto.provider.SealedObjectForKeyProtector>	
DEBUG	Java Object unmarshalled successfully!	
DEBUG	OpCode: 0x73 -- TC_OBJECT (at offset 0x4)	
DEBUG	[object]	
DEBUG	java_object.annotations just after instantiation: []	
DEBUG	  OpCode: 0x72 -- TC_CLASSDESC (at offset 0x5)	
DEBUG	  [classdesc]	
DEBUG	  Class name: com.sun.crypto.provider.SealedObjectForKeyProtector	
DEBUG	  ## New reference handle 0x7E0000: JavaClass -> [com.sun.crypto.provider.SealedObjectForKeyProtector:0x-32A835A618CF44AD]	
DEBUG	  Serial: 0x-32A835A618CF44AD / -3650226485480866989 - classDescFlags: 0x2 SC_SERIALIZABLE	
DEBUG	  Fields num: 0x0	
DEBUG	  OpCode: 0x78 -- TC_ENDBLOCKDATA (classAnnotation)	
DEBUG	  Reading Super Class of com.sun.crypto.provider.SealedObjectForKeyProtector	
DEBUG	    OpCode: 0x72 -- TC_CLASSDESC (at offset 0x47)	
DEBUG	    [classdesc]	
DEBUG	    Class name: javax.crypto.SealedObject	
DEBUG	    ## New reference handle 0x7E0001: JavaClass -> [javax.crypto.SealedObject:0x3E363DA6C3B75470]	
DEBUG	    Serial: 0x3E363DA6C3B75470 / 4482838265551344752 - classDescFlags: 0x2 SC_SERIALIZABLE	
DEBUG	    Fields num: 0x4	
DEBUG	    > Reading field encodedParams	
DEBUG	      OpCode: 0x74 -- TC_STRING (at offset 0x7E)	
DEBUG	      [string]	
DEBUG	      ## New reference handle 0x7E0002: JavaString -> '[B'	
DEBUG	    < FieldName: 0x5B Name:encodedParams Type:[B ID:0	
DEBUG	    > Reading field encryptedContent	
DEBUG	      OpCode: 0x71 -- TC_REFERENCE (at offset 0x96)	
DEBUG	      ## Reference handle: 0x7E0002	
DEBUG	      ###-> Type: <class 'javaobj.core.JavaString'> - Value: [B	
DEBUG	    < FieldName: 0x5B Name:encryptedContent Type:[B ID:1	
DEBUG	    > Reading field paramsAlg	
DEBUG	      OpCode: 0x74 -- TC_STRING (at offset 0xA7)	
DEBUG	      [string]	
DEBUG	      ## New reference handle 0x7E0003: JavaString -> 'Ljava/lang/String;'	
DEBUG	    < FieldName: 0x4C Name:paramsAlg Type:Ljava/lang/String; ID:2	
DEBUG	    > Reading field sealAlg	
DEBUG	      OpCode: 0x71 -- TC_REFERENCE (at offset 0xC6)	
DEBUG	      ## Reference handle: 0x7E0003	
DEBUG	      ###-> Type: <class 'javaobj.core.JavaString'> - Value: Ljava/lang/String;	
DEBUG	    < FieldName: 0x4C Name:sealAlg Type:Ljava/lang/String; ID:3	
DEBUG	    OpCode: 0x78 -- TC_ENDBLOCKDATA (classAnnotation)	
DEBUG	    Reading Super Class of javax.crypto.SealedObject	
DEBUG	      OpCode: 0x70 -- TC_NULL (at offset 0xCC)	
DEBUG	    Super Class for javax.crypto.SealedObject: None	
DEBUG	  Super Class for com.sun.crypto.provider.SealedObjectForKeyProtector: [javax.crypto.SealedObject:0x3E363DA6C3B75470]	
DEBUG	## New reference handle 0x7E0004: JavaObject -> <javaobj:com.sun.crypto.provider.SealedObjectForKeyProtector>	
DEBUG	Constructing class...	
DEBUG	  Class: com.sun.crypto.provider.SealedObjectForKeyProtector	
DEBUG	  Class: javax.crypto.SealedObject	
DEBUG	    [B encodedParams - [B encryptedContent - Ljava/lang/String; paramsAlg - Ljava/lang/String; sealAlg	
DEBUG	Values count: 4	
DEBUG	Prepared list of values: ['encodedParams', 'encryptedContent', 'paramsAlg', 'sealAlg']	
DEBUG	Prepared list of types: ['[B', '[B', 'Ljava/lang/String;', 'Ljava/lang/String;']	
DEBUG	Reading field: [B - encodedParams	
DEBUG	  OpCode: 0x75 -- TC_ARRAY (at offset 0xCD)	
DEBUG	  [array]	
DEBUG	    OpCode: 0x72 -- TC_CLASSDESC (at offset 0xCE)	
DEBUG	    [classdesc]	
DEBUG	    Class name: [B	
DEBUG	    ## New reference handle 0x7E0005: JavaClass -> [[B:0x-530CE807F9F7AB20]	
DEBUG	    Serial: 0x-530CE807F9F7AB20 / -5984413125824719648 - classDescFlags: 0x2 SC_SERIALIZABLE	
DEBUG	    Fields num: 0x0	
DEBUG	    OpCode: 0x78 -- TC_ENDBLOCKDATA (classAnnotation)	
DEBUG	    Reading Super Class of [B	
DEBUG	      OpCode: 0x70 -- TC_NULL (at offset 0xDF)	
DEBUG	    Super Class for [B: None	
DEBUG	  ## New reference handle 0x7E0006: JavaArray -> []	
DEBUG	  size: 17	
DEBUG	* [ encodedParams: <javaobj:[B>	
DEBUG	Reading field: [B - encryptedContent	
DEBUG	  OpCode: 0x75 -- TC_ARRAY (at offset 0xF5)	
DEBUG	  [array]	
DEBUG	    OpCode: 0x71 -- TC_REFERENCE (at offset 0xF6)	
DEBUG	    ## Reference handle: 0x7E0005	
DEBUG	    ###-> Type: <class 'javaobj.core.JavaClass'> - Value: [[B:0x-530CE807F9F7AB20]	
DEBUG	  ## New reference handle 0x7E0007: JavaArray -> []	
DEBUG	  size: 192	
DEBUG	* [ encryptedContent: <javaobj:[B>	
DEBUG	Reading field: Ljava/lang/String; - paramsAlg	
DEBUG	  OpCode: 0x74 -- TC_STRING (at offset 0x1BF)	
DEBUG	  [string]	
DEBUG	  ## New reference handle 0x7E0008: JavaString -> 'PBEWithMD5AndTripleDES'	
DEBUG	* L paramsAlg: 'PBEWithMD5AndTripleDES'	
DEBUG	Reading field: Ljava/lang/String; - sealAlg	
DEBUG	  OpCode: 0x74 -- TC_STRING (at offset 0x1D8)	
DEBUG	  [string]	
DEBUG	  ## New reference handle 0x7E0009: JavaString -> 'PBEWithMD5AndTripleDES'	
DEBUG	* L sealAlg: 'PBEWithMD5AndTripleDES'	
DEBUG	>>> java_object: <javaobj:com.sun.crypto.provider.SealedObjectForKeyProtector>	
DEBUG	Java Object unmarshalled successfully!	
DEBUG	OpCode: 0x73 -- TC_OBJECT (at offset 0x4)	
DEBUG	[object]	
DEBUG	java_object.annotations just after instantiation: []	
DEBUG	  OpCode: 0x72 -- TC_CLASSDESC (at offset 0x5)	
DEBUG	  [classdesc]	
DEBUG	  Class name: com.sun.crypto.provider.SealedObjectForKeyProtector	
DEBUG	  ## New reference handle 0x7E0000: JavaClass -> [com.sun.crypto.provider.SealedObjectForKeyProtector:0x-32A835A618CF44AD]	
DEBUG	  Serial: 0x-32A835A618CF44AD / -3650226485480866989 - classDescFlags: 0x2 SC_SERIALIZABLE	
DEBUG	  Fields num: 0x0	
DEBUG	  OpCode: 0x78 -- TC_ENDBLOCKDATA (classAnnotation)	
DEBUG	  Reading Super Class of com.sun.crypto.provider.SealedObjectForKeyProtector	
DEBUG	    OpCode: 0x72 -- TC_CLASSDESC (at offset 0x47)	
DEBUG	    [classdesc]	
DEBUG	    Class name: javax.crypto.SealedObject	
DEBUG	    ## New reference handle 0x7E0001: JavaClass -> [javax.crypto.SealedObject:0x3E363DA6C3B75470]	
DEBUG	    Serial: 0x3E363DA6C3B75470 / 4482838265551344752 - classDescFlags: 0x2 SC_SERIALIZABLE	
DEBUG	    Fields num: 0x4	
DEBUG	    > Reading field encodedParams	
DEBUG	      OpCode: 0x74 -- TC_STRING (at offset 0x7E)	
DEBUG	      [string]	
DEBUG	      ## New reference handle 0x7E0002: JavaString -> '[B'	
DEBUG	    < FieldName: 0x5B Name:encodedParams Type:[B ID:0	
DEBUG	    > Reading field encryptedContent	
DEBUG	      OpCode: 0x71 -- TC_REFERENCE (at offset 0x96)	
DEBUG	      ## Reference handle: 0x7E0002	
DEBUG	      ###-> Type: <class 'javaobj.core.JavaString'> - Value: [B	
DEBUG	    < FieldName: 0x5B Name:encryptedContent Type:[B ID:1	
DEBUG	    > Reading field paramsAlg	
DEBUG	      OpCode: 0x74 -- TC_STRING (at offset 0xA7)	
DEBUG	      [string]	
DEBUG	      ## New reference handle 0x7E0003: JavaString -> 'Ljava/lang/String;'	
DEBUG	    < FieldName: 0x4C Name:paramsAlg Type:Ljava/lang/String; ID:2	
DEBUG	    > Reading field sealAlg	
DEBUG	      OpCode: 0x71 -- TC_REFERENCE (at offset 0xC6)	
DEBUG	      ## Reference handle: 0x7E0003	
DEBUG	      ###-> Type: <class 'javaobj.core.JavaString'> - Value: Ljava/lang/String;	
DEBUG	    < FieldName: 0x4C Name:sealAlg Type:Ljava/lang/String; ID:3	
DEBUG	    OpCode: 0x78 -- TC_ENDBLOCKDATA (classAnnotation)	
DEBUG	    Reading Super Class of javax.crypto.SealedObject	
DEBUG	      OpCode: 0x70 -- TC_NULL (at offset 0xCC)	
DEBUG	    Super Class for javax.crypto.SealedObject: None	
DEBUG	  Super Class for com.sun.crypto.provider.SealedObjectForKeyProtector: [javax.crypto.SealedObject:0x3E363DA6C3B75470]	
DEBUG	## New reference handle 0x7E0004: JavaObject -> <javaobj:com.sun.crypto.provider.SealedObjectForKeyProtector>	
DEBUG	Constructing class...	
DEBUG	  Class: com.sun.crypto.provider.SealedObjectForKeyProtector	
DEBUG	  Class: javax.crypto.SealedObject	
DEBUG	    [B encodedParams - [B encryptedContent - Ljava/lang/String; paramsAlg - Ljava/lang/String; sealAlg	
DEBUG	Values count: 4	
DEBUG	Prepared list of values: ['encodedParams', 'encryptedContent', 'paramsAlg', 'sealAlg']	
DEBUG	Prepared list of types: ['[B', '[B', 'Ljava/lang/String;', 'Ljava/lang/String;']	
DEBUG	Reading field: [B - encodedParams	
DEBUG	  OpCode: 0x75 -- TC_ARRAY (at offset 0xCD)	
DEBUG	  [array]	
DEBUG	    OpCode: 0x72 -- TC_CLASSDESC (at offset 0xCE)	
DEBUG	    [classdesc]	
DEBUG	    Class name: [B	
DEBUG	    ## New reference handle 0x7E0005: JavaClass -> [[B:0x-530CE807F9F7AB20]	
DEBUG	    Serial: 0x-530CE807F9F7AB20 / -5984413125824719648 - classDescFlags: 0x2 SC_SERIALIZABLE	
DEBUG	    Fields num: 0x0	
DEBUG	    OpCode: 0x78 -- TC_ENDBLOCKDATA (classAnnotation)	
DEBUG	    Reading Super Class of [B	
DEBUG	      OpCode: 0x70 -- TC_NULL (at offset 0xDF)	
DEBUG	    Super Class for [B: None	
DEBUG	  ## New reference handle 0x7E0006: JavaArray -> []	
DEBUG	  size: 17	
DEBUG	* [ encodedParams: <javaobj:[B>	
DEBUG	Reading field: [B - encryptedContent	
DEBUG	  OpCode: 0x75 -- TC_ARRAY (at offset 0xF5)	
DEBUG	  [array]	
DEBUG	    OpCode: 0x71 -- TC_REFERENCE (at offset 0xF6)	
DEBUG	    ## Reference handle: 0x7E0005	
DEBUG	    ###-> Type: <class 'javaobj.core.JavaClass'> - Value: [[B:0x-530CE807F9F7AB20]	
DEBUG	  ## New reference handle 0x7E0007: JavaArray -> []	
DEBUG	  size: 136	
DEBUG	* [ encryptedContent: <javaobj:[B>	
DEBUG	Reading field: Ljava/lang/String; - paramsAlg	
DEBUG	  OpCode: 0x74 -- TC_STRING (at offset 0x187)	
DEBUG	  [string]	
DEBUG	  ## New reference handle 0x7E0008: JavaString -> 'PBEWithMD5AndTripleDES'	
DEBUG	* L paramsAlg: 'PBEWithMD5AndTripleDES'	
DEBUG	Reading field: Ljava/lang/String; - sealAlg	
DEBUG	  OpCode: 0x74 -- TC_STRING (at offset 0x1A0)	
DEBUG	  [string]	
DEBUG	  ## New reference handle 0x7E0009: JavaString -> 'PBEWithMD5AndTripleDES'	
DEBUG	* L sealAlg: 'PBEWithMD5AndTripleDES'	
DEBUG	>>> java_object: <javaobj:com.sun.crypto.provider.SealedObjectForKeyProtector>	
DEBUG	Java Object unmarshalled successfully!	
DEBUG	OpCode: 0x73 -- TC_OBJECT (at offset 0x4)	
DEBUG	[object]	
DEBUG	java_object.annotations just after instantiation: []	
DEBUG	  OpCode: 0x72 -- TC_CLASSDESC (at offset 0x5)	
DEBUG	  [classdesc]	
DEBUG	  Class name: com.sun.crypto.provider.SealedObjectForKeyProtector	
DEBUG	  ## New reference handle 0x7E0000: JavaClass -> [com.sun.crypto.provider.SealedObjectForKeyProtector:0x-32A835A618CF44AD]	
DEBUG	  Serial: 0x-32A835A618CF44AD / -3650226485480866989 - classDescFlags: 0x2 SC_SERIALIZABLE	
DEBUG	  Fields num: 0x0	
DEBUG	  OpCode: 0x78 -- TC_ENDBLOCKDATA (classAnnotation)	
DEBUG	  Reading Super Class of com.sun.crypto.provider.SealedObjectForKeyProtector	
DEBUG	    OpCode: 0x72 -- TC_CLASSDESC (at offset 0x47)	
DEBUG	    [classdesc]	
DEBUG	    Class name: javax.crypto.SealedObject	
DEBUG	    ## New reference handle 0x7E0001: JavaClass -> [javax.crypto.SealedObject:0x3E363DA6C3B75470]	
DEBUG	    Serial: 0x3E363DA6C3B75470 / 4482838265551344752 - classDescFlags: 0x2 SC_SERIALIZABLE	
DEBUG	    Fields num: 0x4	
DEBUG	    > Reading field encodedParams	
DEBUG	      OpCode: 0x74 -- TC_STRING (at offset 0x7E)	
DEBUG	      [string]	
DEBUG	      ## New reference handle 0x7E0002: JavaString -> '[B'	
DEBUG	    < FieldName: 0x5B Name:encodedParams Type:[B ID:0	
DEBUG	    > Reading field encryptedContent	
DEBUG	      OpCode: 0x71 -- TC_REFERENCE (at offset 0x96)	
DEBUG	      ## Reference handle: 0x7E0002	
DEBUG	      ###-> Type: <class 'javaobj.core.JavaString'> - Value: [B	
DEBUG	    < FieldName: 0x5B Name:encryptedContent Type:[B ID:1	
DEBUG	    > Reading field paramsAlg	
DEBUG	      OpCode: 0x74 -- TC_STRING (at offset 0xA7)	
DEBUG	      [string]	
DEBUG	      ## New reference handle 0x7E0003: JavaString -> 'Ljava/lang/String;'	
DEBUG	    < FieldName: 0x4C Name:paramsAlg Type:Ljava/lang/String; ID:2	
DEBUG	    > Reading field sealAlg	
DEBUG	      OpCode: 0x71 -- TC_REFERENCE (at offset 0xC6)	
DEBUG	      ## Reference handle: 0x7E0003	
DEBUG	      ###-> Type: <class 'javaobj.core.JavaString'> - Value: Ljava/lang/String;	
DEBUG	    < FieldName: 0x4C Name:sealAlg Type:Ljava/lang/String; ID:3	
DEBUG	    OpCode: 0x78 -- TC_ENDBLOCKDATA (classAnnotation)	
DEBUG	    Reading Super Class of javax.crypto.SealedObject	
DEBUG	      OpCode: 0x70 -- TC_NULL (at offset 0xCC)	
DEBUG	    Super Class for javax.crypto.SealedObject: None	
DEBUG	  Super Class for com.sun.crypto.provider.SealedObjectForKeyProtector: [javax.crypto.SealedObject:0x3E363DA6C3B75470]	
DEBUG	## New reference handle 0x7E0004: JavaObject -> <javaobj:com.sun.crypto.provider.SealedObjectForKeyProtector>	
DEBUG	Constructing class...	
DEBUG	  Class: com.sun.crypto.provider.SealedObjectForKeyProtector	
DEBUG	  Class: javax.crypto.SealedObject	
DEBUG	    [B encodedParams - [B encryptedContent - Ljava/lang/String; paramsAlg - Ljava/lang/String; sealAlg	
DEBUG	Values count: 4	
DEBUG	Prepared list of values: ['encodedParams', 'encryptedContent', 'paramsAlg', 'sealAlg']	
DEBUG	Prepared list of types: ['[B', '[B', 'Ljava/lang/String;', 'Ljava/lang/String;']	
DEBUG	Reading field: [B - encodedParams	
DEBUG	  OpCode: 0x75 -- TC_ARRAY (at offset 0xCD)	
DEBUG	  [array]	
DEBUG	    OpCode: 0x72 -- TC_CLASSDESC (at offset 0xCE)	
DEBUG	    [classdesc]	
DEBUG	    Class name: [B	
DEBUG	    ## New reference handle 0x7E0005: JavaClass -> [[B:0x-530CE807F9F7AB20]	
DEBUG	    Serial: 0x-530CE807F9F7AB20 / -5984413125824719648 - classDescFlags: 0x2 SC_SERIALIZABLE	
DEBUG	    Fields num: 0x0	
DEBUG	    OpCode: 0x78 -- TC_ENDBLOCKDATA (classAnnotation)	
DEBUG	    Reading Super Class of [B	
DEBUG	      OpCode: 0x70 -- TC_NULL (at offset 0xDF)	
DEBUG	    Super Class for [B: None	
DEBUG	  ## New reference handle 0x7E0006: JavaArray -> []	
DEBUG	  size: 17	
DEBUG	* [ encodedParams: <javaobj:[B>	
DEBUG	Reading field: [B - encryptedContent	
DEBUG	  OpCode: 0x75 -- TC_ARRAY (at offset 0xF5)	
DEBUG	  [array]	
DEBUG	    OpCode: 0x71 -- TC_REFERENCE (at offset 0xF6)	
DEBUG	    ## Reference handle: 0x7E0005	
DEBUG	    ###-> Type: <class 'javaobj.core.JavaClass'> - Value: [[B:0x-530CE807F9F7AB20]	
DEBUG	  ## New reference handle 0x7E0007: JavaArray -> []	
DEBUG	  size: 160	
DEBUG	* [ encryptedContent: <javaobj:[B>	
DEBUG	Reading field: Ljava/lang/String; - paramsAlg	
DEBUG	  OpCode: 0x74 -- TC_STRING (at offset 0x19F)	
DEBUG	  [string]	
DEBUG	  ## New reference handle 0x7E0008: JavaString -> 'PBEWithMD5AndTripleDES'	
DEBUG	* L paramsAlg: 'PBEWithMD5AndTripleDES'	
DEBUG	Reading field: Ljava/lang/String; - sealAlg	
DEBUG	  OpCode: 0x74 -- TC_STRING (at offset 0x1B8)	
DEBUG	  [string]	
DEBUG	  ## New reference handle 0x7E0009: JavaString -> 'PBEWithMD5AndTripleDES'	
DEBUG	* L sealAlg: 'PBEWithMD5AndTripleDES'	
DEBUG	>>> java_object: <javaobj:com.sun.crypto.provider.SealedObjectForKeyProtector>	
DEBUG	Java Object unmarshalled successfully!	
DEBUG	OpCode: 0x73 -- TC_OBJECT (at offset 0x4)	
DEBUG	[object]	
DEBUG	java_object.annotations just after instantiation: []	
DEBUG	  OpCode: 0x72 -- TC_CLASSDESC (at offset 0x5)	
DEBUG	  [classdesc]	
DEBUG	  Class name: com.sun.crypto.provider.SealedObjectForKeyProtector	
DEBUG	  ## New reference handle 0x7E0000: JavaClass -> [com.sun.crypto.provider.SealedObjectForKeyProtector:0x-32A835A618CF44AD]	
DEBUG	  Serial: 0x-32A835A618CF44AD / -3650226485480866989 - classDescFlags: 0x2 SC_SERIALIZABLE	
DEBUG	  Fields num: 0x0	
DEBUG	  OpCode: 0x78 -- TC_ENDBLOCKDATA (classAnnotation)	
DEBUG	  Reading Super Class of com.sun.crypto.provider.SealedObjectForKeyProtector	
DEBUG	    OpCode: 0x72 -- TC_CLASSDESC (at offset 0x47)	
DEBUG	    [classdesc]	
DEBUG	    Class name: javax.crypto.SealedObject	
DEBUG	    ## New reference handle 0x7E0001: JavaClass -> [javax.crypto.SealedObject:0x3E363DA6C3B75470]	
DEBUG	    Serial: 0x3E363DA6C3B75470 / 4482838265551344752 - classDescFlags: 0x2 SC_SERIALIZABLE	
DEBUG	    Fields num: 0x4	
DEBUG	    > Reading field encodedParams	
DEBUG	      OpCode: 0x74 -- TC_STRING (at offset 0x7E)	
DEBUG	      [string]	
DEBUG	      ## New reference handle 0x7E0002: JavaString -> '[B'	
DEBUG	    < FieldName: 0x5B Name:encodedParams Type:[B ID:0	
DEBUG	    > Reading field encryptedContent	
DEBUG	      OpCode: 0x71 -- TC_REFERENCE (at offset 0x96)	
DEBUG	      ## Reference handle: 0x7E0002	
DEBUG	      ###-> Type: <class 'javaobj.core.JavaString'> - Value: [B	
DEBUG	    < FieldName: 0x5B Name:encryptedContent Type:[B ID:1	
DEBUG	    > Reading field paramsAlg	
DEBUG	      OpCode: 0x74 -- TC_STRING (at offset 0xA7)	
DEBUG	      [string]	
DEBUG	      ## New reference handle 0x7E0003: JavaString -> 'Ljava/lang/String;'	
DEBUG	    < FieldName: 0x4C Name:paramsAlg Type:Ljava/lang/String; ID:2	
DEBUG	    > Reading field sealAlg	
DEBUG	      OpCode: 0x71 -- TC_REFERENCE (at offset 0xC6)	
DEBUG	      ## Reference handle: 0x7E0003	
DEBUG	      ###-> Type: <class 'javaobj.core.JavaString'> - Value: Ljava/lang/String;	
DEBUG	    < FieldName: 0x4C Name:sealAlg Type:Ljava/lang/String; ID:3	
DEBUG	    OpCode: 0x78 -- TC_ENDBLOCKDATA (classAnnotation)	
DEBUG	    Reading Super Class of javax.crypto.SealedObject	
DEBUG	      OpCode: 0x70 -- TC_NULL (at offset 0xCC)	
DEBUG	    Super Class for javax.crypto.SealedObject: None	
DEBUG	  Super Class for com.sun.crypto.provider.SealedObjectForKeyProtector: [javax.crypto.SealedObject:0x3E363DA6C3B75470]	
DEBUG	## New reference handle 0x7E0004: JavaObject -> <javaobj:com.sun.crypto.provider.SealedObjectForKeyProtector>	
DEBUG	Constructing class...	
DEBUG	  Class: com.sun.crypto.provider.SealedObjectForKeyProtector	
DEBUG	  Class: javax.crypto.SealedObject	
DEBUG	    [B encodedParams - [B encryptedContent - Ljava/lang/String; paramsAlg - Ljava/lang/String; sealAlg	
DEBUG	Values count: 4	
DEBUG	Prepared list of values: ['encodedParams', 'encryptedContent', 'paramsAlg', 'sealAlg']	
DEBUG	Prepared list of types: ['[B', '[B', 'Ljava/lang/String;', 'Ljava/lang/String;']	
DEBUG	Reading field: [B - encodedParams	
DEBUG	  OpCode: 0x75 -- TC_ARRAY (at offset 0xCD)	
DEBUG	  [array]	
DEBUG	    OpCode: 0x72 -- TC_CLASSDESC (at offset 0xCE)	
DEBUG	    [classdesc]	
DEBUG	    Class name: [B	
DEBUG	    ## New reference handle 0x7E0005: JavaClass -> [[B:0x-530CE807F9F7AB20]	
DEBUG	    Serial: 0x-530CE807F9F7AB20 / -5984413125824719648 - classDescFlags: 0x2 SC_SERIALIZABLE	
DEBUG	    Fields num: 0x0	
DEBUG	    OpCode: 0x78 -- TC_ENDBLOCKDATA (classAnnotation)	
DEBUG	    Reading Super Class of [B	
DEBUG	      OpCode: 0x70 -- TC_NULL (at offset 0xDF)	
DEBUG	    Super Class for [B: None	
DEBUG	  ## New reference handle 0x7E0006: JavaArray -> []	
DEBUG	  size: 17	
DEBUG	* [ encodedParams: <javaobj:[B>	
DEBUG	Reading field: [B - encryptedContent	
DEBUG	  OpCode: 0x75 -- TC_ARRAY (at offset 0xF5)	
DEBUG	  [array]	
DEBUG	    OpCode: 0x71 -- TC_REFERENCE (at offset 0xF6)	
DEBUG	    ## Reference handle: 0x7E0005	
DEBUG	    ###-> Type: <class 'javaobj.core.JavaClass'> - Value: [[B:0x-530CE807F9F7AB20]	
DEBUG	  ## New reference handle 0x7E0007: JavaArray -> []	
DEBUG	  size: 136	
DEBUG	* [ encryptedContent: <javaobj:[B>	
DEBUG	Reading field: Ljava/lang/String; - paramsAlg	
DEBUG	  OpCode: 0x74 -- TC_STRING (at offset 0x187)	
DEBUG	  [string]	
DEBUG	  ## New reference handle 0x7E0008: JavaString -> 'PBEWithMD5AndTripleDES'	
DEBUG	* L paramsAlg: 'PBEWithMD5AndTripleDES'	
DEBUG	Reading field: Ljava/lang/String; - sealAlg	
DEBUG	  OpCode: 0x74 -- TC_STRING (at offset 0x1A0)	
DEBUG	  [string]	
DEBUG	  ## New reference handle 0x7E0009: JavaString -> 'PBEWithMD5AndTripleDES'	
DEBUG	* L sealAlg: 'PBEWithMD5AndTripleDES'	
DEBUG	>>> java_object: <javaobj:com.sun.crypto.provider.SealedObjectForKeyProtector>	
DEBUG	Java Object unmarshalled successfully!	
FAIL	OSError: The stream is not java serialized object. Invalid stream header: E112A27B	
DEBUG	Traceback (most recent call last):
  ...
  File "/root/workspace/ken-validation-build_master-KUMZ5YYY7SRB2MFZBRV44JYHFA6WYN3MGJYDHZ4Y5RRPLHUOOLUA/dependencies/lib/python3.6/site-packages/jks/util.py", line 92, in load
    try_decrypt_keys=try_decrypt_keys)
  File "/root/workspace/ken-validation-build_master-KUMZ5YYY7SRB2MFZBRV44JYHFA6WYN3MGJYDHZ4Y5RRPLHUOOLUA/dependencies/lib/python3.6/site-packages/jks/jks.py", line 525, in loads
    entry.decrypt(store_password)
  File "/root/workspace/ken-validation-build_master-KUMZ5YYY7SRB2MFZBRV44JYHFA6WYN3MGJYDHZ4Y5RRPLHUOOLUA/dependencies/lib/python3.6/site-packages/jks/jks.py", line 336, in decrypt
    obj, dummy = KeyStore._read_java_obj(plaintext, 0)
  File "/root/workspace/ken-validation-build_master-KUMZ5YYY7SRB2MFZBRV44JYHFA6WYN3MGJYDHZ4Y5RRPLHUOOLUA/dependencies/lib/python3.6/site-packages/jks/jks.py", line 724, in _read_java_obj
    obj = javaobj.load(data_stream, ignore_remaining_data=ignore_remaining_data)
  File "/root/workspace/ken-validation-build_master-KUMZ5YYY7SRB2MFZBRV44JYHFA6WYN3MGJYDHZ4Y5RRPLHUOOLUA/dependencies/lib/python3.6/site-packages/javaobj/core.py", line 116, in load
    file_object, kwargs.get("use_numpy_arrays", False)
  File "/root/workspace/ken-validation-build_master-KUMZ5YYY7SRB2MFZBRV44JYHFA6WYN3MGJYDHZ4Y5RRPLHUOOLUA/dependencies/lib/python3.6/site-packages/javaobj/core.py", line 517, in __init__
    self._readStreamHeader()
  File "/root/workspace/ken-validation-build_master-KUMZ5YYY7SRB2MFZBRV44JYHFA6WYN3MGJYDHZ4Y5RRPLHUOOLUA/dependencies/lib/python3.6/site-packages/javaobj/core.py", line 569, in _readStreamHeader
    "Invalid stream header: {0:04X}{1:04X}".format(magic, version)

Any idea / tip to fix this ?

Hash mismatch; incorrect keystore password? for a BKS file

Portecle 1.9 opens the attached secret.bks file without any problems.

secret.zip

However running readks.py --type=bks secret.bks secret results in Hash mismatch; incorrect keystore password? error message.

secret.bks file is full of NULL bytes at the end, and I suspect that this is causing the HMAC signature extraction and calculation to fail. I wonder how Portecle is dealing with such files.

javaobj blocks 2.6 backwards compat

Lately I've been working on docs and testing, and in adding tox I discovered the extent of our backwards incompatibility. As of now, I've got pyjks locally python2.6 syntax-compatible (and will commit the changes shortly), but I discovered that javaobj is Python 2.7+ only.

Given the relatively small extent of javaobj usage last I checked, we had discussed maybe switching to a simpler dependency, even an internal util, that covered just the cases we needed.

Other options include making javaobj 2.6 compatible, or (the easiest) making pyjks 2.7+ only.

Import for pyjks fails after pip Install

The pip package for pyjks results in multiple runtime errors after adding jks reference to project in Python 3.9.

Repro Steps:

  1. Run pip install pyjks at the command line to install package.
  2. Create a new python file and add import jks -> save file.
  3. Execute python script.

Actual Results:
Library does not pass sanity smoke test. The following skid mark of errors are thrown:
image

Expected Results:
Without even calling any methods in pyjks yet, python script should not throw runtime errors simply by adding a reference (import jks).

FWIW for additional reference, here is the output showing the pip installation of pyjks:
image

Environment:
OS: Windows 10.19041.572
Python: 3.9
PIP: 20.2.4

Provide support for keystores with no/empty passphrase

I have several keystores with blank passphrases.

KeyStore.open() requires a passphrase param. Using None, \n, and '' don't work as valid values. There should be a way to open keystores that were created without a passphrase.

One solution would be to make the passphrase parameter optional.

make password optional in jks.KeyStore.load()

keytool lets you query some information in a password-protected keystore without specifying the password. I would like to do the same with pyjks. This would be useful to querying basic information about the keystore, like number of entries, type of entries, alias, etc.

$ keytool -list -keystore keystore.jks -protected

*****************  WARNING WARNING WARNING  *****************
* The integrity of the information stored in your keystore  *
* has NOT been verified!  In order to verify its integrity, *
* you must provide your keystore password.                  *
*****************  WARNING WARNING WARNING  *****************

Keystore type: JKS
Keystore provider: SUN

Your keystore contains 1 entry

myspecialkeyalias, Sep 3, 2020, PrivateKeyEntry, 
Certificate fingerprint (SHA-256): EA:54:23:F7:05:04:A1:1F:B8:AA:F3:33:0F:52:77:25:71:15:C1:01:D3:61:F0:C9:42:11:D0:C0:5A:F0:48:5B

Warning:
The JKS keystore uses a proprietary format. It is recommended to migrate to PKCS12 which is an industry standard format using "keytool -importkeystore -srckeystore keystore.jks -destkeystore keystore.jks -deststoretype pkcs12".
$ keytool -list -keystore keystore.jks -storepass:env STOREPASS
Keystore type: JKS
Keystore provider: SUN

Your keystore contains 1 entry

sova.at.or.at, Sep 3, 2020, PrivateKeyEntry, 
Certificate fingerprint (SHA-256): EA:54:23:F7:05:04:A1:1F:B8:AA:F3:33:0F:52:77:25:71:15:C1:01:D3:61:F0:C9:42:11:D0:C0:5A:F0:48:5B

Warning:
The JKS keystore uses a proprietary format. It is recommended to migrate to PKCS12 which is an industry standard format using "keytool -importkeystore -srckeystore keystore.jks -destkeystore keystore.jks -deststoretype pkcs12".

This is probably related to #36

I'm getting the private_keys, certs and secret_keys. Any idea how I can use them to decrypt something?

So I succesfully get the private_keys, certs and secret_keys. At least, it prints out this:

{u'mirthconnect': <jks.jks.PrivateKeyEntry object at 0x7f4dbe91f9d0>}
{}
{u'encryption': <jks.jks.SecretKeyEntry object at 0x7f4dbe91f950>}

Now I need to use them to decrypt a string I read from a database. But I'm kinda lost in the fact that I have 3 different parts. Any idea how I can use these to decrypt a string in Python?

mistake in PyPI document

in the PyPI page you can see the following example:

import jks

keystore = jks.KeyStore.load('keystore.jks', 'passphrase')

print(ks.private_keys)
print(ks.certs)
print(ks.secret_keys)

you will get :

>>> print(ks.private_keys) Traceback (most recent call last): File "<stdin>", line 1, in <module> NameError: name 'ks' is not defined

Support for Python 2.7.x on windows

At the moment, the installation on Windows platform / Python 2.7.x is failing with this error (tested on appveyor) :

c:\projects\pyjks.tox\py\include\site\python2.7\twofish:
running install
running build
running build_py
creating build
creating build\lib.win32-2.7
copying twofish.py -> build\lib.win32-2.7
running build_ext
building '_twofish' extension
creating build\temp.win32-2.7
creating build\temp.win32-2.7\Release
creating build\temp.win32-2.7\Release\twofish-0.3
C:\Users\appveyor\AppData\Local\Programs\Common\Microsoft\Visual C++ for Python\9.0\VC\Bin\cl.exe /c /nologo /Ox /MD /W3 /GS- /DNDEBUG -Itwofish-0.3 -Ic:\python27\include -Ic:\projects\pyjks.tox\py\PC /Tctwofish-0.3/twofish.c /Fobuild\temp.win32-2.7\Release\twofish-0.3/twofish.obj
twofish.c
c:\users\appveyor\appdata\local\temp\1\pip-build-in0ieu\twofish\twofish-0.3\twofish.h(13) : fatal error C1083: Cannot open include file: 'stdint.h': No such file or directory
error: command 'C:\Users\appveyor\AppData\Local\Programs\Common\Microsoft\Visual C++ for Python\9.0\VC\Bin\cl.exe' failed with exit status 2

Any advice to make it work ?
Thx for your help

Incomplete implementation of JCKES SecretEntry

In jks.py, there is a TODO for handling SecretKey entries, which are a type in JCKES but not JKS. That is exactly the functionality I need, so I was looking through the JceKeyStore implementation on grepcode but saw that the sealed object part of a secret entry is a serialized object that Java loads by using an ObjectInputStream. For the PrivateKey and Cert entries, it looks like the number of bytes for each part of the entry is specified in some way either by the type or by a length property.

I'd be happy to write the code if anyone might be able to tell me if it's possible to read the serialized object (of unknown size I think) byte by byte, and then unserialize it. I'm very much a novice with regards to JKS and JCKES, so I'm sorry if this is a nonissue.

load error

raise BadKeystoreFormatException('Not a JKS or JCEKS keystore'
jks.util.BadKeystoreFormatException: Not a JKS or JCEKS keystore (magic number wrong; expected FEEDFEED or CECECECE);
when i use keytool๏ผŒprint this:

Keystore type: PKCS12
Keystore provider: SUN

Your keystore contains 1 entry

Alias name: abc
Creation date: 2021ๅนด2ๆœˆ28ๆ—ฅ
Entry type: PrivateKeyEntry
Certificate chain length: 1
Certificate[1]:
Owner: ......
Issuer: ......
Serial number: ......
Valid from: Sun Feb 28 18:14:51 CST 2021 until: Mon Feb 16 18:14:51 CST 2071
Certificate fingerprints:
SHA1: ......
SHA256: ......
Signature algorithm name: SHA256withRSA
Subject Public Key Algorithm: 2048-bit RSA key
Version: 3

Extensions:

#1: ObjectId: 2.5.29.14 Criticality=false
SubjectKeyIdentifier [
KeyIdentifier [...]
how can i use pyjks lib for type PKCS12,thanks

JCEKS Format does not work while FIPS is enabled

I am running python version 2.7.5 on RHEL 7 with FIPS enabled. When trying to open a JCEKS format keystore, I run into this error:

ks = jks.KeyStore.load('keystore.jceks','password')
Traceback (most recent call last):
File "", line 1, in
File "build/bdist.linux-x86_64/egg/jks/util.py", line 92, in load
File "build/bdist.linux-x86_64/egg/jks/jks.py", line 525, in loads
File "build/bdist.linux-x86_64/egg/jks/jks.py", line 212, in decrypt
File "build/bdist.linux-x86_64/egg/jks/sun_crypto.py", line 66, in jce_pbe_decrypt
File "build/bdist.linux-x86_64/egg/jks/sun_crypto.py", line 95, in _jce_pbe_derive_key_and_iv
ValueError: error:060800A3:digital envelope routines:EVP_DigestInit_ex:disabled for fips

Through some quick googling, it looks like FIPS disables the use of MD5, which may be causing this error.

Pip error installing with Python 3.8 dependency twofish

There seem to be errors installing pyjks in a venv with Python 3.8
The subpackage twhofish always fails. Is pyjks still depend on twofish to install in newer versions ?

Collecting twofish Using cached twofish-0.3.0.tar.gz (26 kB) Preparing metadata (setup.py) ... done Building wheels for collected packages: twofish Building wheel for twofish (setup.py) ... error error: subprocess-exited-with-error

NotImplementedError: Saving of JCEKS keystores is not implemented

Hello,
At the moment, when saving a keystore of type "JCEKS"m I get the following error :

NotImplementedError: Saving of JCEKS keystores is not implemented 

Is the implementation on the way / planned ?
For sure.... this is not to set pressure on it ^^ but as I find this library promising, I just wanted to be informed about it ;)
Thx for your answers !

Issue while building python code in lambda

I have built JKS package and trying to execute the code in Lambda by uploading as a zip. While trying to test the code I am getting following error ๐Ÿ‘Ž

START RequestId: d210481c-b1d6-11e8-96b2-dbaf32b85648 Version: $LATEST
module initialization error: Cannot load native module 'Crypto.Hash._MD5': Trying '_MD5.cpython-36m-x86_64-linux-gnu.so': /var/task/Crypto/Util/../Hash/_MD5.cpython-36m-x86_64-linux-gnu.so: cannot open shared object file: No such file or directory, Trying '_MD5.abi3.so': /var/task/Crypto/Util/../Hash/_MD5.abi3.so: cannot open shared object file: No such file or directory, Trying '_MD5.so': /var/task/Crypto/Util/../Hash/_MD5.so: cannot open shared object file: No such file or directory

END RequestId: d210481c-b1d6-11e8-96b2-dbaf32b85648
REPORT RequestId: d210481c-b1d6-11e8-96b2-dbaf32b85648 Duration: 516.12 ms Billed Duration: 600 ms Memory Size: 128 MB Max Memory Used: 29 MB
module initialization error
Cannot load native module 'Crypto.Hash._MD5': Trying '_MD5.cpython-36m-x86_64-linux-gnu.so': /var/task/Crypto/Util/../Hash/_MD5.cpython-36m-x86_64-linux-gnu.so: cannot open shared object file: No such file or directory, Trying '_MD5.abi3.so': /var/task/Crypto/Util/../Hash/_MD5.abi3.so: cannot open shared object file: No such file or directory, Trying '_MD5.so': /var/task/Crypto/Util/../Hash/_MD5.so: cannot open shared object file: No such file or directory

It says Cannot load native module.

Add chain cert to jks doesn't work

I have a chain certs in .pem file. When I add the file to jks using jks.TrustedCertEntry.new it add only the first certificate ignoring all other.

Keystore with multiple private keys

Hi,

Thanks for this project, I have been looking for something like this for some time!

I have a keystore that contains more than one private key. From what I can see, only one of the private keys is being retrieved. Is there a way to get all of them loaded?

Thanks

RLS

pip install fails for pyjks 0.2

On Ubuntu 14.04 with pip 1.5.6 on Python 2.7 when I try to install via pip install pyjks I get the following:

Downloading/unpacking pyjks
  Downloading pyjks-0.2.zip
  Running setup.py (path:/tmp/pip_build_root/pyjks/setup.py) egg_info for package pyjks
    Traceback (most recent call last):
      File "<string>", line 17, in <module>
      File "/tmp/pip_build_root/pyjks/setup.py", line 11, in <module>
        long_description=open('README.md').read(),
    IOError: [Errno 2] No such file or directory: 'README.md'
    Complete output from command python setup.py egg_info:
    Traceback (most recent call last):

  File "<string>", line 17, in <module>

  File "/tmp/pip_build_root/pyjks/setup.py", line 11, in <module>

    long_description=open('README.md').read(),

IOError: [Errno 2] No such file or directory: 'README.md'

Hash mismatch; incorrect password or data corrupted

When I try to load a keystore I get the following exception:

Traceback (most recent call last):
  File "./keystore.py", line 5, in <module>
    ks = jks.KeyStore.load('test.keystore', 'lala')
  File "/usr/local/lib/python2.7/dist-packages/jks/jks.py", line 22, in load
    return cls.loads(file.read(), password)
  File "/usr/local/lib/python2.7/dist-packages/jks/jks.py", line 98, in loads
    raise ValueError("Hash mismatch; incorrect password or data corrupted")
ValueError: Hash mismatch; incorrect password or data corrupted

I know however for a fact the password is correct and the archive is not corrupted, as I can open it in Portecle, Keystore Explorer and pure JAVA.

python --version
Python 2.7.6

I would try and replicate it in Python3, but that yields yet another exception:

Traceback (most recent call last):
  File "./keystore.py", line 5, in <module>
    ks = jks.KeyStore.load('test.keystore', 'lala')
  File "/usr/local/lib/python3.4/dist-packages/jks/jks.py", line 22, in load
    return cls.loads(file.read(), password)
  File "/usr/local/lib/python3.4/dist-packages/jks/jks.py", line 47, in loads
    alias, pos = _read_utf(data, pos)
  File "/usr/local/lib/python3.4/dist-packages/jks/jks.py", line 119, in _read_utf
    return unicode(data[pos:pos+size], 'utf-8'), pos+size
NameError: name 'unicode' is not defined
python3 --version
Python 3.4.0

For both Python versions the pyasn1 package is installed. pyjks version is the master/latest.

If it helps I can provide the JAVA code used to create the keystore.

Issues deploying pyjks due to unpinned pycryptodome depenency

Pyjks has an unpinned dependency on pycryptodome that caused our build system to try to use version 3.10.1 and failing (Docker, CentOS 7-ish). We pinned pycryptodome manually in our requirements to 3.9.9 and that made it pass successfully. The failure was only observed in the docker environment and did not result from a failed download or anything I can pin down right now.

can not handle PKCS12 types of keystores

I was trying to open a keystore that was in the PKCS12 format. This did not work, the error message was:
jks.util.BadKeystoreFormatException: Not a JKS or JCEKS keystore (magic number wrong; expected FEEDFEED or CECECECE)

P.S.
The problem started after I followed an advice that the keytool command gave:
Warning:
Nyckellagret JKS anvรคnder ett proprietรคrt format. Du bรถr migrera till PKCS12, som รคr ett branschstandardformat, med "keytool -importkeystore -srckeystore xxx.jks -destkeystore xxx.jks -deststoretype pkcs12".

It told me to convert the keystore to use the PKCS12 format.
D.S.

Does not work on Python 2.7 with javaobj-py3==0.3.0

I'm not sure why this issue is happening but you can replicate it by running the tests on Python 2 with javaobj-py3==0.3.0.

You get the following exception: UnexpectedAlgorithmException: Unexpected algorithm used for encrypting SealedObject: sealAlg=PBEWithMD5AndTripleDES.

Using javaobj-py3==0.2.4 works correctly. This is hard to see because the requirements file in this repo pins that dependancy to 0.2.1, whereas the setup.py file makes no specification.

Unable to install python package with pip, getting Microsoft Visual C++ 14.0 is required

I am trying to install pyjks in Windows 10. Am running everything in admin command prompt.
Initial try to install pyjks resulted in this:

C:\WINDOWS\system32>pip install pyjks
Collecting pyjks
Collecting pycryptodome (from pyjks)
  Using cached https://files.pythonhosted.org/packages/82/bd/bd192c1314bde108a91295fbec02bc20a816330feb10273aa36d885004ab/pycryptodome-3.6.1-cp36-cp36m-win_amd64.whl
Collecting pyasn1-modules (from pyjks)
  Using cached https://files.pythonhosted.org/packages/e9/51/bcd96bf6231d4b2cc5e023c511bee86637ba375c44a6f9d1b4b7ad1ce4b9/pyasn1_modules-0.2.1-py2.py3-none-any.whl
Collecting pyasn1 (from pyjks)
  Using cached https://files.pythonhosted.org/packages/a0/70/2c27740f08e477499ce19eefe05dbcae6f19fdc49e9e82ce4768be0643b9/pyasn1-0.4.3-py2.py3-none-any.whl
Collecting twofish (from pyjks)
  Using cached https://files.pythonhosted.org/packages/82/b4/9eb026a8e62a04512435d3de25c93f7bda51c8b8c7991c1c0be70b5115a6/twofish-0.3.0.tar.gz
Collecting javaobj-py3 (from pyjks)
  Using cached https://files.pythonhosted.org/packages/6a/7d/1979d67bb8f6c5babb8dda0cb79d6d4663ef9a039c193b5adcc787a86285/javaobj_py3-0.2.4-py2.py3-none-any.whl
Installing collected packages: pycryptodome, pyasn1, pyasn1-modules, twofish, javaobj-py3, pyjks
  Running setup.py install for twofish ... error
    Complete output from command "c:\program files\python36\python.exe" -u -c "import setuptools, tokenize;__file__='C:\\Users\\crrma\\AppData\\Local\\Temp\\pip-install-xlk00hde\\twofish\\setup.py';f=getattr(tokenize, 'open', open)(__file__);code=f.read().replace('\r\n', '\n');f.close();exec(compile(code, __file__, 'exec'))" install --record C:\Users\crrma\AppData\Local\Temp\pip-record-5jn53157\install-record.txt --single-version-externally-managed --compile:
    running install
    running build
    running build_py
    creating build
    creating build\lib.win-amd64-3.6
    copying twofish.py -> build\lib.win-amd64-3.6
    running build_ext
    building '_twofish' extension
    error: Microsoft Visual C++ 14.0 is required. Get it with "Microsoft Visual C++ Build Tools": http://landinghub.visualstudio.com/visual-cpp-build-tools

    ----------------------------------------
Command ""c:\program files\python36\python.exe" -u -c "import setuptools, tokenize;__file__='C:\\Users\\crrma\\AppData\\Local\\Temp\\pip-install-xlk00hde\\twofish\\setup.py';f=getattr(tokenize, 'open', open)(__file__);code=f.read().replace('\r\n', '\n');f.close();exec(compile(code, __file__, 'exec'))" install --record C:\Users\crrma\AppData\Local\Temp\pip-record-5jn53157\install-record.txt --single-version-externally-managed --compile" failed with error code 1 in C:\Users\crrma\AppData\Local\Temp\pip-install-xlk00hde\twofish\

I installed Visual C++ 14.0 from here and tried reinstalling. But got same error. (Someone on stackoverflow said that this is not C++ compiler but are runtime components. Do I have to install full Visual Studio with C++ compiler just for installing pyjks package?)

So as suggested in several comments on this page, I upgraded setuptools:

C:\WINDOWS\system32>pip install --upgrade setuptools
Collecting setuptools
  Using cached https://files.pythonhosted.org/packages/7f/e1/820d941153923aac1d49d7fc37e17b6e73bfbd2904959fffbad77900cf92/setuptools-39.2.0-py2.py3-none-any.whl
Installing collected packages: setuptools
  Found existing installation: setuptools 39.0.1
    Uninstalling setuptools-39.0.1:
      Successfully uninstalled setuptools-39.0.1
Successfully installed setuptools-39.2.0

But still getting the same error. So as suggested on same page, I downloaded tar.gz from here and installed from it:

C:\Users\crrma\Downloads>pip install pyjks-17.1.1.tar.gz
Processing c:\users\crrma\downloads\pyjks-17.1.1.tar.gz
Requirement already satisfied: pyasn1 in c:\program files\python36\lib\site-packages (from pyjks==17.1.1) (0.4.3)
Requirement already satisfied: pyasn1_modules in c:\program files\python36\lib\site-packages (from pyjks==17.1.1) (0.2.1)
Collecting javaobj-py3 (from pyjks==17.1.1)
  Using cached https://files.pythonhosted.org/packages/6a/7d/1979d67bb8f6c5babb8dda0cb79d6d4663ef9a039c193b5adcc787a86285/javaobj_py3-0.2.4-py2.py3-none-any.whl
Requirement already satisfied: pycryptodome in c:\program files\python36\lib\site-packages (from pyjks==17.1.1) (3.6.1)
Collecting twofish (from pyjks==17.1.1)
  Using cached https://files.pythonhosted.org/packages/82/b4/9eb026a8e62a04512435d3de25c93f7bda51c8b8c7991c1c0be70b5115a6/twofish-0.3.0.tar.gz
Installing collected packages: javaobj-py3, twofish, pyjks
  Running setup.py install for twofish ... error
    Complete output from command "c:\program files\python36\python.exe" -u -c "import setuptools, tokenize;__file__='C:\\Users\\crrma\\AppData\\Local\\Temp\\pip-install-c3n_0udc\\twofish\\setup.py';f=getattr(tokenize, 'open', open)(__file__);code=f.read().replace('\r\n', '\n');f.close();exec(compile(code, __file__, 'exec'))" install --record C:\Users\crrma\AppData\Local\Temp\pip-record-tpgigq69\install-record.txt --single-version-externally-managed --compile:
    running install
    running build
    running build_py
    creating build
    creating build\lib.win-amd64-3.6
    copying twofish.py -> build\lib.win-amd64-3.6
    running build_ext
    building '_twofish' extension
    error: Microsoft Visual C++ 14.0 is required. Get it with "Microsoft Visual C++ Build Tools": http://landinghub.visualstudio.com/visual-cpp-build-tools

    ----------------------------------------
Command ""c:\program files\python36\python.exe" -u -c "import setuptools, tokenize;__file__='C:\\Users\\crrma\\AppData\\Local\\Temp\\pip-install-c3n_0udc\\twofish\\setup.py';f=getattr(tokenize, 'open', open)(__file__);code=f.read().replace('\r\n', '\n');f.close();exec(compile(code, __file__, 'exec'))" install --record C:\Users\crrma\AppData\Local\Temp\pip-record-tpgigq69\install-record.txt --single-version-externally-managed --compile" failed with error code 1 in C:\Users\crrma\AppData\Local\Temp\pip-install-c3n_0udc\twofish\

But its simply not getting installed. Whats going wrong here?

I am running latest version of python:

C:\>python
Python 3.6.6rc1 (v3.6.6rc1:1015e38be4, Jun 12 2018, 08:38:06) [MSC v.1900 64 bit (AMD64)] on win32

better utf-16 encoding

Use the proper encode('utf-16be') call instead of the cheesy null-padding it is doing now.

Missing BksKeyStore.saves() method

Hello and thanks for a great library!
I am using pyjks v20.0.0 from pip under WSL Ubuntu.

I am editing a BKS v1 keystore (it only contains certificates if that matters). I want to add a certificate from a file to the keystore.
I can successfully open keystore with ks = jks.BksKeyStore.load(ks_path, password), read certs, generate new cert using jks.bks.BksTrustedCertEntry.new(new_alias, cert_bytes).

However, when I call ks.save(file, password) to save resulting keystore, the followind exception occurs:

Traceback (most recent call last):
  File "./list_cacerts.py", line 44, in <module>
    ks.save(res_path, password)
  File "/home/user/.local/lib/python3.8/site-packages/jks/util.py", line 101, in save
    keystore_bytes = self.saves(store_password)
AttributeError: 'BksKeyStore' object has no attribute 'saves'

Examining the source code, I indeed cannot find any save-related code for BKS and UBER storages.

Are there any plans to support saving BKS keystores?

[FR] Support EC private key

Hello,

Thanks for this great library. Very handy!

Would it be possible to implement to import EC private keys?

Thanks a lot!

Is pyjks supports loading of base64 decoded data for creating instance of KeyStore, How to add an instance of certificate similar to keytool import

Hi,

I need to construct the KeyStore instance using the base64 decoded data pulled from the config map (actually it consists of pre-loaded jks file content in base64 encoded form) . I can see the load method only takes the jks file as input, passing decoded base64 data and creating the KeyStore instance is not possible ?. I want to avoid again creating of the local/temp .jks file just for constructing the Keystore instance.

And, I need to add a new certificate into the created Keystore instance and pull the data from Keystore instance and do the base64 encoding for re-patching into the same configmap.

is this possible with this library ?

tox fails on first run

On a fresh checkout of the source repository, running tox fails on its first run with the error below. I'm not familiar with the stages tox performs (and they seem poorly documented), but the "install" step does not actually seem to install the source into the virtualenv for some reason.

The [testenv].commands entry in tox.ini specifies that py.test should look for test cases in {envsitepackagesdir}/jks (and also in {toxinidir}/tests, why twice?), but because of the dist seemingly not actually getting installed, that directory doesn't exist and tox errors out.

Reproducible on Ubuntu 16.04 and CentOS 7, in both cases with Python 2.7 as the default system python version. The same thing happens for all the other environments in tox.ini as well.

vmuser@vm:~/pyjks$ rm -rf .tox/; tox -v -e py27
using tox.ini: /home/vmuser/pyjks/tox.ini
using tox-2.3.1 from /usr/local/lib/python2.7/dist-packages/tox/__init__.pyc
GLOB sdist-make: /home/vmuser/pyjks/setup.py
  /home/vmuser/pyjks$ /usr/bin/python /home/vmuser/pyjks/setup.py sdist --formats=zip --dist-dir /home/vmuser/pyjks/.tox/dist >/home/vmuser/pyjks/.tox/log/tox-0.log
py27 create: /home/vmuser/pyjks/.tox/py27
  /home/vmuser/pyjks/.tox$ /usr/bin/python -m virtualenv --python /usr/bin/python2.7 py27 >/home/vmuser/pyjks/.tox/py27/log/py27-0.log
py27 installdeps: -rrequirements-test.txt
  /home/vmuser/pyjks$ /home/vmuser/pyjks/.tox/py27/bin/pip install -rrequirements-test.txt >/home/vmuser/pyjks/.tox/py27/log/py27-1.log
py27 inst: /home/vmuser/pyjks/.tox/dist/pyjks-0.5.1.dev0.zip
  /home/vmuser/pyjks$ /home/vmuser/pyjks/.tox/py27/bin/pip install /home/vmuser/pyjks/.tox/dist/pyjks-0.5.1.dev0.zip >/home/vmuser/pyjks/.tox/py27/log/py27-2.log
  /home/vmuser/pyjks$ /home/vmuser/pyjks/.tox/py27/bin/pip freeze >/home/vmuser/pyjks/.tox/py27/log/py27-3.log
py27 installed: javaobj-py3==0.1.4,pluggy==0.3.1,py==1.4.31,pyasn1==0.1.7,pyasn1-modules==0.0.8,pycrypto==2.6.1,pyjks==0.5.1.dev0,pytest==2.9.2,tox==2.3.1,twofish==0.3.0,virtualenv==15.0.2
py27 runtests: PYTHONHASHSEED='2807748729'
py27 runtests: commands[0] | py.test --doctest-modules /home/vmuser/pyjks/.tox/py27/lib/python2.7/site-packages/jks /home/vmuser/pyjks/tests
  /home/vmuser/pyjks/.tox$ /home/vmuser/pyjks/.tox/py27/bin/py.test --doctest-modules /home/vmuser/pyjks/.tox/py27/lib/python2.7/site-packages/jks /home/vmuser/pyjks/tests 
================================================================== test session starts ===================================================================
platform linux2 -- Python 2.7.12, pytest-2.9.2, py-1.4.31, pluggy-0.3.1
rootdir: /home/vmuser/pyjks, inifile: 

============================================================== no tests ran in 0.00 seconds ==============================================================
ERROR: file not found: /home/vmuser/pyjks/.tox/py27/lib/python2.7/site-packages/jks
ERROR: InvocationError: '/home/vmuser/pyjks/.tox/py27/bin/py.test --doctest-modules /home/vmuser/pyjks/.tox/py27/lib/python2.7/site-packages/jks /home/vmuser/pyjks/tests'
________________________________________________________________________ summary _________________________________________________________________________
ERROR:   py27: commands failed

The following line from the output suggests that tox is installing the source distribution in the virtual env:

/home/vmuser/pyjks$ /home/vmuser/pyjks/.tox/py27/bin/pip install /home/vmuser/pyjks/.tox/dist/pyjks-0.5.1.dev0.zip >/home/vmuser/pyjks/.tox/py27/log/py27-2.log

But it is nowhere to be found:

vmuser@vm:~/pyjks$ (. .tox/py27/bin/activate; pip freeze -l)
javaobj-py3==0.1.4
pluggy==0.3.1
py==1.4.31
pyasn1==0.1.7
pyasn1-modules==0.0.8
pycrypto==2.6.1
pytest==2.9.2
tox==2.3.1
twofish==0.3.0
virtualenv==15.0.2

Exact version numbers:

vmuser@vm:~/pyjks$ python --version
Python 2.7.12
vmuser@vm:~/pyjks$ tox --version
2.3.1 imported from /usr/local/lib/python2.7/dist-packages/tox/__init__.pyc
vmuser@vm:~/pyjks$ virtualenv --version
15.0.3

Contents of /home/vmuser/pyjks/.tox/py27/log/py27-2.log:

vmuser@vm:~/pyjks$ cat /home/vmuser/pyjks/.tox/py27/log/py27-2.log
actionid: py27
msg: installpkg
cmdargs: [local('/home/vmuser/pyjks/.tox/py27/bin/pip'), 'install', '/home/vmuser/pyjks/.tox/dist/pyjks-0.5.1.dev0.zip']
env: {'LC_NUMERIC': 'en_US.UTF-8', 'QT_QPA_PLATFORMTHEME': 'appmenu-qt5', 'XDG_GREETER_DATA_DIR': '/var/lib/lightdm-data/vmuser', 'GNOME_DESKTOP_SESSION_ID': 'this-is-deprecated', 'LC_MEASUREMENT': 'en_US.UTF-8', 'UPSTART_EVENTS': 'xsession started', 'XDG_CURRENT_DESKTOP': 'Unity', 'LC_PAPER': 'en_US.UTF-8', 'TMOUT': '0', 'QT_IM_MODULE': 'ibus', 'LOGNAME': 'vmuser', 'USER': 'vmuser', 'PATH': '/home/vmuser/pyjks/.tox/py27/bin:/home/vmuser/local/bin:/home/vmuser/local/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games:/snap/bin', 'XDG_VTNR': '7', 'GNOME_KEYRING_CONTROL': '', 'DISPLAY': ':0', 'LANG': 'en_US.UTF-8', 'TERM': 'xterm-256color', 'SHELL': '/bin/bash', 'XDG_SESSION_PATH': '/org/freedesktop/DisplayManager/Session0', 'XAUTHORITY': '/home/vmuser/.Xauthority', 'LANGUAGE': 'en_US', 'INSTANCE': '', 'LC_MONETARY': 'en_US.UTF-8', 'QT_LINUX_ACCESSIBILITY_ALWAYS_ON': '1', 'MANDATORY_PATH': '/usr/share/gconf/ubuntu.mandatory.path', 'QT_ACCESSIBILITY': '1', 'VIRTUAL_ENV': '/home/vmuser/pyjks/.tox/py27', 'UPSTART_INSTANCE': '', 'COMPIZ_CONFIG_PROFILE': 'ubuntu', 'WINDOWID': '56959269', 'MANPATH': '/home/vmuser/local/share/man:/home/vmuser/local/share/man:', 'CLUTTER_IM_MODULE': 'xim', 'XMODIFIERS': '@im=ibus', 'PYTHONHASHSEED': '3183146666', 'GPG_AGENT_INFO': '/home/vmuser/.gnupg/S.gpg-agent:0:1', 'HOME': '/home/vmuser', 'QT4_IM_MODULE': 'xim', 'GTK2_MODULES': 'overlay-scrollbar', 'XDG_SESSION_DESKTOP': 'ubuntu', 'COMPIZ_BIN_PATH': '/usr/bin/', 'XDG_RUNTIME_DIR': '/run/user/1000', 'LC_IDENTIFICATION': 'en_US.UTF-8', 'LC_ADDRESS': 'en_US.UTF-8', 'PYTHONPATH': '/home/vmuser/local/lib64/python2.6/site-packages:/home/vmuser/local/lib64/python2.6/site-packages:', 'SESSIONTYPE': 'gnome-session', 'SESSION': 'ubuntu', 'VTE_VERSION': '4205', 'SSH_AUTH_SOCK': '/run/user/1000/keyring/ssh', 'GDMSESSION': 'ubuntu', 'IM_CONFIG_PHASE': '1', 'UPSTART_JOB': 'unity7', 'TMUX': '/tmp/tmux-1000/default,5533,3', 'XDG_DATA_DIRS': '/usr/share/ubuntu:/usr/share/gnome:/usr/local/share/:/usr/share/:/var/lib/snapd/desktop', 'XDG_SEAT_PATH': '/org/freedesktop/DisplayManager/Seat0', 'XDG_SESSION_ID': 'c1', 'DBUS_SESSION_BUS_ADDRESS': 'unix:abstract=/tmp/dbus-QLVgZX6JqO', '_': '/usr/local/bin/tox', 'DEFAULTS_PATH': '/usr/share/gconf/ubuntu.default.path', 'GTK_IM_MODULE': 'ibus', 'DESKTOP_SESSION': 'ubuntu', 'UPSTART_SESSION': 'unix:abstract=/com/ubuntu/upstart-session/1000/4389', 'XDG_CONFIG_DIRS': '/etc/xdg/xdg-ubuntu:/usr/share/upstart/xdg:/etc/xdg', 'GNOME_KEYRING_PID': '', 'XDG_SESSION_TYPE': 'x11', 'TERMINFO': '/home/vmuser/.terminfo', 'GDM_LANG': 'en_US', 'LC_TELEPHONE': 'en_US.UTF-8', 'GTK_MODULES': 'gail:atk-bridge:unity-gtk-module', 'PAPERSIZE': 'letter', 'SHLVL': '3', 'PWD': '/home/vmuser/pyjks', 'JOB': 'unity-settings-daemon', 'SWT_GTK3': '0', 'LC_NAME': 'en_US.UTF-8', 'LC_TIME': 'en_US.UTF-8', 'LS_COLORS': 'rs=0:di=01;34:ln=01;36:mh=00:pi=40;33:so=01;35:do=01;35:bd=40;33;01:cd=40;33;01:or=40;31;01:mi=00:su=37;41:sg=30;43:ca=30;41:tw=30;42:ow=34;42:st=37;44:ex=01;32:*.tar=01;31:*.tgz=01;31:*.arc=01;31:*.arj=01;31:*.taz=01;31:*.lha=01;31:*.lz4=01;31:*.lzh=01;31:*.lzma=01;31:*.tlz=01;31:*.txz=01;31:*.tzo=01;31:*.t7z=01;31:*.zip=01;31:*.z=01;31:*.Z=01;31:*.dz=01;31:*.gz=01;31:*.lrz=01;31:*.lz=01;31:*.lzo=01;31:*.xz=01;31:*.bz2=01;31:*.bz=01;31:*.tbz=01;31:*.tbz2=01;31:*.tz=01;31:*.deb=01;31:*.rpm=01;31:*.jar=01;31:*.war=01;31:*.ear=01;31:*.sar=01;31:*.rar=01;31:*.alz=01;31:*.ace=01;31:*.zoo=01;31:*.cpio=01;31:*.7z=01;31:*.rz=01;31:*.cab=01;31:*.jpg=01;35:*.jpeg=01;35:*.gif=01;35:*.bmp=01;35:*.pbm=01;35:*.pgm=01;35:*.ppm=01;35:*.tga=01;35:*.xbm=01;35:*.xpm=01;35:*.tif=01;35:*.tiff=01;35:*.png=01;35:*.svg=01;35:*.svgz=01;35:*.mng=01;35:*.pcx=01;35:*.mov=01;35:*.mpg=01;35:*.mpeg=01;35:*.m2v=01;35:*.mkv=01;35:*.webm=01;35:*.ogm=01;35:*.mp4=01;35:*.m4v=01;35:*.mp4v=01;35:*.vob=01;35:*.qt=01;35:*.nuv=01;35:*.wmv=01;35:*.asf=01;35:*.rm=01;35:*.rmvb=01;35:*.flc=01;35:*.avi=01;35:*.fli=01;35:*.flv=01;35:*.gl=01;35:*.dl=01;35:*.xcf=01;35:*.xwd=01;35:*.yuv=01;35:*.cgm=01;35:*.emf=01;35:*.ogv=01;35:*.ogx=01;35:*.aac=00;36:*.au=00;36:*.flac=00;36:*.m4a=00;36:*.mid=00;36:*.midi=00;36:*.mka=00;36:*.mp3=00;36:*.mpc=00;36:*.ogg=00;36:*.ra=00;36:*.wav=00;36:*.oga=00;36:*.opus=00;36:*.spx=00;36:*.xspf=00;36:', 'TMUX_PANE': '%54', 'XDG_SEAT': 'seat0'}

Processing ./.tox/dist/pyjks-0.5.1.dev0.zip
  Requirement already satisfied (use --upgrade to upgrade): pyjks==0.5.1.dev0 from file:///home/vmuser/pyjks/.tox/dist/pyjks-0.5.1.dev0.zip in /home/vmuser/pyjks
Requirement already satisfied (use --upgrade to upgrade): pyasn1 in ./.tox/py27/lib/python2.7/site-packages (from pyjks==0.5.1.dev0)
Requirement already satisfied (use --upgrade to upgrade): pyasn1_modules in ./.tox/py27/lib/python2.7/site-packages (from pyjks==0.5.1.dev0)
Requirement already satisfied (use --upgrade to upgrade): javaobj-py3 in ./.tox/py27/lib/python2.7/site-packages (from pyjks==0.5.1.dev0)
Requirement already satisfied (use --upgrade to upgrade): pycrypto in ./.tox/py27/lib/python2.7/site-packages (from pyjks==0.5.1.dev0)
Requirement already satisfied (use --upgrade to upgrade): twofish in ./.tox/py27/lib/python2.7/site-packages (from pyjks==0.5.1.dev0)
Building wheels for collected packages: pyjks
  Running setup.py bdist_wheel for pyjks: started
  Running setup.py bdist_wheel for pyjks: finished with status 'done'
  Stored in directory: /home/vmuser/.cache/pip/wheels/23/00/59/df3c23a752fa609874cf336943df85d00b2175fd94ee002d45
Successfully built pyjks

Unencrypted private keys in JKS files cannot be decrypted with the JKS passphrase

Our application creates JKS files using PyJKS version 17.1.0 using the following method:

def jks_key(alias: str, chain: list, key_der: bytes, passphrase: str) -> bytes:
    """ generate a java keystore with an alias for the given key """

    pke = jks.PrivateKeyEntry.new(alias, chain, key_der, 'rsa_raw')
    keystore = jks.KeyStore.new('jks', [pke])
    return keystore.saves(passphrase)

Up until recently the JKS files have worked well, and our Java application could read and decrypt the private key using the provided passphrase.

Since the pyasn1 module was updated to version 0.3.2 and pyasn1-modules to version 0.0.11, the JKS files created by the application no longer work. The passphrase can decrypt the JKS itself, but cannot decrypt the private key within it anymore.

http://pyjks.readthedocs.io/en/latest/jks.html#jks.jks.KeyStore.saves states: "If any of the private keys are unencrypted, they will be encrypted with the same password as the keystore." This statement does not seem to hold true anymore.

Support for Keystore manipulation

Does pyjks currently support importing keys or certificates into a JKS keystore or creation of a new keystore? If no, are there plans to implement something like this?

Best regards

creating jks file using pyjks

Hi
I have a certificate, certificate chain & private_key as PEM encoded text files.
Using this , Can i generate a .jks file using pyjks library ?

Please advise

TrustedCertEntry not being added to JKS together with PrivateKeyEntry

I'm generating a JKS from here:

def write_to_appendable_file(filename, data):
    filename.seek(0)
    filename.truncate()
    filename.write(data)

def save_to_jks(data):
    tce = jks.TrustedCertEntry.new('IssuingCA', data['issuing_ca'].encode())
    pke = jks.PrivateKeyEntry.new(args.domain, [data['certificate'].encode()], data['private_key'].encode(), 'rsa_raw')
    keystore = jks.KeyStore.new('jks', [pke, tce])
    keystore_bytes = keystore.saves(args.password)
    write_to_appendable_file(args.jks, keystore_bytes)

Running: keytool -list -v -keystore keystore.jks gives:

Keystore type: JKS
Keystore provider: SUN

Your keystore contains 2 entries

Alias name: test.mydomain.com
Creation date: Mar 7, 2018
Entry type: PrivateKeyEntry
Certificate chain length: 1
...
*******************************************
*******************************************


keytool error: java.lang.Exception: Alias <IssuingCA> does not exist
java.lang.Exception: Alias <IssuingCA> does not exist
	at sun.security.tools.keytool.Main.doPrintEntry(Main.java:1866)
	at sun.security.tools.keytool.Main.doPrintEntries(Main.java:2236)
	at sun.security.tools.keytool.Main.doCommands(Main.java:1123)
	at sun.security.tools.keytool.Main.run(Main.java:366)
	at sun.security.tools.keytool.Main.main(Main.java:359)

How do I get the proper pem format from .jks file to sign the jwt token?

Hi, I am trying to use the .jks file to sign the jwt token. The libraries I am using are pyjwt and pyjks. Below is the code snippets:

        userDto = user
        payload = {
            "iss": "test",
            "exp": datetime.now(tz=timezone.utc) + timedelta(days=365),
            "iat": datetime.now(tz=timezone.utc),
            "nbf": datetime.now(tz=timezone.utc),
            "sub": "testUser",
            "auth": userDto
        }
        keystorePath = os.path.abspath("KeyStore.jks")
        keystorePass = "test"
        keyAlias = "test"
        keystore = jks.KeyStore.load(keystorePath, keystorePass)
        pk = keystore.private_keys[keyAlias]

        encoded = jwt.encode(payload, pk, algorithm="RS512")

While executing the last line of code to generate the jwt using jks signature, it throws error saying expecting a PEM-formatted key. I am thinking the pk format is not what the jwk requires. My question is how I could extract pem file formatted file from .jks to sign the jwk token? Thanks.

Jceks File Not Supporting in Python 2.7.5

I am getting below error though we have jks version 19.0.0 and javaobj = 0.4.0.Does any one face this problem while calling jks.KeyStore.load(), though I am giving correct store password
cc: @danpker @cory-parr

Python 2.7.5
Type "help", "copyright", "credits" or "license" for more information.

import jks
jks.KeyStore.load('file_name.jceks',"pass_phrase")
Traceback (most recent call last):
File "", line 1, in
File "/usr/lib/python2.7/site-packages/jks/util.py", line 92, in load
try_decrypt_keys=try_decrypt_keys)
File "/usr/lib/python2.7/site-packages/jks/jks.py", line 525, in loads
entry.decrypt(store_password)
File "/usr/lib/python2.7/site-packages/jks/jks.py", line 320, in decrypt
raise UnexpectedAlgorithmException("Unexpected algorithm used for encrypting SealedObject: sealAlg=%s" % sealed_obj.sealAlg)
jks.util.UnexpectedAlgorithmException: Unexpected algorithm used for encrypting SealedObject: sealAlg=PBEWithMD5AndTripleDES

Pyjks doesn't convert alias to lowercase

This is what Java Keytool does when importing items, although it's not documented everywhere. Keytool throws an error and Keystore Explorer fails silently when opening a keystore that has an alias where atleast one character is uppercase.

Unable to reach HTTPS endpoint - Keystore generated using pyJKS

I am developing a spring boot app and created a keystore file using pyJKS

I used a certificate, certificate_chain & private key

The keystore.jks file is generated successfully. But when i deploy that in a spring sboot app and try to access the endpoint using curl, i get below error

curl -v -k https://localhost:8181/

  • timeout on name lookup is not supported
  • Trying 127.0.0.1...
    % Total % Received % Xferd Average Speed Time Time Time Current
    Dload Upload Total Spent Left Speed
    0 0 0 0 0 0 0 0 --:--:-- --:--:-- --:--:-- 0* Connected to localhost (127.0.0.1) port 8181 (#0)
  • ALPN, offering h2
  • ALPN, offering http/1.1
  • Cipher selection: ALL:!EXPORT:!EXPORT40:!EXPORT56:!aNULL:!LOW:!RC4:@strength
  • successfully set certificate verify locations:
  • CAfile: C:/Developer/..../ca-bundle.crt
    CApath: none
  • TLSv1.2 (OUT), TLS header, Certificate Status (22):
    } [5 bytes data]
  • TLSv1.2 (OUT), TLS handshake, Client hello (1):
    } [512 bytes data]
    0 0 0 0 0 0 0 0 --:--:-- --:--:-- --:--:-- 0* TLSv1.2 (IN), TLS header, Unknown (21):
    { [5 bytes data]
  • TLSv1.2 (IN), TLS alert, Server hello (2):
    { [2 bytes data]
  • error:14077438:SSL routines:SSL23_GET_SERVER_HELLO:tlsv1 alert internal error
    0 0 0 0 0 0 0 0 --:--:-- --:--:-- --:--:-- 0
  • Closing connection 0
    curl: (35) error:14077438:SSL routines:SSL23_GET_SERVER_HELLO:tlsv1 alert internal error

Below is the code that i use to generate keystore.

cert_file = open("Certificate.txt", "rb")
cert = cert_file.read()
cert_file.close()

cert_chain_file = open("Certificate_chain.txt", "rb")
cert_chain = cert_chain_file.read()
cert_chain_file.close()

private_key_file = open("private_key.txt", "rb")
private_key = private_key_file.read()
private_key_file.close()

certs = []
certs.append(cert)
certs.append(cert_chain)

pke = jks.PrivateKeyEntry.new("test", certs,private_key, 'rsa_raw')
keystore = jks.KeyStore.new('jks', [pke])
keystore.save('./keystore.jks', 'test')

When i use keytool command , generated keystore works fine.

Can someone advise what could be wrong here ?

pyjks does not exclude its `tests` directory when packaged

When I install pyjks, installs its tests directory in with my other packages. This causes problems in various cases where the packages directory that includes pyjks comes before my application's directory in sys.path, since my own test code directory is also called tests.

$ tar ztf pyjks-17.1.0.tar.gz
pyjks-17.1.0/
pyjks-17.1.0/tests/
pyjks-17.1.0/tests/expected/
pyjks-17.1.0/tests/expected/DSA2048.py
pyjks-17.1.0/tests/expected/RSA1024.py
pyjks-17.1.0/tests/expected/bks_custom_entry_passwords.py
pyjks-17.1.0/tests/expected/RSA2048_3certs.py
pyjks-17.1.0/tests/expected/__init__.py
pyjks-17.1.0/tests/expected/custom_entry_passwords.py
pyjks-17.1.0/tests/expected/bks_christmas.py
pyjks-17.1.0/tests/expected/jks_non_ascii_password.py
pyjks-17.1.0/tests/test_jks.py
pyjks-17.1.0/tests/__init__.py
pyjks-17.1.0/PKG-INFO
pyjks-17.1.0/setup.py
pyjks-17.1.0/pyjks.egg-info/
pyjks-17.1.0/pyjks.egg-info/PKG-INFO
pyjks-17.1.0/pyjks.egg-info/requires.txt
pyjks-17.1.0/pyjks.egg-info/dependency_links.txt
pyjks-17.1.0/pyjks.egg-info/top_level.txt
pyjks-17.1.0/pyjks.egg-info/SOURCES.txt
pyjks-17.1.0/jks/
pyjks-17.1.0/jks/rfc2898.py
pyjks-17.1.0/jks/bks.py
pyjks-17.1.0/jks/sun_crypto.py
pyjks-17.1.0/jks/util.py
pyjks-17.1.0/jks/__init__.py
pyjks-17.1.0/jks/rfc7292.py
pyjks-17.1.0/jks/jks.py
pyjks-17.1.0/setup.cfg

This is probably happening because setup.py does not use the exclude argument to exclude the tests directory/package/module:

http://setuptools.readthedocs.io/en/latest/setuptools.html#using-find-packages

Proposal: Add embedded type hints

I want to add type hints for the pyjks package. Roughly there are two ways I could achieve this:

  1. Contribute embedded type hints to upstream pyjks project directly (e.g. change def xor_bytearrays(a, b): -> def xor_bytearrays(a: bytearray, b: bytearray) -> bytearray:)
  2. Create a separate types/stubs project such as types-pyjks. Would make most sense to create it under the typeshed umbrella, which already maintains lots of stubs packages.

Generally the Python community prefers approach (1), hence I'm trying to gauge the interest. I've noticed that the pyjks project has been static for several years now. Are there still maintainers here who could review such a PR and release a new version?

Approach (1) would also mean removing support for older Python versions, as type hints were introduced in 3.5 but are more annoying in the initial Python versions. Python 3.7 is EOL since 2 months ago and I think we should support version range 3.8 ... 3.12.

Alternatively, if maintainers aren't interested in this, I will pursue (2).

Add support for listing keystores without passphrase

pyjks doesn't allow to open a keystore without passphrase, this is correct.
But what about getting a simple listing of entries in a keystore without providing passphrase?

keytool allows to get some details of a pass-protected keystore without providing passphrase, e.g.:

Alias name: test
Creation date: Jul 15, 2019
Entry type: PrivateKeyEntry
Certificate chain length: 3
Certificate[1]:
Owner: CN=test, OU=ou, O=org, L=loc, C=us
Issuer: CN=cn, O=org, C=us
Serial number: 100
Valid from: Mon Jul 01 14:39:46 2019 until: Tue Jun 30 14:39:46 2020
Certificate fingerprints:
         SHA1: <<censored>>
         SHA256: <<censored>>
Signature algorithm name: SHA512withRSA
Subject Public Key Algorithm: 2048-bit RSA key
Version: 3

Could you please consider adding support of keystore listing w/o passphrase like keytool does?

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.