Esempio n. 1
0
    def deserialize(self):
        try:
            self.x = base64_to_long(self.x)
            self.y = base64_to_long(self.y)
        except TypeError:
            raise DeSerializationNotPossible()

        self.curve = NISTEllipticCurve.by_name(self.crv)
        if self.d:
            self.d = base64_to_long(self.d)
        self.deser = True
        self.ser = False
Esempio n. 2
0
    def enc_setup(self, msg, auth_data, key=None, **kwargs):

        encrypted_key = ""
        # Generate the input parameters
        try:
            apu = b64d(kwargs["apu"])
        except KeyError:
            apu = b64d(Random.get_random_bytes(16))
        try:
            apv = b64d(kwargs["apv"])
        except KeyError:
            apv = b64d(Random.get_random_bytes(16))
        # Generate an ephemeral key pair
        curve = NISTEllipticCurve.by_name(key.crv)
        if "epk" in kwargs:
            epk = ECKey(key=kwargs["epk"], private=False)
            eprivk = ECKey(kwargs["epk"], private=True)
        else:
            (eprivk, epk) = curve.key_pair()
            # Derive the KEK and encrypt
        params = {
            "apu": b64e(apu),
            "apv": b64e(apv),
            #"epk": exportKey(epk, "EC", curve)
        }

        cek, iv = self._generate_key_and_iv(self.enc)
        if self.alg == "ECDH-ES":
            try:
                dk_len = KEYLEN[self.enc]
            except KeyError:
                raise Exception("Unknown key length for algorithm %s" %
                                self.enc)

            cek = ecdh_derive_key(curve, eprivk, key, apu, apv, self.enc,
                                  dk_len)
        elif self.alg in [
                "ECDH-ES+A128KW", "ECDH-ES+A192KW", "ECDH-ES+A256KW"
        ]:
            _pre, _post = self.alg.split("+")
            klen = int(_post[1:4])
            kek = ecdh_derive_key(curve, eprivk, key, apu, apv, _post, klen)
            encrypted_key = aes_wrap_key(kek, cek)
        else:
            raise Exception("Unsupported algorithm %s" % self.alg)

        return cek, encrypted_key, iv, params
Esempio n. 3
0
File: keyio.py Progetto: npgm/pyoidc
def ec_init(spec):
    """

    :param spec: Key specifics of the form
    {"type": "EC", "crv": "P-256", "use": ["sig"]},
    :return: A KeyBundle instance
    """
    typ = spec["type"].upper()
    _key = NISTEllipticCurve.by_name(spec["crv"])
    kb = KeyBundle(keytype=typ, keyusage=spec["use"])
    for use in spec["use"]:
        priv, pub = _key.key_pair()
        ec = ECKey(x=pub[0], y=pub[1], d=priv, crv=spec["crv"])
        ec.serialize()
        ec.use = use
        kb.append(ec)
    return kb
Esempio n. 4
0
def ec_init(spec):
    """

    :param spec: Key specifics of the form
    {"type": "EC", "crv": "P-256", "use": ["sig"]},
    :return: A KeyBundle instance
    """
    typ = spec["type"].upper()
    _key = NISTEllipticCurve.by_name(spec["crv"])
    kb = KeyBundle(keytype=typ, keyusage=spec["use"])
    for use in spec["use"]:
        priv, pub = _key.key_pair()
        ec = ECKey(x=pub[0], y=pub[1], d=priv, crv=spec["crv"])
        ec.serialize()
        ec.use = use
        kb.append(ec)
    return kb
Esempio n. 5
0
    def enc_setup(self, msg, auth_data, key=None, **kwargs):

        encrypted_key = ""
        # Generate the input parameters
        try:
            apu = b64d(kwargs["apu"])
        except KeyError:
            apu = b64d(Random.get_random_bytes(16))
        try:
            apv = b64d(kwargs["apv"])
        except KeyError:
            apv = b64d(Random.get_random_bytes(16))
        # Generate an ephemeral key pair
        curve = NISTEllipticCurve.by_name(key.crv)
        if "epk" in kwargs:
            epk = ECKey(key=kwargs["epk"], private=False)
            eprivk = ECKey(kwargs["epk"], private=True)
        else:
            (eprivk, epk) = curve.key_pair()
            # Derive the KEK and encrypt
        params = {
            "apu": b64e(apu),
            "apv": b64e(apv),
            #"epk": exportKey(epk, "EC", curve)
        }
        
        cek, iv = self._generate_key_and_iv(self.enc)
        if self.alg == "ECDH-ES":
            try:
                dk_len = KEYLEN[self.enc]
            except KeyError:
                raise Exception(
                    "Unknown key length for algorithm %s" % self.enc)
            
            cek = ecdh_derive_key(curve, eprivk, key, apu, apv, self.enc, 
                                  dk_len)
        elif self.alg in ["ECDH-ES+A128KW", "ECDH-ES+A192KW", "ECDH-ES+A256KW"]:
            _pre, _post = self.alg.split("+")
            klen = int(_post[1:4])
            kek = ecdh_derive_key(curve, eprivk, key, apu, apv, _post, klen)
            encrypted_key = aes_wrap_key(kek, cek)
        else:
            raise Exception("Unsupported algorithm %s" % self.alg)

        return cek, encrypted_key, iv, params
Esempio n. 6
0
    def deserialize(self):
        try:
            if isinstance(self.x, basestring):
                self.x = base64_to_long(self.x)
            if isinstance(self.y, basestring):
                self.y = base64_to_long(self.y)
        except TypeError:
            raise DeSerializationNotPossible()
        except ValueError as err:
            raise DeSerializationNotPossible("%s" % err)

        self.curve = NISTEllipticCurve.by_name(self.crv)
        if self.d:
            try:
                if isinstance(self.d, basestring):
                    self.d = base64_to_long(self.d)
            except ValueError as err:
                raise DeSerializationNotPossible(str(err))
Esempio n. 7
0
    def deserialize(self):
        """
        Starting with information gathered from the on-the-wire representation
        of an elliptic curve key initiate an Elliptic Curve.
        """
        try:
            if isinstance(self.x, basestring):
                self.x = base64_to_long(self.x)
            if isinstance(self.y, basestring):
                self.y = base64_to_long(self.y)
        except TypeError:
            raise DeSerializationNotPossible()
        except ValueError as err:
            raise DeSerializationNotPossible("%s" % err)

        self.curve = NISTEllipticCurve.by_name(self.crv)
        if self.d:
            try:
                if isinstance(self.d, basestring):
                    self.d = base64_to_long(self.d)
            except ValueError as err:
                raise DeSerializationNotPossible(str(err))
Esempio n. 8
0
 def deserialize(self):
     self.x = base64_to_long(self.x)
     self.y = base64_to_long(self.y)
     self.curve = NISTEllipticCurve.by_name(self.crv)
     if self.d:
         self.d = base64_to_long(self.d)
Esempio n. 9
0
def decryptKey(alg, enc, jwk, encryptedKey, header={}):
    """
    Decrypt a JWE encrypted key.
    
    @type  alg: string
    @param alg: The JWE "alg" value specifying the key management algorithm
    @type  enc: string
    @param enc: The JWE "enc" value specifying the encryption algorithm
    @type  jwk: dict
    @param jwk: The key to be used, as an unserialized JWK object
    @type  encryptedKey: bytes
    @param encryptedKey: The key to decrypt
    @type  header: dict
    @param header: A header object containing additional parameters
    @rtype: bytes
    @return: The decrypted key
    """
    key = importKey(jwk, private=True)
    if alg == "RSA1_5":
        sentinel = "fnord"
        cipher = PKCS1_v1_5.new(key)
        CEK = cipher.decrypt(encryptedKey, sentinel)
        if CEK == sentinel:
            raise Exception("Unable to unwrap key")
        return CEK
    elif alg == "RSA-OAEP":
        cipher = PKCS1_OAEP.new(key)
        CEK = cipher.decrypt(encryptedKey)
        return CEK
    elif alg in ["A128KW", "A192KW", "A256KW"]:
        return polyfills.aes_key_unwrap(key, encryptedKey)
    elif alg == "dir":
        if encryptedKey and len(encryptedKey) > 0:
            raise Exception("Direct encryption with non-empty encrypted key")
        return key
    elif alg in ["ECDH-ES", "ECDH-ES+A128KW", "ECDH-ES+A192KW", "ECDH-ES+A256KW"]:
        # Pull the input parameters 
        epk = importKey(getOrRaise(header, "epk"))
        apu = b64dec(getOrRaise(header, "apu"))
        apv = b64dec(getOrRaise(header, "apv"))
        # Select the curve
        curve = NISTEllipticCurve.byName(getOrRaise(header["epk"], "crv"))
        # Derive the KEK and decrypt
        if alg == "ECDH-ES":
            dkLen = keyLength(enc)
            return polyfills.ECDH_deriveKey(curve, key, epk, apu, apv, enc, dkLen)
        elif alg == "ECDH-ES+A128KW":
            kek = polyfills.ECDH_deriveKey(curve, key, epk, apu, apv, "A128KW", 128)
            return polyfills.aes_key_unwrap(kek, encryptedKey)
        elif alg == "ECDH-ES+A192KW":
            kek = polyfills.ECDH_deriveKey(curve, key, epk, apu, apv, "A192KW", 192)
            return polyfills.aes_key_unwrap(kek, encryptedKey)
        elif alg == "ECDH-ES+A256KW":
            kek = polyfills.ECDH_deriveKey(curve, key, epk, apu, apv, "A256KW", 256)
            return polyfills.aes_key_unwrap(kek, encryptedKey)
    elif alg in ["A128GCMKW", "A192GCMKW", "A256GCMKW"]:
        iv = b64dec(getOrRaise(header, "iv"))
        tag = b64dec(getOrRaise(header, "tag"))
        gcm = AES_GCM(bytes_to_long(key))
        return gcm.decrypt(bytes_to_long(iv), encryptedKey, bytes_to_long(tag), '')
    elif alg == "PBES2-HS256+A128KW":
        return polyfills.PBKDF_key_unwrap(key, encryptedKey, SHA256, 16, header)
    elif alg == "PBES2-HS384+A192KW":
        return polyfills.PBKDF_key_unwrap(key, encryptedKey, SHA384, 24, header)
    elif alg == "PBES2-HS512+A256KW":
        return polyfills.PBKDF_key_unwrap(key, encryptedKey, SHA512, 32, header)
    else: 
        raise Exception("Unsupported key management algorithm " + alg)
Esempio n. 10
0
def generateSenderParams(alg, enc, jwk, header={}, inCEK=None):
    """
    Generate parameters for the sender of a JWE.  This is essentially an 
    encryptKey method, except (1) in some cases, the key is specified directly
    or derived ("dir", "ECDH"), and (2) other parameters besides the encrypted
    key are generated (e.g., the IV).

    This method returns several things:
      - A random CEK (can be overridden with the inCEK parameter)
      - The encrypted CEK
      - A random IV
      - A dictionary of parameters generated within this function

    The idea is that the parameters generated within this function (e.g.,
    "epk", "p2s") should be added back to the JWE header

    @type  alg: string
    @param alg: The JWE "alg" value specifying the key management algorithm
    @type  enc: string
    @param enc: The JWE "enc" value specifying the encryption algorithm
    @type  jwk: dict
    @param jwk: The key to be used, as an unserialized JWK object
    @type  header: dict
    @param header: A header object with additional parameters
    @type  inCEK: bytes
    @param inCEK: A fixed CEK (overrides random CEK generation)
    @rtype: tuple
    @return: (CEK, encryptedKey, IV, params), the first three as bytes, 
      params as dict.  
    """
    # Generate a random key/iv for enc
    (CEK, IV) = generateKeyIV(enc)
    if inCEK:
        CEK = inCEK
    encryptedKey = ""
    params = {}
    key = importKey(jwk, private=False)

    # Encrypt key / generate params as defined by alg
    if alg == "RSA1_5":
        cipher = PKCS1_v1_5.new(key)
        encryptedKey = cipher.encrypt(CEK)
    elif alg == "RSA-OAEP":
        (CEK, IV) = generateKeyIV(enc)
        cipher = PKCS1_OAEP.new(key)
        encryptedKey = cipher.encrypt(CEK)
    elif alg in ["A128KW", "A192KW", "A256KW"]:
        encryptedKey = polyfills.aes_key_wrap(key, CEK)
    elif alg == "dir":
        CEK = key
    elif alg in ["ECDH-ES", "ECDH-ES+A128KW", "ECDH-ES+A192KW", "ECDH-ES+A256KW"]:
        # Generate the input parameters 
        apu = b64dec(header["apu"]) if "apu" in header else Random.get_random_bytes(16) 
        apv = b64dec(header["apv"]) if "apv" in header else Random.get_random_bytes(16) 
        # Generate an ephemeral key pair
        curve = NISTEllipticCurve.byName(getOrRaise(jwk, "crv"))
        if "epk" in header:
            epk = importKey(header["epk"], private=False)
            eprivk = importKey(header["epk"], private=True)
        else:
            (eprivk, epk) = curve.keyPair()
        # Derive the KEK and encrypt
        params = {
            "apu": b64enc(apu),
            "apv": b64enc(apv),
            "epk": exportKey(epk, "EC", curve)
        }
        if alg == "ECDH-ES":
            dkLen = keyLength(enc)
            CEK = polyfills.ECDH_deriveKey(curve, eprivk, key, apu, apv, enc, dkLen)
        elif alg == "ECDH-ES+A128KW":
            kek = polyfills.ECDH_deriveKey(curve, eprivk, key, apu, apv, "A128KW", 128)
            encryptedKey = polyfills.aes_key_wrap(kek, CEK)
        elif alg == "ECDH-ES+A192KW":
            kek = polyfills.ECDH_deriveKey(curve, eprivk, key, apu, apv, "A192KW", 192)
            encryptedKey = polyfills.aes_key_wrap(kek, CEK)
        elif alg == "ECDH-ES+A256KW":
            kek = polyfills.ECDH_deriveKey(curve, eprivk, key, apu, apv, "A256KW", 256)
            encryptedKey = polyfills.aes_key_wrap(kek, CEK)
    elif alg in ["A128GCMKW", "A192GCMKW", "A256GCMKW"]:
        iv = Random.get_random_bytes(12)
        gcm = AES_GCM(bytes_to_long(key))
        encryptedKey, tag = gcm.encrypt(bytes_to_long(iv), CEK, '')
        params = { "iv": b64enc(iv), "tag": b64enc(long_to_bytes(tag,16)) }
    elif alg == "PBES2-HS256+A128KW":
        (CEK, IV) = generateKeyIV(enc)
        (encryptedKey, params) = \
            polyfills.PBKDF_key_wrap( key, CEK, SHA256, 16, header )
    elif alg == "PBES2-HS384+A192KW":
        (CEK, IV) = generateKeyIV(enc)
        (encryptedKey, params) = \
            polyfills.PBKDF_key_wrap( key, CEK, SHA384, 24, header )
    elif alg == "PBES2-HS512+A256KW":
        (CEK, IV) = generateKeyIV(enc)
        (encryptedKey, params) = \
            polyfills.PBKDF_key_wrap( key, CEK, SHA512, 32, header )
    else: 
        raise Exception("Unsupported key management algorithm " + alg)
    
    return (CEK, encryptedKey, IV, params)