Beispiel #1
0
def generate_root_certificate(private_key: rsa.RSAPrivateKey) -> x509.Certificate:
    backend = cryptography.hazmat.backends.default_backend()
    subject = x509.Name(
        [x509.NameAttribute(
            x509.oid.NameOID.COMMON_NAME, 'root'
        )]
    )
    builder = x509.CertificateBuilder()
    return builder.subject_name(subject).issuer_name(subject) \
        .not_valid_before(datetime.datetime.utcnow()) \
        .not_valid_after(datetime.datetime.utcnow() + datetime.timedelta(days=1)) \
        .serial_number(1) \
        .public_key(private_key.public_key()) \
        .add_extension(extension=x509.BasicConstraints(ca=True, path_length=1), critical=True) \
        .add_extension(extension=x509.KeyUsage(digital_signature=False,
                                               content_commitment=False,
                                               key_encipherment=False,
                                               data_encipherment=False,
                                               key_agreement=False,
                                               key_cert_sign=True,
                                               crl_sign=True,
                                               encipher_only=False,
                                               decipher_only=False,
                                               ), critical=True) \
        .sign(private_key=private_key, algorithm=hashes.SHA256(), backend=backend)
Beispiel #2
0
def compute_signature(pkey: RSAPrivateKey, text: str) -> str:
    signature = pkey.sign(
        text.encode('utf-8'),
        padding.PKCS1v15(),
        SHA256(),
    )
    return b64encode(signature).decode('ascii')
Beispiel #3
0
 def _DefaultBlobSign(
     self,
     blob_bytes: bytes,
     private_key: rsa.RSAPrivateKey,
 ) -> bytes:
     padding_algorithm = padding.PKCS1v15()
     return private_key.sign(blob_bytes, padding_algorithm, hashes.SHA256())
Beispiel #4
0
    def getFileSignature(cls, filename: str,
                         private_key: RSAPrivateKey) -> Optional[str]:
        """Creates the signature for the (hash of the) provided file, given a private key.

        :param filename: The file to be signed.
        :param private_key: The private key used for signing.
        :return: The signature if successful, 'None' otherwise.
        """

        file_hash = cls.getFileHash(filename)
        if file_hash is None:
            return None
        try:
            file_hash_bytes = base64.b64decode(file_hash)
            signature_bytes = private_key.sign(
                file_hash_bytes,
                padding.PSS(mgf=padding.MGF1(cls.__hash_algorithm),
                            salt_length=padding.PSS.MAX_LENGTH),
                Prehashed(cls.__hash_algorithm))
            return base64.b64encode(signature_bytes).decode("utf-8")
        except:  # Yes, we  do really want this on _every_ exception that might occur.
            Logger.logException(
                "e", "Couldn't sign '{0}', no signature generated.".format(
                    filename))
        return None
def rsa_key_to_str(private_key: rsa.RSAPrivateKey) -> str:
    """ return RSA private key as string - PEM format, no encryption """
    return private_key.private_bytes(
        encoding=serialization.Encoding.PEM,
        format=serialization.PrivateFormat.TraditionalOpenSSL,
        encryption_algorithm=serialization.NoEncryption()
    ).decode()
Beispiel #6
0
def serialize_privkey(private_key: rsa.RSAPrivateKey) -> bytes:
    """
    Serialize an RSA private into the DER format.
    """
    return private_key.private_bytes(serialization.Encoding.DER,
                                     serialization.PrivateFormat.PKCS8,
                                     serialization.NoEncryption())
Beispiel #7
0
    def getHashSignature(cls,
                         shash: str,
                         private_key: RSAPrivateKey,
                         err_info: Optional[str] = None) -> Optional[str]:
        """ Creates the signature for the provided hash, given a private key.

        :param shash: The provided string.
        :param private_key: The private key used for signing.
        :param err_info: Some optional extra info to be printed on error (for ex.: a filename the data came from).
        :return: The signature if successful, 'None' otherwise.
        """

        try:
            hash_bytes = base64.b64decode(shash)
            signature_bytes = private_key.sign(
                hash_bytes,
                padding.PSS(mgf=padding.MGF1(cls.__hash_algorithm),
                            salt_length=padding.PSS.MAX_LENGTH),
                Prehashed(cls.__hash_algorithm))
            return base64.b64encode(signature_bytes).decode("utf-8")
        except:  # Yes, we  do really want this on _every_ exception that might occur.
            if err_info is None:
                err_info = "HASH:" + shash
            Logger.logException(
                "e", "Couldn't sign '{0}', no signature generated.".format(
                    err_info))
        return None
Beispiel #8
0
def save_private_key(key: rsa.RSAPrivateKey,
                     file_name: Path,
                     passphrase: bytes = None,
                     encoding: str = 'PEM',
                     format: str = 'PKCS8'):
    """
    Save private key to file.
    Default is PEM key in PKCS8 format.

    Parameters
    ----------
    key
        Private key object.
    file_name
        Output file name.
    passphrase
        Passphrase to encrypt file.
    encoding
        Encoding format.
    format
        Output format.
        Values: PKCS8 or TraditionalOpenSSL
    """
    with open(str(file_name), "wb") as outf:
        outf.write(
            key.private_bytes(
                encoding=Encoding[encoding],
                format=PrivateFormat[format],
                encryption_algorithm=serialization.BestAvailableEncryption(
                    password=passphrase),
            ))
Beispiel #9
0
def generate_self_signed(private_key: rsa.RSAPrivateKey, subject: x509.Name) -> x509.Certificate:
    """Generate a Self-Signed certificate for use with a CMS PKCS#10 request.

    Args:
          private_key (rsa.RSAPrivateKey): The private key to sign the certificate with.
        subject (x509.Name): The subject used in the CSR, which must match this certificates subject.

    Returns:
          x509.Certificate: Self signed certificate for CMS envelope
    """
    one_day = datetime.timedelta(1, 0, 0)
    builder = x509.CertificateBuilder()
    builder = builder.subject_name(subject)
    builder = builder.issuer_name(subject)
    builder = builder.not_valid_before(datetime.datetime.today() - one_day)
    builder = builder.not_valid_after(datetime.datetime.utcnow() + datetime.timedelta(days=365))
    builder = builder.serial_number(x509.random_serial_number())
    builder = builder.public_key(private_key.public_key())
    
    # builder = builder.add_extension(
    #     x509.KeyUsage(digital_signature=True, key_encipherment=True), critical=True
    # )
    certificate = builder.sign(private_key=private_key, algorithm=hashes.SHA256(),
                               backend=default_backend())
    return certificate
Beispiel #10
0
def obtain_key_id(token: str, rsa_key: RSAPrivateKey, staging: bool = False) -> Response:
    target = '/g_business/v1/authentication_keys'
    key_encoding = Encoding.PEM
    key_format = PublicFormat.SubjectPublicKeyInfo
    public_key = rsa_key.public_key().public_bytes(key_encoding, key_format)
    body = {'public_key': public_key.decode(), 'token': token}
    with SatispayClient('PLACEHOLDER', rsa_key, staging) as client:
        return client.post(target, json=body)
Beispiel #11
0
def check_certificate_against_private_key(
    cert: Certificate,
    private_key: RSAPrivateKey,
) -> None:
    # Check if the public key of certificate matches the public key corresponding to the given
    # private one
    assert (_rsa_public_key_from_cert_or_csr(cert).public_numbers() ==
            private_key.public_key().public_numbers())
Beispiel #12
0
 def decode(cls, private_key: RSAPrivateKey, token_bytes: str) -> str:
     public_bytes = private_key.public_key().public_bytes(
         encoding=Encoding.PEM, format=PublicFormat.SubjectPublicKeyInfo)
     token = jwt_decode(token_bytes,
                        public_bytes,
                        algorithms=['RS256'],
                        verify=False)
     return token['sub']
Beispiel #13
0
def decrypt_message(ciphertext: bytes,
                    private_key: rsa.RSAPrivateKey = PRIVATE_KEY) -> bytes:
    """Decrypt some message encrypted with out public key."""
    return private_key.decrypt(
        ciphertext,
        padding.OAEP(mgf=padding.MGF1(algorithm=hashes.SHA256()),
                     algorithm=hashes.SHA256(),
                     label=None))
Beispiel #14
0
def pk_decrypt(ciphertext: bytes, private_key: rsa.RSAPrivateKey) -> bytes:
    """
    Decrypt an RSAES-OAEP-encrypted message.
    """
    plaintext = private_key.decrypt(
        ciphertext,
        padding.OAEP(padding.MGF1(hashes.SHA1()), hashes.SHA1(), None))
    return plaintext
Beispiel #15
0
def gen_self_signed(key: rsa.RSAPrivateKey, cert_opts: Dict,
                    crypto_opts: Dict) -> None:  # noqa
    # subject / issuer
    subject = issuer = _subject(cert_opts)

    # init builder
    builder = x509.CertificateBuilder()

    # set subject and issuer
    builder = builder.subject_name(subject)
    builder = builder.issuer_name(issuer)

    # set public key
    builder = builder.public_key(key.public_key())

    # set serial number
    serial = x509.random_serial_number()
    builder = builder.serial_number(serial)

    # set expiration
    now = datetime.datetime.utcnow()
    days = cert_opts['days']
    builder = builder.not_valid_before(now)
    builder = builder.not_valid_after(now + datetime.timedelta(days=days))

    # add base extensions
    for is_critical, ext in _extensions(key, cert_opts):
        builder = builder.add_extension(ext, critical=is_critical)

    # add AuthorityKeyIdentifier extension (experimental feature)
    pkey = key.public_key()
    key_identifier = x509.extensions._key_identifier_from_public_key(pkey)
    authority_cert_issuer = [x509.DirectoryName(issuer)]
    builder = builder.add_extension(x509.AuthorityKeyIdentifier(
        key_identifier, authority_cert_issuer, serial),
                                    critical=False)

    # sign the certificate
    md_alg = MD_ALGS[crypto_opts['md_alg']]
    crt = builder.sign(key, md_alg)

    # write to file
    crt_out = crypto_opts['crt_out']
    with open(str(crt_out), "wb") as fp:
        fp.write(crt.public_bytes(serialization.Encoding.PEM))
        fp.close()
Beispiel #16
0
def pk_sign(message: bytes, private_key: rsa.RSAPrivateKey) -> bytes:
    """
    Sign a message using RSASSA-PSS.
    """
    signer = private_key.signer(padding.PSS(padding.MGF1(hashes.SHA256()),
            padding.PSS.MAX_LENGTH),
        hashes.SHA256())
    signer.update(message)
    return signer.finalize()
Beispiel #17
0
def pk_sign(message: bytes, private_key: rsa.RSAPrivateKey) -> bytes:
    """
    Sign a message using RSASSA-PSS.
    """
    signer = private_key.signer(
        padding.PSS(padding.MGF1(hashes.SHA256()), padding.PSS.MAX_LENGTH),
        hashes.SHA256())
    signer.update(message)
    return signer.finalize()
Beispiel #18
0
def make_jwks(_private_key: RSAPrivateKey):
    """Returns JWKS."""
    jwk = json.loads(
        RSAAlgorithm.to_jwk(_private_key.public_key()),
    )
    jwk['kid'] = TEST_KID
    return {
        'keys': [jwk]
    }
Beispiel #19
0
    def get_envelope(self, key: RSAPrivateKey):
        json_message = self.to_json()
        signature = base64.b64encode(
            key.sign(json_message.encode("utf-8"), padding.PKCS1v15(), hashes.SHA256())
        )

        return PaymentRequestEnvelope(
            message=json_message, signature=signature.decode("utf-8")
        )
Beispiel #20
0
def pk_decrypt(ciphertext: bytes, private_key: rsa.RSAPrivateKey) -> bytes:
    """
    Decrypt an RSAES-OAEP-encrypted message.
    """
    plaintext = private_key.decrypt(ciphertext, padding.OAEP(
            padding.MGF1(hashes.SHA1()),
            hashes.SHA1(),
            None))
    return plaintext
Beispiel #21
0
    def get_decrypted_envelope_data(self, certificate: x509.Certificate,
                                    key: rsa.RSAPrivateKey) -> bytes:
        """Decrypt the encrypted envelope data:
        
        Decrypt encrypted_key using public key of CA
        encrypted_key is available at content.recipient_infos[x].encrypted_key
        algo is content.recipient_infos[x].key_encryption_algorithm
        at the moment this is RSA
        """
        encap = self.encap_content_info
        ct = encap['content_type'].native
        print(ct)
        recipient_info = encap['content']['recipient_infos'][0]

        encryption_algo = recipient_info.chosen[
            'key_encryption_algorithm'].native
        encrypted_key = recipient_info.chosen['encrypted_key'].native

        assert encryption_algo['algorithm'] == 'rsa'

        plain_key = key.decrypt(
            encrypted_key,
            padding=asympad.PKCS1v15(),
        )

        # Now we have the plain key, we can decrypt the encrypted data
        encrypted_contentinfo = encap['content']['encrypted_content_info']
        print('encrypted content type: {}'.format(
            encrypted_contentinfo['content_type'].native))

        algorithm = encrypted_contentinfo[
            'content_encryption_algorithm']  #: EncryptionAlgorithm
        encrypted_content_bytes = encrypted_contentinfo[
            'encrypted_content'].native

        symkey = None

        if algorithm.encryption_cipher == 'aes':
            symkey = AES(plain_key)
            print('cipher AES')
        elif algorithm.encryption_cipher == 'tripledes':
            symkey = TripleDES(plain_key)
            print('cipher 3DES')
        else:
            print('Dont understand encryption cipher: ',
                  algorithm.encryption_cipher)

        print('key length: ', algorithm.key_length)
        print('enc mode: ', algorithm.encryption_mode)

        cipher = Cipher(symkey,
                        modes.CBC(algorithm.encryption_iv),
                        backend=default_backend())
        decryptor = cipher.decryptor()

        return decryptor.update(encrypted_content_bytes) + decryptor.finalize()
Beispiel #22
0
    def encode(self, private_key: RSAPrivateKey) -> bytes:
        private_bytes = private_key.private_bytes(
            encoding=Encoding.PEM,
            format=PrivateFormat.TraditionalOpenSSL,
            encryption_algorithm=NoEncryption())

        public_key = private_key.public_key()
        numbers = public_key.public_numbers()
        n = numbers.n.to_bytes(int(public_key.key_size / 8),
                               'big').lstrip(b'\x00')

        kid = sha1(n).hexdigest()

        payload = self.payload()

        return jwt_encode(payload,
                          private_bytes,
                          algorithm='RS256',
                          headers={'kid': kid})
Beispiel #23
0
 def sign(self, key: rsa.RSAPrivateKey, msg: bytes) -> bytes:
     """Sign the ``msg`` using ``key``."""
     try:
         return key.sign(msg, self.padding, self.hash)
     except AttributeError as error:
         logger.debug(error, exc_info=True)
         raise errors.Error("Public key cannot be used for signing")
     except ValueError as error:  # digest too large
         logger.debug(error, exc_info=True)
         raise errors.Error(str(error))
Beispiel #24
0
    def sign(private_key: RSAPrivateKey, data: bytes) -> bytes:
        """Sign one block of data which can be verified later by other using the public key.

        Args:
            private_key: The private key with which the data is signed.
            data: The message data to sign.

        Returns:
            Signature
        """
        return private_key.sign(data, padding.PKCS1v15(), hashes.SHA256())
Beispiel #25
0
def write_key(rsa_key: RSAPrivateKey,
              path: PathLike,
              password: Optional[str] = None) -> None:
    try:
        encryption_algorithm = BestAvailableEncryption(password.encode())
    except AttributeError:
        encryption_algorithm = NoEncryption()
    pem = rsa_key.private_bytes(Encoding.PEM, PrivateFormat.PKCS8,
                                encryption_algorithm)
    with open(path, 'wb') as file:
        file.write(pem)
Beispiel #26
0
def dump_private_key(key: rsa.RSAPrivateKey) -> bytes:
    """Dump a private key to PEM format (text)

    :param key: The Private Key objec to dump
    :return: The bytes of the private key, as PEM
    """
    return key.private_bytes(
        encoding=serialization.Encoding.PEM,
        format=serialization.PrivateFormat.PKCS8,
        encryption_algorithm=serialization.NoEncryption(),
    )
Beispiel #27
0
def rsa_decrypt(enc_short_message: bytes, private_key: rsa.RSAPrivateKey) -> bytes:
    """ decrypt Optimal Asymmetric Encryption Padding (OAEP)"""
    hash_algorithm = hashes.SHA512 if private_key.key_size >= 2048 else hashes.SHA256
    return private_key.decrypt(
        ciphertext=enc_short_message,
        padding=padding.OAEP(
            mgf=padding.MGF1(algorithm=hash_algorithm()),
            algorithm=hash_algorithm(),
            label=None
        )
    )
Beispiel #28
0
def get_private_key_pem(private_key: RSAPrivateKey) -> bytes:
    """
    Returns private key PEM file bytes.
    :param private_key: RSPrivateKey
    :return: bytes
    """
    return private_key.private_bytes(  # type: ignore
        encoding=serialization.Encoding.PEM,
        format=serialization.PrivateFormat.PKCS8,
        encryption_algorithm=serialization.NoEncryption(),
    )
def _save_key(namespace: str, identifier: str, key_pair: rsa.RSAPrivateKey):
    key_dir = pathlib.Path(KEY_STORE_PATH) / namespace / identifier
    os.makedirs(key_dir)

    with open(key_dir / 'id_rsa', 'wb') as f:
        key_binary = key_pair.private_bytes(
            encoding=serialization.Encoding.PEM,
            format=serialization.PrivateFormat.TraditionalOpenSSL,
            encryption_algorithm=serialization.NoEncryption()
        )

        f.write(key_binary)

    with open(key_dir / 'id_rsa.pub', 'wb') as f:
        key_binary = key_pair.public_key().public_bytes(
            encoding=serialization.Encoding.PEM,
            format=serialization.PublicFormat.SubjectPublicKeyInfo
        )

        f.write(key_binary)
Beispiel #30
0
def key_to_bytes(
    key: RSAPrivateKey,
    passphrase: Optional[str] = None,
):
    kwargs = {"encryption_algorithm": serialization.NoEncryption()}
    if passphrase is not None:
        kwargs["encryption_algorithm"] = serialization.BestAvailableEncryption(
            passphrase.encode())
    return key.private_bytes(
        encoding=serialization.Encoding.PEM,
        format=serialization.PrivateFormat.TraditionalOpenSSL,
        **kwargs,
    )
Beispiel #31
0
    def private_key(self, private_key: rsa.RSAPrivateKey):
        if self._password is not None:
            enc = serialization.BestAvailableEncryption(self._password)
        else:
            enc = serialization.NoEncryption()

        key_bytes = private_key.private_bytes(
            encoding=serialization.Encoding.PEM,
            format=serialization.PrivateFormat.PKCS8,
            encryption_algorithm=enc)

        with open(os.path.join(self._key_path), 'wb') as fd:
            fd.write(key_bytes)
Beispiel #32
0
 def attack_pubkey_deception_jwk(self,
                                 pk: RSAPrivateKey,
                                 kid: str,
                                 jwt: TestJWT = None):
     if jwt is None:
         jwt = self.init_token()
     pubkey: RSAPublicKey = pk.public_key()
     jwk = utils.rsa_pubkey_to_jwk(pem_file=None, key_id=kid, pubkey=pubkey)
     jwt.header['jwk'] = jwk
     jwt.header['jwk']['use'] = "sig"
     del (jwt.header['jwk']['alg'])
     self.payloads['attack_pubkey_deception_jwk'] = utils.force_unicode(
         jwt.build_token(pk))
Beispiel #33
0
def _key_to_str(key_object: rsa.RSAPrivateKey) -> str:
    """ Converts a private key object to a string """
    pem = key_object.private_bytes(
        encoding=serialization.Encoding.PEM,
        format=serialization.PrivateFormat.TraditionalOpenSSL,
        encryption_algorithm=serialization.NoEncryption())

    key_str = pem.decode()  # type: str
    key_str = key_str[len(_PRIVATE_BEGIN_TAG):]  # remove being tag
    key_str = key_str[:-(len(_PRIVATE_END_TAG) + 1)]  # remove end tag
    key_str = key_str.replace("\n", "")  # remove new lines

    return key_str
Beispiel #34
0
def serialize_privkey(private_key: rsa.RSAPrivateKey) -> bytes:
    """
    Serialize an RSA private into the DER format.
    """
    return private_key.private_bytes(serialization.Encoding.DER,
            serialization.PrivateFormat.PKCS8, serialization.NoEncryption())