Exemplo n.º 1
0
    def encrypt(self, key_password):
        """
        Encrypts the private key, so that it can be saved to a keystore.

        This will make it necessary to decrypt it again if it is going to be used later.
        Has no effect if the entry is already encrypted.

        :param str key_password: The password to encrypt the entry with.
        """
        if not self.is_decrypted():
            return

        encrypted_private_key = sun_crypto.jks_pkey_encrypt(
            self.pkey_pkcs8, key_password)

        a = AlgorithmIdentifier()
        a.setComponentByName('algorithm', sun_crypto.SUN_JKS_ALGO_ID)
        a.setComponentByName('parameters', '\x05\x00')
        epki = rfc5208.EncryptedPrivateKeyInfo()
        epki.setComponentByName('encryptionAlgorithm', a)
        epki.setComponentByName('encryptedData', encrypted_private_key)

        self._encrypted = encoder.encode(epki)
        self._pkey = None
        self._pkey_pkcs8 = None
        self._algorithm_oid = None
Exemplo n.º 2
0
    def decrypt(self, key_password):
        """
        Decrypts the entry using the given password. Has no effect if the entry has already been decrypted.

        :param str key_password: The password to decrypt the entry with. If the entry was loaded from a JCEKS keystore,
                                 the password must not contain any characters outside of the ASCII character set.
        :raises DecryptionFailureException: If the entry could not be decrypted using the given password.
        :raises UnexpectedAlgorithmException: If the entry was encrypted with an unknown or unexpected algorithm
        :raise ValueError: If the entry was loaded from a JCEKS keystore and the password contains non-ASCII characters.
        """
        if self.is_decrypted():
            return

        encrypted_info = decoder.decode(
            self._encrypted, asn1Spec=rfc5208.EncryptedPrivateKeyInfo())[0]
        algo_id = encrypted_info['encryptionAlgorithm']['algorithm'].asTuple()
        algo_params = encrypted_info['encryptionAlgorithm'][
            'parameters'].asOctets()
        encrypted_private_key = encrypted_info['encryptedData'].asOctets()

        plaintext = None
        try:
            if algo_id == sun_crypto.SUN_JKS_ALGO_ID:
                plaintext = sun_crypto.jks_pkey_decrypt(
                    encrypted_private_key, key_password)

            elif algo_id == sun_crypto.SUN_JCE_ALGO_ID:
                if self.store_type != "jceks":
                    raise UnexpectedAlgorithmException(
                        "Encountered JCEKS private key protection algorithm in JKS keystore"
                    )
                # see RFC 2898, section A.3: PBES1 and definitions of AlgorithmIdentifier and PBEParameter
                params = decoder.decode(algo_params,
                                        asn1Spec=rfc2898.PBEParameter())[0]
                salt = params['salt'].asOctets()
                iteration_count = int(params['iterationCount'])
                plaintext = sun_crypto.jce_pbe_decrypt(encrypted_private_key,
                                                       key_password, salt,
                                                       iteration_count)
            else:
                raise UnexpectedAlgorithmException(
                    "Unknown %s private key protection algorithm: %s" %
                    (self.store_type.upper(), algo_id))

        except (BadHashCheckException, BadPaddingException):
            raise DecryptionFailureException(
                "Failed to decrypt data for private key '%s'; wrong password?"
                % self.alias)

        # at this point, 'plaintext' is a PKCS#8 PrivateKeyInfo (see RFC 5208)
        private_key_info = decoder.decode(plaintext,
                                          asn1Spec=rfc5208.PrivateKeyInfo())[0]
        key = private_key_info['privateKey'].asOctets()
        algorithm_oid = private_key_info['privateKeyAlgorithm'][
            'algorithm'].asTuple()

        self._encrypted = None
        self._pkey = key
        self._pkey_pkcs8 = plaintext
        self._algorithm_oid = algorithm_oid
Exemplo n.º 3
0
 def setUp(self):
     self.asn1Spec = rfc5208.EncryptedPrivateKeyInfo()
Exemplo n.º 4
0
cnt = 0

while 1:
    idx, substrate = pem.readPemBlocksFromFile(
        sys.stdin,
        ('-----BEGIN PRIVATE KEY-----', '-----END PRIVATE KEY-----'),
        ('-----BEGIN ENCRYPTED PRIVATE KEY-----',
         '-----END ENCRYPTED PRIVATE KEY-----'))
    if not substrate:
        break

    if idx == 0:
        asn1Spec = rfc5208.PrivateKeyInfo()
    elif idx == 1:
        asn1Spec = rfc5208.EncryptedPrivateKeyInfo()
    else:
        break

    key, rest = decoder.decode(substrate, asn1Spec=asn1Spec)

    if rest: substrate = substrate[:-len(rest)]

    print(key.prettyPrint())

    assert encoder.encode(key) == substrate, 'pkcs8 recode fails'

    cnt = cnt + 1

print('*** %s PKCS#8 key(s) de/serialized' % cnt)