Beispiel #1
0
    def to_dict(self):
        if not self.is_public():
            public_key = self.prepared_key.get_verifying_key()
        else:
            public_key = self.prepared_key

        crv = {
            ecdsa.curves.NIST256p: 'P-256',
            ecdsa.curves.NIST384p: 'P-384',
            ecdsa.curves.NIST521p: 'P-521',
        }[self.prepared_key.curve]

        # Calculate the key size in bytes. Section 6.2.1.2 and 6.2.1.3 of
        # RFC7518 prescribes that the 'x', 'y' and 'd' parameters of the curve
        # points must be encoded as octed-strings of this length.
        key_size = self.prepared_key.curve.baselen

        data = {
            'alg': self._algorithm,
            'kty': 'EC',
            'crv': crv,
            'x': long_to_base64(public_key.pubkey.point.x(), size=key_size),
            'y': long_to_base64(public_key.pubkey.point.y(), size=key_size),
        }

        if not self.is_public():
            data['d'] = long_to_base64(
                self.prepared_key.privkey.secret_multiplier, size=key_size)

        return data
Beispiel #2
0
    def to_dict(self):
        if not self.is_public():
            public_key = self.prepared_key.get_verifying_key()
        else:
            public_key = self.prepared_key

        crv = {
            ecdsa.curves.NIST256p: 'P-256',
            ecdsa.curves.NIST384p: 'P-384',
            ecdsa.curves.NIST521p: 'P-521',
        }[self.prepared_key.curve]

        # Calculate the key size in bytes. Section 6.2.1.2 and 6.2.1.3 of
        # RFC7518 prescribes that the 'x', 'y' and 'd' parameters of the curve
        # points must be encoded as octed-strings of this length.
        key_size = self.prepared_key.curve.baselen

        data = {
            'alg': self._algorithm,
            'kty': 'EC',
            'crv': crv,
            'x': long_to_base64(public_key.pubkey.point.x(), size=key_size),
            'y': long_to_base64(public_key.pubkey.point.y(), size=key_size),
        }

        if not self.is_public():
            data['d'] = long_to_base64(
                self.prepared_key.privkey.secret_multiplier,
                size=key_size
            )

        return data
Beispiel #3
0
    def to_dict(self):
        if not self.is_public():
            public_key = self.prepared_key.public_key()
        else:
            public_key = self.prepared_key

        crv = {
            'secp256r1': 'P-256',
            'secp384r1': 'P-384',
            'secp521r1': 'P-521',
        }[self.prepared_key.curve.name]

        # Calculate the key size in bytes. Section 6.2.1.2 and 6.2.1.3 of
        # RFC7518 prescribes that the 'x', 'y' and 'd' parameters of the curve
        # points must be encoded as octed-strings of this length.
        key_size = (self.prepared_key.curve.key_size + 7) // 8

        data = {
            'alg': self._algorithm,
            'kty': 'EC',
            'crv': crv,
            'x': long_to_base64(public_key.public_numbers().x, size=key_size),
            'y': long_to_base64(public_key.public_numbers().y, size=key_size),
        }

        if not self.is_public():
            data['d'] = long_to_base64(
                self.prepared_key.private_numbers().private_value,
                size=key_size)

        return data
    def to_dict(self):
        if not self.is_public():
            public_key = self.prepared_key.public_key()
        else:
            public_key = self.prepared_key

        crv = {
            'secp256r1': 'P-256',
            'secp384r1': 'P-384',
            'secp521r1': 'P-521',
        }[self.prepared_key.curve.name]

        # Calculate the key size in bytes. Section 6.2.1.2 and 6.2.1.3 of
        # RFC7518 prescribes that the 'x', 'y' and 'd' parameters of the curve
        # points must be encoded as octed-strings of this length.
        key_size = (self.prepared_key.curve.key_size + 7) // 8

        data = {
            'alg': self._algorithm,
            'kty': 'EC',
            'crv': crv,
            'x': long_to_base64(public_key.public_numbers().x, size=key_size),
            'y': long_to_base64(public_key.public_numbers().y, size=key_size),
        }

        if not self.is_public():
            data['d'] = long_to_base64(
                self.prepared_key.private_numbers().private_value,
                size=key_size
            )

        return data
Beispiel #5
0
    def create_jwk():
        private_key = ec.generate_private_key(ec.SECP256R1(), default_backend())
        public_key = private_key.public_key()

        pub_key = {
            'alg': 'ES256',
            'kty': 'EC',
            'crv': 'P-256',
            'use': 'sig',
            'x': long_to_base64(
                    public_key.public_numbers().x,
                    size=32
                ).decode('utf-8'),
            'y': long_to_base64(
                    public_key.public_numbers().y,
                    size=32
                ).decode('utf-8'),
            }
        priv_key = dict(pub_key)
        priv_key['d'] = long_to_base64(
                            private_key.private_numbers().private_value,
                            size=32
                        ).decode('utf-8')

        logger.debug("create_jwk()= " + json.dumps(pub_key, indent=4))
        return priv_key, pub_key
Beispiel #6
0
def gen_jwks():
    """Generate JSON Web Key Set (JWKS), exposing the public key details,
    based on the private key.

    Returns:
        dict: an RFC 7517-compliant data structure

    Refs:
        - https://tools.ietf.org/html/rfc7517 (specifying the JWKS format)
        - https://tools.ietf.org/html/rfc7518 (specifying key parameterization)
    """
    log.info("Generate JSON Web Key Set")

    public_numbers = _public_key_cryptography.public_numbers()

    # Generate Key ID parameter, see
    # https://tools.ietf.org/html/rfc7517#section-4.5
    # Make it depend on the (public) key specifics.
    fingerprint = "%s%sRSA" % (public_numbers.e, public_numbers.n)
    key_id = hashlib.sha256(fingerprint.encode('utf-8')).hexdigest()

    # `n` and `e` are Base64urlUInt-encoded values, see
    # https://tools.ietf.org/html/rfc7518#section-6.3

    return {
        'keys': [{
            'kid': key_id,
            'kty': 'RSA',
            'n': long_to_base64(public_numbers.n).decode('ascii'),
            'e': long_to_base64(public_numbers.e).decode('ascii'),
            'alg': 'RS256',
            'use': 'sig'
        }]
    }
Beispiel #7
0
def generate_ecdsa_key(kid=6, jwkey=None, pem_priv=None, pem_pub=None):
    """
    Creates a key using ECDSA algorithm
    :param kid: Customer key ID. Key ID to define key slot number in
           the key storage. Key ID must be in range 6-10
    :param jwkey: Filename of the key in JWK format to create.
           If None, JWK file will not be created
    :param pem_priv: Filename of the private key in PEM format to
           create. If None, PEM file will not be created
    :param pem_pub: Filename of the public key in PEM format to
           create. If None, PEM file will not be created
    :return:
    """
    private_key = ec.generate_private_key(ec.SECP256R1(), default_backend())
    public_key = private_key.public_key()

    key_json = {
        'alg':
        'ES256',
        'kty':
        'EC',
        'crv':
        'P-256',
        'use':
        'sig',
        'kid':
        str(kid),
        'x':
        long_to_base64(public_key.public_numbers().x, size=32).decode('utf-8'),
        'y':
        long_to_base64(public_key.public_numbers().y, size=32).decode('utf-8'),
        'd':
        long_to_base64(private_key.private_numbers().private_value,
                       size=32).decode('utf-8'),
    }
    key_str = json.dumps(key_json, indent=4)

    if jwkey:
        os.makedirs(os.path.dirname(jwkey), exist_ok=True)
        with open(jwkey, 'w') as fp:
            fp.write(key_str)
            logger.info(f'Created key in {jwkey}')

        key = ECKey(key_json, ALGORITHMS.ES256)
        if pem_priv:
            os.makedirs(os.path.dirname(pem_priv), exist_ok=True)
            with open(pem_priv, 'wb') as fp:
                fp.write(key.to_pem().strip())

        if pem_pub:
            os.makedirs(os.path.dirname(pem_pub), exist_ok=True)
            with open(pem_pub, 'wb') as fp:
                fp.write(key.public_key().to_pem().strip())

    return key_str
Beispiel #8
0
    def to_dict(self):
        if not self.is_public():
            public_key = self.prepared_key.public_key()
        else:
            public_key = self.prepared_key

        data = {
            'alg': self._algorithm,
            'kty': 'RSA',
            'n': long_to_base64(public_key.public_numbers().n),
            'e': long_to_base64(public_key.public_numbers().e),
        }

        if not self.is_public():
            data.update({
                'd':
                long_to_base64(self.prepared_key.private_numbers().d),
                'p':
                long_to_base64(self.prepared_key.private_numbers().p),
                'q':
                long_to_base64(self.prepared_key.private_numbers().q),
                'dp':
                long_to_base64(self.prepared_key.private_numbers().dmp1),
                'dq':
                long_to_base64(self.prepared_key.private_numbers().dmq1),
                'qi':
                long_to_base64(self.prepared_key.private_numbers().iqmp),
            })

        return data
Beispiel #9
0
    def to_dict(self):
        if not self.is_public():
            public_key = self.public_key()._prepared_key
        else:
            public_key = self._prepared_key

        data = {
            'alg': self._algorithm,
            'kty': 'RSA',
            'n': long_to_base64(public_key.n).decode('ASCII'),
            'e': long_to_base64(public_key.e).decode('ASCII'),
        }

        if not self.is_public():
            data.update({
                'd':
                long_to_base64(self._prepared_key.d).decode('ASCII'),
                'p':
                long_to_base64(self._prepared_key.p).decode('ASCII'),
                'q':
                long_to_base64(self._prepared_key.q).decode('ASCII'),
                'dp':
                long_to_base64(self._prepared_key.exp1).decode('ASCII'),
                'dq':
                long_to_base64(self._prepared_key.exp2).decode('ASCII'),
                'qi':
                long_to_base64(self._prepared_key.coef).decode('ASCII'),
            })

        return data
    def to_dict(self):
        data = {
            'alg': self._algorithm,
            'kty': 'RSA',
            'n': long_to_base64(self.prepared_key.n),
            'e': long_to_base64(self.prepared_key.e),
        }

        if not self.is_public():
            # Section 6.3.2 of RFC7518 prescribes that when we include the
            # optional parameters p and q, we must also include the values of
            # dp and dq, which are not readily available from PyCrypto - so we
            # calculate them. Moreover, PyCrypto stores the inverse of p
            # modulo q rather than the inverse of q modulo p, so we switch
            # p and q. As far as I can tell, this is OK - RFC7518 only
            # asserts that p is the 'first factor', but does not specify
            # what 'first' means in this case.
            dp = self.prepared_key.d % (self.prepared_key.p - 1)
            dq = self.prepared_key.d % (self.prepared_key.q - 1)
            data.update({
                'd': long_to_base64(self.prepared_key.d),
                'p': long_to_base64(self.prepared_key.q),
                'q': long_to_base64(self.prepared_key.p),
                'dp': long_to_base64(dq),
                'dq': long_to_base64(dp),
                'qi': long_to_base64(self.prepared_key.u),
            })

        return data
Beispiel #11
0
    def to_dict(self):
        if not self.is_public():
            public_key = self.public_key()._prepared_key
        else:
            public_key = self._prepared_key

        data = {
            "alg": self._algorithm,
            "kty": "RSA",
            "n": long_to_base64(public_key.n).decode("ASCII"),
            "e": long_to_base64(public_key.e).decode("ASCII"),
        }

        if not self.is_public():
            data.update({
                "d":
                long_to_base64(self._prepared_key.d).decode("ASCII"),
                "p":
                long_to_base64(self._prepared_key.p).decode("ASCII"),
                "q":
                long_to_base64(self._prepared_key.q).decode("ASCII"),
                "dp":
                long_to_base64(self._prepared_key.exp1).decode("ASCII"),
                "dq":
                long_to_base64(self._prepared_key.exp2).decode("ASCII"),
                "qi":
                long_to_base64(self._prepared_key.coef).decode("ASCII"),
            })

        return data
    def to_dict(self):
        data = {
            'alg': self._algorithm,
            'kty': 'RSA',
            'n': long_to_base64(self.prepared_key.n),
            'e': long_to_base64(self.prepared_key.e),
        }

        if not self.is_public():
            # Section 6.3.2 of RFC7518 prescribes that when we include the
            # optional parameters p and q, we must also include the values of
            # dp and dq, which are not readily available from PyCrypto - so we
            # calculate them. Moreover, PyCrypto stores the inverse of p
            # modulo q rather than the inverse of q modulo p, so we switch
            # p and q. As far as I can tell, this is OK - RFC7518 only
            # asserts that p is the 'first factor', but does not specify
            # what 'first' means in this case.
            dp = self.prepared_key.d % (self.prepared_key.p - 1)
            dq = self.prepared_key.d % (self.prepared_key.q - 1)
            data.update({
                'd': long_to_base64(self.prepared_key.d),
                'p': long_to_base64(self.prepared_key.q),
                'q': long_to_base64(self.prepared_key.p),
                'dp': long_to_base64(dq),
                'dq': long_to_base64(dp),
                'qi': long_to_base64(self.prepared_key.u),
            })

        return data
Beispiel #13
0
    def to_dict(self):
        if not self.is_public():
            public_key = self.prepared_key.get_verifying_key()
        else:
            public_key = self.prepared_key
        crv = None
        for key, value in self.CURVE_NAMES:
            if key == self.prepared_key.curve:
                crv = value
        if not crv:
            raise KeyError(f"Can't match {self.prepared_key.curve}")

        # Calculate the key size in bytes. Section 6.2.1.2 and 6.2.1.3 of
        # RFC7518 prescribes that the 'x', 'y' and 'd' parameters of the curve
        # points must be encoded as octed-strings of this length.
        key_size = self.prepared_key.curve.baselen

        data = {
            "alg":
            self._algorithm,
            "kty":
            "EC",
            "crv":
            crv,
            "x":
            long_to_base64(public_key.pubkey.point.x(),
                           size=key_size).decode("ASCII"),
            "y":
            long_to_base64(public_key.pubkey.point.y(),
                           size=key_size).decode("ASCII"),
        }

        if not self.is_public():
            data["d"] = long_to_base64(
                self.prepared_key.privkey.secret_multiplier,
                size=key_size).decode("ASCII")

        return data
Beispiel #14
0
    def to_dict(self):
        if not self.is_public():
            public_key = self.public_key()._prepared_key
        else:
            public_key = self._prepared_key

        data = {
            'alg': self._algorithm,
            'kty': 'RSA',
            'n': long_to_base64(public_key.n),
            'e': long_to_base64(public_key.e),
        }

        if not self.is_public():
            data.update({
                'd': long_to_base64(self._prepared_key.d),
                'p': long_to_base64(self._prepared_key.p),
                'q': long_to_base64(self._prepared_key.q),
                'dp': long_to_base64(self._prepared_key.exp1),
                'dq': long_to_base64(self._prepared_key.exp2),
                'qi': long_to_base64(self._prepared_key.coef),
            })

        return data
    def to_dict(self):
        if not self.is_public():
            public_key = self.prepared_key.public_key()
        else:
            public_key = self.prepared_key

        data = {
            'alg': self._algorithm,
            'kty': 'RSA',
            'n': long_to_base64(public_key.public_numbers().n),
            'e': long_to_base64(public_key.public_numbers().e),
        }

        if not self.is_public():
            data.update({
                'd': long_to_base64(self.prepared_key.private_numbers().d),
                'p': long_to_base64(self.prepared_key.private_numbers().p),
                'q': long_to_base64(self.prepared_key.private_numbers().q),
                'dp': long_to_base64(self.prepared_key.private_numbers().dmp1),
                'dq': long_to_base64(self.prepared_key.private_numbers().dmq1),
                'qi': long_to_base64(self.prepared_key.private_numbers().iqmp),
            })

        return data
Beispiel #16
0
 def test_long_to_base64(self, longdata, kwargs, b64):
     assert utils.long_to_base64(longdata, **kwargs) == b64
Beispiel #17
0
 def test_long_to_base64(self):
     assert utils.long_to_base64(0xDEADBEEF) == b'3q2-7w'
     assert utils.long_to_base64(0xCAFED00D, size=10) == b'AAAAAAAAyv7QDQ'
Beispiel #18
0
 def test_long_to_base64(self):
     assert utils.long_to_base64(0xDEADBEEF) == b'3q2-7w'
     assert utils.long_to_base64(0xCAFED00D, size=10) == b'AAAAAAAAyv7QDQ'