Exemple #1
0
    def extract_ssl_cert_key_pem(self) -> NoReturn:
        '''Extract the SSL certificate and key in PEM encoded format.
		
		It write to a file named <DEVICE_ID>.pem, where DEVICE_ID is
		the device ID extracted from the certificate.
		'''
        out_path = Path(f'./{self.device_id}.pem')
        with open(out_path, 'w') as ssl_pem_stream:
            ssl_pem_stream.write(
                PEM.encode(self.ssl_certificate, 'CERTIFICATE'))
            ssl_pem_stream.write('\n')
            ssl_pem_stream.write(PEM.encode(self.ssl_key, 'RSA PRIVATE KEY'))
Exemple #2
0
def sign_target(fname, ofname, private_key=None, **kwargs):  # pylint: disable=unused-argument
    """
    Sign a given `fname` and write the signature to `ofname`.
    """
    if private_key is None:
        private_key = Options.private_key
    # NOTE: This is intended to crash if there's some number of keys other than
    # exactly 1 read from the private_key file:
    the_keys = list(read_certs(private_key))
    if not the_keys:
        log.error(
            'unable to sign %s with %s (no such file or error reading certs)',
            os.path.abspath(fname), os.path.abspath(private_key))
        return
    first_key = the_keys[0]
    hasher, chosen_hash = hash_target(fname, obj_mode=True)
    args = {'data': hasher.finalize()}

    salt_padding_bits = _format_padding_bits(Options.salt_padding_bits)

    log.error('signing %s using %s', fname, private_key)

    if isinstance(first_key, rsa.RSAPrivateKey):
        log.error('signing %s using SBP:%s', fname,
                  _format_padding_bits_txt(salt_padding_bits))
        args['padding'] = padding.PSS(mgf=padding.MGF1(hashes.SHA256()),
                                      salt_length=salt_padding_bits)
        args['algorithm'] = utils.Prehashed(chosen_hash)
    sig = first_key.sign(**args)
    with open(ofname, 'w') as fh:
        log.error('writing signature of %s to %s', os.path.abspath(fname),
                  os.path.abspath(ofname))
        fh.write(PEM.encode(sig, 'Detached Signature of {}'.format(fname)))
        fh.write('\n')
Exemple #3
0
    def send_funds_from_to(self, sender_public_key_str: str, sender_private_key_str: str,
                           recipient_public_key_str: str, value: float):
        if self.get_balance_for_public_key(sender_public_key_str) < value:
            print("Not enough balance, transaction discarded")
            return None

        if value <= 0:
            print("Value should be positive, transaction discarded")
            return None

        inputs = []
        total = 0
        for transaction_id, utxo in self.all_utxos.items():
            if utxo.is_mine(sender_public_key_str):
                total += utxo.value
                inp = TransactionInput(transaction_id)
                inputs.append(inp)

                if total >= value + self.fee:
                    break

        transaction = Transaction(sender_public_key_str, recipient_public_key_str, value, inputs)
        encoded = base64.b64decode(sender_private_key_str.encode('utf8'))
        sender_private_formated = PEM.encode(encoded, 'RSA PRIVATE KEY')
        transaction.generate_signature(import_key(sender_private_formated.encode('utf8')))
        transaction.process_transaction(self.all_utxos, self.minimum_transaction, self.fee)
        return transaction
Exemple #4
0
    def create_bridge_descriptor(self):
        nickname = self.config.nickname

        if not check_nickname(nickname):
            raise ORError("Bad nickname {}".format(nickname))

        published = time.strftime("%Y-%m-%d %H:%M:%S", time.gmtime())
        bandwidth = "{:d} {:d} {:d}".format(self.config.announced_bandwidth[0],
                                            self.config.announced_bandwidth[1],
                                            0)

        encoded_key = encodePEMRawRSAPubKey(self.identity_pubkey)
        encoded_onion_key = encodePEMRawRSAPubKey(self.onion_privkey)

        desc = DESCRIPTOR_TEMPLATE.format(
            nickname=nickname,
            address=self.config.address,
            port=self.config.listen_address[1],
            platform=PLATFORM,
            published=published,
            fingerprint=self.fingerprint,
            bandwidth=bandwidth,
            onion_key=encoded_onion_key,
            signing_key=encoded_key,
            ntor_onion_key=self.ntor_onion_key.public.encode("base64").strip())
        # Does it make sense for an MITM box to rotate its keys?

        router_signature = LowLevelSignature(self.identity_privkey).sign(
            SHA1.new(desc).digest())
        router_signature = PEM.encode(router_signature, "SIGNATURE")

        return desc + router_signature + "\n"
Exemple #5
0
def sign_target(fname, ofname, key_file='private.key', **kw):
    with open(key_file, 'r') as fh:
        private_key = RSA.importKey(fh.read())
    signer = PKCS1_v1_5.new(private_key)
    sig = signer.sign(hash_target(fname, obj_mode=True))
    with open(ofname, 'w') as fh:
        fh.write(PEM.encode(sig, f'Detached Signature of {fname}'))
        fh.write('\n')
 def _export_private_encrypted_pkcs8_in_clear_pem(self, passphrase,
                                                  **kwargs):
     assert passphrase
     if 'protection' not in kwargs:
         raise ValueError(
             "At least the 'protection' parameter should be present")
     encoded_der = self._export_pkcs8(passphrase=passphrase, **kwargs)
     return PEM.encode(encoded_der, "ENCRYPTED PRIVATE KEY")
    def verify_signature(self):
        if self.sender == '':
            return True
        if not self.signature:
            return False

        message = self.sender + self.recipient + str(self.value)
        encoded = base64.b64decode(self.sender.encode('utf8'))
        sender_public_formated = PEM.encode(encoded, 'RSA PUBLIC KEY')
        sender_public_key = import_key(sender_public_formated)
        return verify(message.encode(), self.signature, sender_public_key)
 def exportKey(self,
               format='PEM',
               passphrase=None,
               pkcs=1,
               protection=None):
     if passphrase is not None:
         passphrase = tobytes(passphrase)
     if format == 'OpenSSH':
         eb = long_to_bytes(self.e)
         nb = long_to_bytes(self.n)
         if bord(eb[0]) & 128:
             eb = bchr(0) + eb
         if bord(nb[0]) & 128:
             nb = bchr(0) + nb
         keyparts = [b('ssh-rsa'), eb, nb]
         keystring = b('').join(
             [struct.pack('>I', len(kp)) + kp for kp in keyparts])
         return b('ssh-rsa ') + binascii.b2a_base64(keystring)[:-1]
     else:
         if self.has_private():
             binary_key = newDerSequence(0, self.n, self.e, self.d, self.p,
                                         self.q, self.d % (self.p - 1),
                                         self.d % (self.q - 1),
                                         inverse(self.q, self.p)).encode()
             if pkcs == 1:
                 keyType = 'RSA PRIVATE'
                 if format == 'DER' and passphrase:
                     raise ValueError(
                         'PKCS#1 private key cannot be encrypted')
             elif format == 'PEM' and protection is None:
                 keyType = 'PRIVATE'
                 binary_key = PKCS8.wrap(binary_key, oid, None)
             else:
                 keyType = 'ENCRYPTED PRIVATE'
                 if not protection:
                     protection = 'PBKDF2WithHMAC-SHA1AndDES-EDE3-CBC'
                 binary_key = PKCS8.wrap(binary_key, oid, passphrase,
                                         protection)
                 passphrase = None
         else:
             keyType = 'RSA PUBLIC'
             binary_key = newDerSequence(
                 algorithmIdentifier,
                 newDerBitString(newDerSequence(self.n, self.e))).encode()
         if format == 'DER':
             return binary_key
         if format == 'PEM':
             pem_str = PEM.encode(binary_key, keyType + ' KEY', passphrase,
                                  self._randfunc)
             return tobytes(pem_str)
         raise ValueError(
             "Unknown key format '%s'. Cannot export the RSA key." % format)
         return
Exemple #9
0
def forge(certificate_path: str, key_pem: str):
    """
    given a valid certificate_path and key_pem create a forged key
    """
    public_key_point = get_public_key(certificate_path)
    Q = Point(int(public_key_point[0:96], 16),
              int(public_key_point[96:], 16),
              curve=P384)

    # Generate rogue generator
    privkey_inv = 2
    # we take the private key as being the inverse of 2 modulo the curve order
    private_key = gmpy2.invert(privkey_inv, P384.q)  # pylint: disable=c-extension-no-member
    private_key = unhexlify(f"{private_key:x}".encode())
    # we multply our public key Q with the inverse of our chosen private key value
    roug_g = privkey_inv * Q
    roug_g = unhexlify(b"04" + f"{roug_g.x:x}".encode() +
                       f"{roug_g.y:x}".encode())

    # Generate the file with explicit parameters
    with open(key_pem, mode="rt") as handle:
        keyfile = PEM.decode(handle.read())

    seq_der = DerSequence()
    der = seq_der.decode(keyfile[0])

    # Replace private key
    octet_der = DerOctetString(private_key)
    der[1] = octet_der.encode()

    # Replace public key
    bits_der = DerBitString(unhexlify(b"04" + public_key_point))
    der[3] = b"\xa1\x64" + bits_der.encode()

    # Replace the generator
    seq_der = DerSequence()
    s = seq_der.decode(der[2][4:])  # pylint: disable=invalid-name
    octet_der = DerOctetString(roug_g)
    s[3] = octet_der.encode()
    der[2] = der[2][:4] + s.encode()

    return PEM.encode(der.encode(), "EC PRIVATE KEY")
    def exportKey(self,
                  format='PEM',
                  passphrase=None,
                  pkcs=1,
                  protection=None,
                  randfunc=None):
        """Export this RSA key.

        :Parameters:
          format : string
            The format to use for wrapping the key:

            - *'DER'*. Binary encoding.
            - *'PEM'*. Textual encoding, done according to `RFC1421`_/`RFC1423`_.
            - *'OpenSSH'*. Textual encoding, done according to OpenSSH specification.
              Only suitable for public keys (not private keys).

          passphrase : string
            For private keys only. The pass phrase used for deriving the encryption
            key.

          pkcs : integer
            For *DER* and *PEM* format only.
            The PKCS standard to follow for assembling the components of the key.
            You have two choices:

            - **1** (default): the public key is embedded into
              an X.509 ``SubjectPublicKeyInfo`` DER SEQUENCE.
              The private key is embedded into a `PKCS#1`_
              ``RSAPrivateKey`` DER SEQUENCE.
            - **8**: the private key is embedded into a `PKCS#8`_
              ``PrivateKeyInfo`` DER SEQUENCE. This value cannot be used
              for public keys.

          protection : string
            The encryption scheme to use for protecting the private key.

            If ``None`` (default), the behavior depends on ``format``:

            - For *DER*, the *PBKDF2WithHMAC-SHA1AndDES-EDE3-CBC*
              scheme is used. The following operations are performed:

                1. A 16 byte Triple DES key is derived from the passphrase
                   using `Crypto.Protocol.KDF.PBKDF2` with 8 bytes salt,
                   and 1 000 iterations of `Crypto.Hash.HMAC`.
                2. The private key is encrypted using CBC.
                3. The encrypted key is encoded according to PKCS#8.

            - For *PEM*, the obsolete PEM encryption scheme is used.
              It is based on MD5 for key derivation, and Triple DES for encryption.

            Specifying a value for ``protection`` is only meaningful for PKCS#8
            (that is, ``pkcs=8``) and only if a pass phrase is present too.

            The supported schemes for PKCS#8 are listed in the
            `Crypto.IO.PKCS8` module (see ``wrap_algo`` parameter).

          randfunc : callable
            A function that provides random bytes. Only used for PEM encoding.
            The default is `Crypto.Random.get_random_bytes`.

        :Return: A byte string with the encoded public or private half
          of the key.
        :Raise ValueError:
            When the format is unknown or when you try to encrypt a private
            key with *DER* format and PKCS#1.
        :attention:
            If you don't provide a pass phrase, the private key will be
            exported in the clear!

        .. _RFC1421:    http://www.ietf.org/rfc/rfc1421.txt
        .. _RFC1423:    http://www.ietf.org/rfc/rfc1423.txt
        .. _`PKCS#1`:   http://www.ietf.org/rfc/rfc3447.txt
        .. _`PKCS#8`:   http://www.ietf.org/rfc/rfc5208.txt
        """

        if passphrase is not None:
            passphrase = tobytes(passphrase)

        if randfunc is None:
            randfunc = Random.get_random_bytes

        if format == 'OpenSSH':
            eb, nb = [self._key[comp].to_bytes() for comp in 'e', 'n']
            if bord(eb[0]) & 0x80: eb = bchr(0x00) + eb
            if bord(nb[0]) & 0x80: nb = bchr(0x00) + nb
            keyparts = [b('ssh-rsa'), eb, nb]
            keystring = b('').join(
                [struct.pack(">I", len(kp)) + kp for kp in keyparts])
            return b('ssh-rsa ') + binascii.b2a_base64(keystring)[:-1]

        # DER format is always used, even in case of PEM, which simply
        # encodes it into BASE64.
        if self.has_private():
            binary_key = newDerSequence(
                0, self.n, self.e, self.d, self.p, self.q,
                self.d % (self.p - 1), self.d % (self.q - 1),
                Integer(self.q).inverse(self.p)).encode()
            if pkcs == 1:
                keyType = 'RSA PRIVATE'
                if format == 'DER' and passphrase:
                    raise ValueError("PKCS#1 private key cannot be encrypted")
            else:  # PKCS#8
                if format == 'PEM' and protection is None:
                    keyType = 'PRIVATE'
                    binary_key = PKCS8.wrap(binary_key, oid, None)
                else:
                    keyType = 'ENCRYPTED PRIVATE'
                    if not protection:
                        protection = 'PBKDF2WithHMAC-SHA1AndDES-EDE3-CBC'
                    binary_key = PKCS8.wrap(binary_key, oid, passphrase,
                                            protection)
                    passphrase = None
        else:
            keyType = "RSA PUBLIC"
            binary_key = newDerSequence(
                algorithmIdentifier,
                newDerBitString(newDerSequence(self.n, self.e))).encode()
        if format == 'DER':
            return binary_key
        if format == 'PEM':
            pem_str = PEM.encode(binary_key, keyType + " KEY", passphrase,
                                 randfunc)
            return tobytes(pem_str)
        raise ValueError(
            "Unknown key format '%s'. Cannot export the RSA key." % format)
Exemple #11
0
 def _export_public_pem(self):
     encoded_der = self._export_subjectPublicKeyInfo()
     return PEM.encode(encoded_der, "PUBLIC KEY")
Exemple #12
0
    def exportKey(self, format='PEM', passphrase=None, pkcs=1,
                   protection=None, randfunc=None):
        """Export this RSA key.

        Args:
          format (string):
            The format to use for wrapping the key:

            - *'PEM'*. (*Default*) Text encoding, done according to `RFC1421`_/`RFC1423`_.
            - *'DER'*. Binary encoding.
            - *'OpenSSH'*. Textual encoding, done according to OpenSSH specification.
              Only suitable for public keys (not private keys).

          passphrase (string):
            (*For private keys only*) The pass phrase used for protecting the output.

          pkcs (integer):
            (*For private keys only*) The ASN.1 structure to use for
            serializing the key. Note that even in case of PEM
            encoding, there is an inner ASN.1 DER structure.

            With ``pkcs=1`` (*default*), the private key is encoded in a
            simple `PKCS#1`_ structure (``RSAPrivateKey``).

            With ``pkcs=8``, the private key is encoded in a `PKCS#8`_ structure
            (``PrivateKeyInfo``).

            .. note::
                This parameter is ignored for a public key.
                For DER and PEM, an ASN.1 DER ``SubjectPublicKeyInfo``
                structure is always used.

          protection (string):
            (*For private keys only*)
            The encryption scheme to use for protecting the private key.

            If ``None`` (default), the behavior depends on :attr:`format`:

            - For *'DER'*, the *PBKDF2WithHMAC-SHA1AndDES-EDE3-CBC*
              scheme is used. The following operations are performed:

                1. A 16 byte Triple DES key is derived from the passphrase
                   using :func:`Crypto.Protocol.KDF.PBKDF2` with 8 bytes salt,
                   and 1 000 iterations of :mod:`Crypto.Hash.HMAC`.
                2. The private key is encrypted using CBC.
                3. The encrypted key is encoded according to PKCS#8.

            - For *'PEM'*, the obsolete PEM encryption scheme is used.
              It is based on MD5 for key derivation, and Triple DES for encryption.

            Specifying a value for :attr:`protection` is only meaningful for PKCS#8
            (that is, ``pkcs=8``) and only if a pass phrase is present too.

            The supported schemes for PKCS#8 are listed in the
            :mod:`Crypto.IO.PKCS8` module (see :attr:`wrap_algo` parameter).

          randfunc (callable):
            A function that provides random bytes. Only used for PEM encoding.
            The default is :func:`Crypto.Random.get_random_bytes`.

        Returns:
          byte string: the encoded key

        Raises:
          ValueError:when the format is unknown or when you try to encrypt a private
            key with *DER* format and PKCS#1.

        .. warning::
            If you don't provide a pass phrase, the private key will be
            exported in the clear!

        .. _RFC1421:    http://www.ietf.org/rfc/rfc1421.txt
        .. _RFC1423:    http://www.ietf.org/rfc/rfc1423.txt
        .. _`PKCS#1`:   http://www.ietf.org/rfc/rfc3447.txt
        .. _`PKCS#8`:   http://www.ietf.org/rfc/rfc5208.txt
        """

        if passphrase is not None:
            passphrase = tobytes(passphrase)

        if randfunc is None:
            randfunc = Random.get_random_bytes

        if format == 'OpenSSH':
            e_bytes, n_bytes = [x.to_bytes() for x in (self._e, self._n)]
            if bord(e_bytes[0]) & 0x80:
                e_bytes = bchr(0) + e_bytes
            if bord(n_bytes[0]) & 0x80:
                n_bytes = bchr(0) + n_bytes
            keyparts = [b('ssh-rsa'), e_bytes, n_bytes]
            keystring = b('').join([struct.pack(">I", len(kp)) + kp for kp in keyparts])
            return b('ssh-rsa ') + binascii.b2a_base64(keystring)[:-1]

        # DER format is always used, even in case of PEM, which simply
        # encodes it into BASE64.
        if self.has_private():
            binary_key = DerSequence([0,
                                      self.n,
                                      self.e,
                                      self.d,
                                      self.p,
                                      self.q,
                                      self.d % (self.p-1),
                                      self.d % (self.q-1),
                                      Integer(self.q).inverse(self.p)
                                      ]).encode()
            if pkcs == 1:
                key_type = 'RSA PRIVATE KEY'
                if format == 'DER' and passphrase:
                    raise ValueError("PKCS#1 private key cannot be encrypted")
            else:  # PKCS#8
                if format == 'PEM' and protection is None:
                    key_type = 'PRIVATE KEY'
                    binary_key = PKCS8.wrap(binary_key, oid, None)
                else:
                    key_type = 'ENCRYPTED PRIVATE KEY'
                    if not protection:
                        protection = 'PBKDF2WithHMAC-SHA1AndDES-EDE3-CBC'
                    binary_key = PKCS8.wrap(binary_key, oid,
                                            passphrase, protection)
                    passphrase = None
        else:
            key_type = "PUBLIC KEY"
            binary_key = _create_subject_public_key_info(oid,
                                                         DerSequence([self.n,
                                                                      self.e])
                                                         )

        if format == 'DER':
            return binary_key
        if format == 'PEM':
            pem_str = PEM.encode(binary_key, key_type, passphrase, randfunc)
            return tobytes(pem_str)

        raise ValueError("Unknown key format '%s'. Cannot export the RSA key." % format)
Exemple #13
0
    def exportKey(self, format='PEM', passphrase=None, pkcs=1, protection=None, randfunc=None):
        """Export this RSA key.

        :Parameters:
          format : string
            The format to use for wrapping the key:

            - *'DER'*. Binary encoding.
            - *'PEM'*. Textual encoding, done according to `RFC1421`_/`RFC1423`_.
            - *'OpenSSH'*. Textual encoding, done according to OpenSSH specification.
              Only suitable for public keys (not private keys).

          passphrase : string
            For private keys only. The pass phrase used for deriving the encryption
            key.

          pkcs : integer
            For *DER* and *PEM* format only.
            The PKCS standard to follow for assembling the components of the key.
            You have two choices:

            - **1** (default): the public key is embedded into
              an X.509 ``SubjectPublicKeyInfo`` DER SEQUENCE.
              The private key is embedded into a `PKCS#1`_
              ``RSAPrivateKey`` DER SEQUENCE.
            - **8**: the private key is embedded into a `PKCS#8`_
              ``PrivateKeyInfo`` DER SEQUENCE. This value cannot be used
              for public keys.

          protection : string
            The encryption scheme to use for protecting the private key.

            If ``None`` (default), the behavior depends on ``format``:

            - For *DER*, the *PBKDF2WithHMAC-SHA1AndDES-EDE3-CBC*
              scheme is used. The following operations are performed:

                1. A 16 byte Triple DES key is derived from the passphrase
                   using `Crypto.Protocol.KDF.PBKDF2` with 8 bytes salt,
                   and 1 000 iterations of `Crypto.Hash.HMAC`.
                2. The private key is encrypted using CBC.
                3. The encrypted key is encoded according to PKCS#8.

            - For *PEM*, the obsolete PEM encryption scheme is used.
              It is based on MD5 for key derivation, and Triple DES for encryption.

            Specifying a value for ``protection`` is only meaningful for PKCS#8
            (that is, ``pkcs=8``) and only if a pass phrase is present too.

            The supported schemes for PKCS#8 are listed in the
            `Crypto.IO.PKCS8` module (see ``wrap_algo`` parameter).

          randfunc : callable
            A function that provides random bytes. Only used for PEM encoding.
            The default is `Crypto.Random.get_random_bytes`.

        :Return: A byte string with the encoded public or private half
          of the key.
        :Raise ValueError:
            When the format is unknown or when you try to encrypt a private
            key with *DER* format and PKCS#1.
        :attention:
            If you don't provide a pass phrase, the private key will be
            exported in the clear!

        .. _RFC1421:    http://www.ietf.org/rfc/rfc1421.txt
        .. _RFC1423:    http://www.ietf.org/rfc/rfc1423.txt
        .. _`PKCS#1`:   http://www.ietf.org/rfc/rfc3447.txt
        .. _`PKCS#8`:   http://www.ietf.org/rfc/rfc5208.txt
        """

        if passphrase is not None:
            passphrase = tobytes(passphrase)

        if randfunc is None:
            randfunc = Random.get_random_bytes

        if format=='OpenSSH':
               eb, nb = [self._key[comp].to_bytes() for comp in 'e', 'n']
               if bord(eb[0]) & 0x80: eb=bchr(0x00)+eb
               if bord(nb[0]) & 0x80: nb=bchr(0x00)+nb
               keyparts = [ b('ssh-rsa'), eb, nb ]
               keystring = b('').join([ struct.pack(">I",len(kp))+kp for kp in keyparts])
               return b('ssh-rsa ')+binascii.b2a_base64(keystring)[:-1]

        # DER format is always used, even in case of PEM, which simply
        # encodes it into BASE64.
        if self.has_private():
                binary_key = newDerSequence(
                        0,
                        self.n,
                        self.e,
                        self.d,
                        self.p,
                        self.q,
                        self.d % (self.p-1),
                        self.d % (self.q-1),
                        Integer(self.q).inverse(self.p)
                    ).encode()
                if pkcs==1:
                    keyType = 'RSA PRIVATE'
                    if format=='DER' and passphrase:
                        raise ValueError("PKCS#1 private key cannot be encrypted")
                else: # PKCS#8
                    if format=='PEM' and protection is None:
                        keyType = 'PRIVATE'
                        binary_key = PKCS8.wrap(binary_key, oid, None)
                    else:
                        keyType = 'ENCRYPTED PRIVATE'
                        if not protection:
                            protection = 'PBKDF2WithHMAC-SHA1AndDES-EDE3-CBC'
                        binary_key = PKCS8.wrap(binary_key, oid, passphrase, protection)
                        passphrase = None
        else:
                keyType = "RSA PUBLIC"
                binary_key = newDerSequence(
                    algorithmIdentifier,
                    newDerBitString(
                        newDerSequence( self.n, self.e )
                        )
                    ).encode()
        if format=='DER':
            return binary_key
        if format=='PEM':
            pem_str = PEM.encode(binary_key, keyType+" KEY", passphrase, randfunc)
            return tobytes(pem_str)
        raise ValueError("Unknown key format '%s'. Cannot export the RSA key." % format)
Exemple #14
0
    def _export_private_pem(self, passphrase, **kwargs):
        from Crypto.IO import PEM

        encoded_der = self._export_private_der()
        return PEM.encode(encoded_der, "EC PRIVATE KEY", passphrase, **kwargs)
Exemple #15
0
    def exportKey(self,
                  format='PEM',
                  pkcs8=None,
                  passphrase=None,
                  protection=None,
                  randfunc=None):
        """Export this DSA key.

        Args:
          format (string):
            The encoding for the output:

            - *'PEM'* (default). ASCII as per `RFC1421`_/ `RFC1423`_.
            - *'DER'*. Binary ASN.1 encoding.
            - *'OpenSSH'*. ASCII one-liner as per `RFC4253`_.
              Only suitable for public keys, not for private keys.

          passphrase (string):
            *Private keys only*. The pass phrase to protect the output.

          pkcs8 (boolean):
            *Private keys only*. If ``True`` (default), the key is encoded
            with `PKCS#8`_. If ``False``, it is encoded in the custom
            OpenSSL/OpenSSH container.

          protection (string):
            *Only in combination with a pass phrase*.
            The encryption scheme to use to protect the output.

            If :data:`pkcs8` takes value ``True``, this is the PKCS#8
            algorithm to use for deriving the secret and encrypting
            the private DSA key.
            For a complete list of algorithms, see :mod:`Crypto.IO.PKCS8`.
            The default is *PBKDF2WithHMAC-SHA1AndDES-EDE3-CBC*.

            If :data:`pkcs8` is ``False``, the obsolete PEM encryption scheme is
            used. It is based on MD5 for key derivation, and Triple DES for
            encryption. Parameter :data:`protection` is then ignored.

            The combination ``format='DER'`` and ``pkcs8=False`` is not allowed
            if a passphrase is present.

          randfunc (callable):
            A function that returns random bytes.
            By default it is :func:`Crypto.Random.get_random_bytes`.

        Returns:
          byte string : the encoded key

        Raises:
          ValueError : when the format is unknown or when you try to encrypt a private
            key with *DER* format and OpenSSL/OpenSSH.

        .. warning::
            If you don't provide a pass phrase, the private key will be
            exported in the clear!

        .. _RFC1421:    http://www.ietf.org/rfc/rfc1421.txt
        .. _RFC1423:    http://www.ietf.org/rfc/rfc1423.txt
        .. _RFC4253:    http://www.ietf.org/rfc/rfc4253.txt
        .. _`PKCS#8`:   http://www.ietf.org/rfc/rfc5208.txt
        """

        if passphrase is not None:
            passphrase = tobytes(passphrase)

        if randfunc is None:
            randfunc = Random.get_random_bytes

        if format == 'OpenSSH':
            tup1 = [self._key[x].to_bytes() for x in ('p', 'q', 'g', 'y')]

            def func(x):
                if (bord(x[0]) & 0x80):
                    return bchr(0) + x
                else:
                    return x

            tup2 = list(map(func, tup1))
            keyparts = [b('ssh-dss')] + tup2
            keystring = b('').join(
                [struct.pack(">I", len(kp)) + kp for kp in keyparts])
            return b('ssh-dss ') + binascii.b2a_base64(keystring)[:-1]

        # DER format is always used, even in case of PEM, which simply
        # encodes it into BASE64.
        params = DerSequence([self.p, self.q, self.g])
        if self.has_private():
            if pkcs8 is None:
                pkcs8 = True
            if pkcs8:
                if not protection:
                    protection = 'PBKDF2WithHMAC-SHA1AndDES-EDE3-CBC'
                private_key = DerInteger(self.x).encode()
                binary_key = PKCS8.wrap(private_key,
                                        oid,
                                        passphrase,
                                        protection,
                                        key_params=params,
                                        randfunc=randfunc)
                if passphrase:
                    key_type = 'ENCRYPTED PRIVATE'
                else:
                    key_type = 'PRIVATE'
                passphrase = None
            else:
                if format != 'PEM' and passphrase:
                    raise ValueError("DSA private key cannot be encrypted")
                ints = [0, self.p, self.q, self.g, self.y, self.x]
                binary_key = DerSequence(ints).encode()
                key_type = "DSA PRIVATE"
        else:
            if pkcs8:
                raise ValueError("PKCS#8 is only meaningful for private keys")

            binary_key = _create_subject_public_key_info(
                oid, DerInteger(self.y), params)
            key_type = "PUBLIC"

        if format == 'DER':
            return binary_key
        if format == 'PEM':
            pem_str = PEM.encode(binary_key, key_type + " KEY", passphrase,
                                 randfunc)
            return tobytes(pem_str)
        raise ValueError(
            "Unknown key format '%s'. Cannot export the DSA key." % format)
Exemple #16
0
 def _export_private_clear_pkcs8_in_clear_pem(self):
     encoded_der = self._export_pkcs8()
     return PEM.encode(encoded_der, "PRIVATE KEY")
#print(hexlify(keyfile[0]))
f.close()
seq_der = DerSequence()
der = seq_der.decode(keyfile[0])

# Replace private key
octet_der = DerOctetString(privkey)
der[1] = octet_der.encode()

# Replace public key
#print(hexlify(der[3]))
bits_der = DerBitString(unhexlify(b"04" + pubkey))
der[3] = b"\xa1\x64" + bits_der.encode()
#print(hexlify(der[3]))

# Replace the generator
#print(hexlify(der[2]))
seq_der = DerSequence()
s = seq_der.decode(der[2][4:])
octet_der = DerOctetString(rogueG)
s[3] = octet_der.encode()
der[2] = der[2][:4] + s.encode()
#print(hexlify(der[2]))

# Generate new file
f = open('p384-key-rogue.pem', 'w')
#print(hexlify(der.encode()))
keyfile = PEM.encode(der.encode(), 'EC PRIVATE KEY')
f.write(keyfile)
f.close()
def get_private_key(key_pair):
    privKey_DER = key_pair.exportKey(format='DER')
    return PEM.encode(privKey_DER, "RSA PRIVATE KEY")
    def exportKey(self,
                  format='PEM',
                  pkcs8=None,
                  passphrase=None,
                  protection=None):
        if passphrase is not None:
            passphrase = tobytes(passphrase)
        if format == 'OpenSSH':
            tup1 = [long_to_bytes(x) for x in (self.p, self.q, self.g, self.y)]

            def func(x):
                if bord(x[0]) & 128:
                    return bchr(0) + x
                else:
                    return x

            tup2 = map(func, tup1)
            keyparts = [b('ssh-dss')] + tup2
            keystring = b('').join(
                [struct.pack('>I', len(kp)) + kp for kp in keyparts])
            return b('ssh-dss ') + binascii.b2a_base64(keystring)[:-1]
        else:
            params = newDerSequence(self.p, self.q, self.g)
            if self.has_private():
                if pkcs8 is None:
                    pkcs8 = True
                if pkcs8:
                    if not protection:
                        protection = 'PBKDF2WithHMAC-SHA1AndDES-EDE3-CBC'
                    private_key = DerInteger(self.x).encode()
                    binary_key = PKCS8.wrap(private_key,
                                            oid,
                                            passphrase,
                                            protection,
                                            key_params=params,
                                            randfunc=self._randfunc)
                    if passphrase:
                        key_type = 'ENCRYPTED PRIVATE'
                    else:
                        key_type = 'PRIVATE'
                    passphrase = None
                else:
                    if format != 'PEM' and passphrase:
                        raise ValueError('DSA private key cannot be encrypted')
                    ints = [0, self.p, self.q, self.g, self.y, self.x]
                    binary_key = newDerSequence(*ints).encode()
                    key_type = 'DSA PRIVATE'
            else:
                if pkcs8:
                    raise ValueError(
                        'PKCS#8 is only meaningful for private keys')
                binary_key = newDerSequence(
                    newDerSequence(DerObjectId(oid), params),
                    newDerBitString(DerInteger(self.y))).encode()
                key_type = 'DSA PUBLIC'
            if format == 'DER':
                return binary_key
            if format == 'PEM':
                pem_str = PEM.encode(binary_key, key_type + ' KEY', passphrase,
                                     self._randfunc)
                return tobytes(pem_str)
            raise ValueError(
                "Unknown key format '%s'. Cannot export the DSA key." % format)
            return
Exemple #20
0
def encodePEMRawRSAPubKey(key):
    return PEM.encode(DerSequence([key.n, key.e]).encode(), "RSA PUBLIC KEY")
Exemple #21
0
    def exportKey(self, format='PEM', pkcs8=None, passphrase=None,
                  protection=None, randfunc=None):
        """Export this DSA key.

        Args:
          format (string):
            The encoding for the output:

            - *'PEM'* (default). ASCII as per `RFC1421`_/ `RFC1423`_.
            - *'DER'*. Binary ASN.1 encoding.
            - *'OpenSSH'*. ASCII one-liner as per `RFC4253`_.
              Only suitable for public keys, not for private keys.

          passphrase (string):
            *Private keys only*. The pass phrase to protect the output.

          pkcs8 (boolean):
            *Private keys only*. If ``True`` (default), the key is encoded
            with `PKCS#8`_. If ``False``, it is encoded in the custom
            OpenSSL/OpenSSH container.

          protection (string):
            *Only in combination with a pass phrase*.
            The encryption scheme to use to protect the output.

            If :data:`pkcs8` takes value ``True``, this is the PKCS#8
            algorithm to use for deriving the secret and encrypting
            the private DSA key.
            For a complete list of algorithms, see :mod:`Crypto.IO.PKCS8`.
            The default is *PBKDF2WithHMAC-SHA1AndDES-EDE3-CBC*.

            If :data:`pkcs8` is ``False``, the obsolete PEM encryption scheme is
            used. It is based on MD5 for key derivation, and Triple DES for
            encryption. Parameter :data:`protection` is then ignored.

            The combination ``format='DER'`` and ``pkcs8=False`` is not allowed
            if a passphrase is present.

          randfunc (callable):
            A function that returns random bytes.
            By default it is :func:`Crypto.Random.get_random_bytes`.

        Returns:
          byte string : the encoded key

        Raises:
          ValueError : when the format is unknown or when you try to encrypt a private
            key with *DER* format and OpenSSL/OpenSSH.

        .. warning::
            If you don't provide a pass phrase, the private key will be
            exported in the clear!

        .. _RFC1421:    http://www.ietf.org/rfc/rfc1421.txt
        .. _RFC1423:    http://www.ietf.org/rfc/rfc1423.txt
        .. _RFC4253:    http://www.ietf.org/rfc/rfc4253.txt
        .. _`PKCS#8`:   http://www.ietf.org/rfc/rfc5208.txt
        """

        if passphrase is not None:
            passphrase = tobytes(passphrase)

        if randfunc is None:
            randfunc = Random.get_random_bytes

        if format == 'OpenSSH':
            tup1 = [self._key[x].to_bytes() for x in 'p', 'q', 'g', 'y']

            def func(x):
                if (bord(x[0]) & 0x80):
                    return bchr(0) + x
                else:
                    return x

            tup2 = map(func, tup1)
            keyparts = [b('ssh-dss')] + tup2
            keystring = b('').join(
                            [struct.pack(">I", len(kp)) + kp for kp in keyparts]
                            )
            return b('ssh-dss ') + binascii.b2a_base64(keystring)[:-1]

        # DER format is always used, even in case of PEM, which simply
        # encodes it into BASE64.
        params = DerSequence([self.p, self.q, self.g])
        if self.has_private():
            if pkcs8 is None:
                pkcs8 = True
            if pkcs8:
                if not protection:
                    protection = 'PBKDF2WithHMAC-SHA1AndDES-EDE3-CBC'
                private_key = DerInteger(self.x).encode()
                binary_key = PKCS8.wrap(
                                private_key, oid, passphrase,
                                protection, key_params=params,
                                randfunc=randfunc
                                )
                if passphrase:
                    key_type = 'ENCRYPTED PRIVATE'
                else:
                    key_type = 'PRIVATE'
                passphrase = None
            else:
                if format != 'PEM' and passphrase:
                    raise ValueError("DSA private key cannot be encrypted")
                ints = [0, self.p, self.q, self.g, self.y, self.x]
                binary_key = DerSequence(ints).encode()
                key_type = "DSA PRIVATE"
        else:
            if pkcs8:
                raise ValueError("PKCS#8 is only meaningful for private keys")

            binary_key = _create_subject_public_key_info(oid,
                                DerInteger(self.y), params)
            key_type = "PUBLIC"

        if format == 'DER':
            return binary_key
        if format == 'PEM':
            pem_str = PEM.encode(
                                binary_key, key_type + " KEY",
                                passphrase, randfunc
                            )
            return tobytes(pem_str)
        raise ValueError("Unknown key format '%s'. Cannot export the DSA key." % format)
Exemple #22
0
    def exportKey(self,
                  format='PEM',
                  passphrase=None,
                  pkcs=1,
                  protection=None,
                  randfunc=None):
        """Export this RSA key.

        Args:
          format (string):
            The format to use for wrapping the key:

            - *'PEM'*. (*Default*) Text encoding, done according to `RFC1421`_/`RFC1423`_.
            - *'DER'*. Binary encoding.
            - *'OpenSSH'*. Textual encoding, done according to OpenSSH specification.
              Only suitable for public keys (not private keys).

          passphrase (string):
            (*For private keys only*) The pass phrase used for protecting the output.

          pkcs (integer):
            (*For private keys only*) The ASN.1 structure to use for
            serializing the key. Note that even in case of PEM
            encoding, there is an inner ASN.1 DER structure.

            With ``pkcs=1`` (*default*), the private key is encoded in a
            simple `PKCS#1`_ structure (``RSAPrivateKey``).

            With ``pkcs=8``, the private key is encoded in a `PKCS#8`_ structure
            (``PrivateKeyInfo``).

            .. note::
                This parameter is ignored for a public key.
                For DER and PEM, an ASN.1 DER ``SubjectPublicKeyInfo``
                structure is always used.

          protection (string):
            (*For private keys only*)
            The encryption scheme to use for protecting the private key.

            If ``None`` (default), the behavior depends on :attr:`format`:

            - For *'DER'*, the *PBKDF2WithHMAC-SHA1AndDES-EDE3-CBC*
              scheme is used. The following operations are performed:

                1. A 16 byte Triple DES key is derived from the passphrase
                   using :func:`Crypto.Protocol.KDF.PBKDF2` with 8 bytes salt,
                   and 1 000 iterations of :mod:`Crypto.Hash.HMAC`.
                2. The private key is encrypted using CBC.
                3. The encrypted key is encoded according to PKCS#8.

            - For *'PEM'*, the obsolete PEM encryption scheme is used.
              It is based on MD5 for key derivation, and Triple DES for encryption.

            Specifying a value for :attr:`protection` is only meaningful for PKCS#8
            (that is, ``pkcs=8``) and only if a pass phrase is present too.

            The supported schemes for PKCS#8 are listed in the
            :mod:`Crypto.IO.PKCS8` module (see :attr:`wrap_algo` parameter).

          randfunc (callable):
            A function that provides random bytes. Only used for PEM encoding.
            The default is :func:`Crypto.Random.get_random_bytes`.

        Returns:
          byte string: the encoded key

        Raises:
          ValueError:when the format is unknown or when you try to encrypt a private
            key with *DER* format and PKCS#1.

        .. warning::
            If you don't provide a pass phrase, the private key will be
            exported in the clear!

        .. _RFC1421:    http://www.ietf.org/rfc/rfc1421.txt
        .. _RFC1423:    http://www.ietf.org/rfc/rfc1423.txt
        .. _`PKCS#1`:   http://www.ietf.org/rfc/rfc3447.txt
        .. _`PKCS#8`:   http://www.ietf.org/rfc/rfc5208.txt
        """

        if passphrase is not None:
            passphrase = tobytes(passphrase)

        if randfunc is None:
            randfunc = Random.get_random_bytes

        if format == 'OpenSSH':
            e_bytes, n_bytes = [x.to_bytes() for x in (self._e, self._n)]
            if bord(e_bytes[0]) & 0x80:
                e_bytes = bchr(0) + e_bytes
            if bord(n_bytes[0]) & 0x80:
                n_bytes = bchr(0) + n_bytes
            keyparts = [b('ssh-rsa'), e_bytes, n_bytes]
            keystring = b('').join(
                [struct.pack(">I", len(kp)) + kp for kp in keyparts])
            return b('ssh-rsa ') + binascii.b2a_base64(keystring)[:-1]

        # DER format is always used, even in case of PEM, which simply
        # encodes it into BASE64.
        if self.has_private():
            binary_key = DerSequence([
                0, self.n, self.e, self.d, self.p, self.q,
                self.d % (self.p - 1), self.d % (self.q - 1),
                Integer(self.q).inverse(self.p)
            ]).encode()
            if pkcs == 1:
                key_type = 'RSA PRIVATE KEY'
                if format == 'DER' and passphrase:
                    raise ValueError("PKCS#1 private key cannot be encrypted")
            else:  # PKCS#8
                if format == 'PEM' and protection is None:
                    key_type = 'PRIVATE KEY'
                    binary_key = PKCS8.wrap(binary_key, oid, None)
                else:
                    key_type = 'ENCRYPTED PRIVATE KEY'
                    if not protection:
                        protection = 'PBKDF2WithHMAC-SHA1AndDES-EDE3-CBC'
                    binary_key = PKCS8.wrap(binary_key, oid, passphrase,
                                            protection)
                    passphrase = None
        else:
            key_type = "PUBLIC KEY"
            binary_key = _create_subject_public_key_info(
                oid, DerSequence([self.n, self.e]))

        if format == 'DER':
            return binary_key
        if format == 'PEM':
            pem_str = PEM.encode(binary_key, key_type, passphrase, randfunc)
            return tobytes(pem_str)

        raise ValueError(
            "Unknown key format '%s'. Cannot export the RSA key." % format)
Exemple #23
0
 def _export_public_pem(self):
     encoded_der = self._export_subjectPublicKeyInfo()
     return PEM.encode(encoded_der, "PUBLIC KEY")
Exemple #24
0
    def exportKey(self, format='PEM', pkcs8=None, passphrase=None,
                  protection=None, randfunc=None):
        """Export this DSA key.

        :Parameters:
          format : string
            The format to use for wrapping the key:

            - *'DER'*. Binary encoding.
            - *'PEM'*. Textual encoding, done according to `RFC1421`_/
              `RFC1423`_ (default).
            - *'OpenSSH'*. Textual encoding, one line of text, see `RFC4253`_.
              Only suitable for public keys, not private keys.

          passphrase : string
            For private keys only. The pass phrase to use for deriving
            the encryption key.

          pkcs8 : boolean
            For private keys only. If ``True`` (default), the key is arranged
            according to `PKCS#8`_ and if `False`, according to the custom
            OpenSSL/OpenSSH encoding.

          protection : string
            The encryption scheme to use for protecting the private key.
            It is only meaningful when a pass phrase is present too.

            If ``pkcs8`` takes value ``True``, ``protection`` is the PKCS#8
            algorithm to use for deriving the secret and encrypting
            the private DSA key.
            For a complete list of algorithms, see `Crypto.IO.PKCS8`.
            The default is *PBKDF2WithHMAC-SHA1AndDES-EDE3-CBC*.

            If ``pkcs8`` is ``False``, the obsolete PEM encryption scheme is
            used. It is based on MD5 for key derivation, and Triple DES for
            encryption. Parameter ``protection`` is ignored.

            The combination ``format='DER'`` and ``pkcs8=False`` is not allowed
            if a passphrase is present.

          randfunc : callable
            A function that returns random bytes.
            By default it is `Crypto.Random.get_random_bytes`.

        :Return: A byte string with the encoded public or private half
          of the key.
        :Raise ValueError:
            When the format is unknown or when you try to encrypt a private
            key with *DER* format and OpenSSL/OpenSSH.
        :attention:
            If you don't provide a pass phrase, the private key will be
            exported in the clear!

        .. _RFC1421:    http://www.ietf.org/rfc/rfc1421.txt
        .. _RFC1423:    http://www.ietf.org/rfc/rfc1423.txt
        .. _RFC4253:    http://www.ietf.org/rfc/rfc4253.txt
        .. _`PKCS#8`:   http://www.ietf.org/rfc/rfc5208.txt
        """

        if passphrase is not None:
            passphrase = tobytes(passphrase)

        if randfunc is None:
            randfunc = Random.get_random_bytes

        if format == 'OpenSSH':
            tup1 = [self._key[x].to_bytes() for x in 'p', 'q', 'g', 'y']

            def func(x):
                if (bord(x[0]) & 0x80):
                    return bchr(0) + x
                else:
                    return x

            tup2 = map(func, tup1)
            keyparts = [b('ssh-dss')] + tup2
            keystring = b('').join(
                            [struct.pack(">I", len(kp)) + kp for kp in keyparts]
                            )
            return b('ssh-dss ') + binascii.b2a_base64(keystring)[:-1]

        # DER format is always used, even in case of PEM, which simply
        # encodes it into BASE64.
        params = newDerSequence(self.p, self.q, self.g)
        if self.has_private():
            if pkcs8 is None:
                pkcs8 = True
            if pkcs8:
                if not protection:
                    protection = 'PBKDF2WithHMAC-SHA1AndDES-EDE3-CBC'
                private_key = DerInteger(self.x).encode()
                binary_key = PKCS8.wrap(
                                private_key, oid, passphrase,
                                protection, key_params=params,
                                randfunc=randfunc
                                )
                if passphrase:
                    key_type = 'ENCRYPTED PRIVATE'
                else:
                    key_type = 'PRIVATE'
                passphrase = None
            else:
                if format != 'PEM' and passphrase:
                    raise ValueError("DSA private key cannot be encrypted")
                ints = [0, self.p, self.q, self.g, self.y, self.x]
                binary_key = newDerSequence(*ints).encode()
                key_type = "DSA PRIVATE"
        else:
            if pkcs8:
                raise ValueError("PKCS#8 is only meaningful for private keys")
            binary_key = newDerSequence(
                            newDerSequence(DerObjectId(oid), params),
                            newDerBitString(DerInteger(self.y))
                            ).encode()
            key_type = "DSA PUBLIC"

        if format == 'DER':
            return binary_key
        if format == 'PEM':
            pem_str = PEM.encode(
                                binary_key, key_type + " KEY",
                                passphrase, randfunc
                            )
            return tobytes(pem_str)
        raise ValueError("Unknown key format '%s'. Cannot export the DSA key." % format)
Exemple #25
0
 def _export_private_pem(self, passphrase, **kwargs):
     encoded_der = self._export_private_der()
     return PEM.encode(encoded_der, "EC PRIVATE KEY", passphrase, **kwargs)
Exemple #26
0
    def _export_public_pem(self, compress):
        from Crypto.IO import PEM

        encoded_der = self._export_subjectPublicKeyInfo(compress)
        return PEM.encode(encoded_der, "PUBLIC KEY")
Exemple #27
0
 def _export_private_clear_pkcs8_in_clear_pem(self):
     encoded_der = self._export_pkcs8()
     return PEM.encode(encoded_der, "PRIVATE KEY")
Exemple #28
0
    def _export_private_clear_pkcs8_in_clear_pem(self):
        from Crypto.IO import PEM

        encoded_der = self._export_pkcs8()
        return PEM.encode(encoded_der, "PRIVATE KEY")
Exemple #29
0
 def _export_private_encrypted_pkcs8_in_clear_pem(self, passphrase, **kwargs):
     assert passphrase
     if 'protection' not in kwargs:
         raise ValueError("At least the 'protection' parameter should be present")
     encoded_der = self._export_pkcs8(passphrase=passphrase, **kwargs)
     return PEM.encode(encoded_der, "ENCRYPTED PRIVATE KEY")