def _get_key(self, alg, key, p2s, p2c):
        if isinstance(key, bytes):
            plain = key
        else:
            plain = key.encode('utf8')
        salt = bytes(self.name.encode('utf8')) + b'\x00' + p2s

        if self.hashsize == 256:
            hashalg = hashes.SHA256()
        elif self.hashsize == 384:
            hashalg = hashes.SHA384()
        elif self.hashsize == 512:
            hashalg = hashes.SHA512()
        else:
            raise ValueError('Unknown Hash Size')

        kdf = PBKDF2HMAC(algorithm=hashalg,
                         length=_inbytes(self.keysize),
                         salt=salt,
                         iterations=p2c,
                         backend=self.backend)
        rk = kdf.derive(plain)
        if _bitsize(rk) != self.keysize:
            raise InvalidJWEKeyLength(self.keysize, len(rk))
        return JWK(kty="oct", use="enc", k=base64url_encode(rk))
    def unwrap(self, key, bitsize, ek, headers):
        rk = self._get_key(key, 'decrypt')

        # Implement RFC 3394 Key Unwrap - 2.2.3
        # TODO: Use cryptography once issue #1733 is resolved
        iv = 'a6a6a6a6a6a6a6a6'
        aiv = unhexlify(iv)

        r = [ek[i:i + 8] for i in range(0, len(ek), 8)]
        a = r.pop(0)
        n = len(r)
        for j in range(5, -1, -1):
            for i in range(n - 1, -1, -1):
                da = _decode_int(a)
                atr = _encode_int((da ^ ((n * j) + i + 1)), 64) + r[i]
                d = Cipher(algorithms.AES(rk),
                           modes.ECB(),
                           backend=self.backend).decryptor()
                b = d.update(atr) + d.finalize()
                a = b[:8]
                r[i] = b[-8:]

        if a != aiv:
            raise RuntimeError('Decryption Failed')

        cek = b''.join(r)
        if _bitsize(cek) != bitsize:
            raise InvalidJWEKeyLength(bitsize, _bitsize(cek))
        return cek
 def unwrap(self, key, bitsize, ek, headers):
     self._check_key(key)
     rk = key.get_op_key('decrypt')
     cek = rk.decrypt(ek, self.padfn)
     if _bitsize(cek) != bitsize:
         raise InvalidJWEKeyLength(bitsize, _bitsize(cek))
     return cek
Exemple #4
0
 def unwrap(self, key, bitsize, ek, headers):
     self._check_key(key)
     if ek != b'':
         raise ValueError('Invalid Encryption Key.')
     cek = base64url_decode(key.get_op_key('decrypt'))
     if _bitsize(cek) != bitsize:
         raise InvalidJWEKeyLength(bitsize, _bitsize(cek))
     return cek
Exemple #5
0
 def _get_key(self, key, op):
     if not isinstance(key, JWK):
         raise ValueError('key is not a JWK object')
     if key.key_type != 'oct':
         raise InvalidJWEKeyType('oct', key.key_type)
     rk = base64url_decode(key.get_op_key(op))
     if _bitsize(rk) != self.keysize:
         raise InvalidJWEKeyLength(self.keysize, _bitsize(rk))
     return rk
Exemple #6
0
    def unwrap(self, key, bitsize, ek, headers):
        rk = self._get_key(key, 'decrypt')

        if 'iv' not in headers:
            raise ValueError('Invalid Header, missing "iv" parameter')
        iv = base64url_decode(headers['iv'])
        if 'tag' not in headers:
            raise ValueError('Invalid Header, missing "tag" parameter')
        tag = base64url_decode(headers['tag'])

        cipher = Cipher(algorithms.AES(rk), modes.GCM(iv, tag),
                        backend=self.backend)
        decryptor = cipher.decryptor()
        cek = decryptor.update(ek) + decryptor.finalize()
        if _bitsize(cek) != bitsize:
            raise InvalidJWEKeyLength(bitsize, _bitsize(cek))
        return cek