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'))
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')
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
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"
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
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)
def _export_public_pem(self): encoded_der = self._export_subjectPublicKeyInfo() return PEM.encode(encoded_der, "PUBLIC KEY")
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)
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)
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)
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)
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
def encodePEMRawRSAPubKey(key): return PEM.encode(DerSequence([key.n, key.e]).encode(), "RSA PUBLIC KEY")
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)
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)
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)
def _export_private_pem(self, passphrase, **kwargs): encoded_der = self._export_private_der() return PEM.encode(encoded_der, "EC PRIVATE KEY", passphrase, **kwargs)
def _export_public_pem(self, compress): from Crypto.IO import PEM encoded_der = self._export_subjectPublicKeyInfo(compress) return PEM.encode(encoded_der, "PUBLIC KEY")
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")
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")