def checksum(self, **kwargs): """Base64-encoded HMAC signature of the parameters string The checksum is caclulated as documented at: http://monitis.com/api/api.html#checkSum - sort all request parameters alphabetically by param name - join param-value pairs in a string: param1value1param2value2... - return Base64-encoded RFC 2104-compliant HMAC signature of the constructed string using your secrect key """ try: # if a secretkey is in **kwargs, use it, and remove it secretkey = kwargs['secretkey'] del kwargs['secretkey'] except KeyError: # if the kwargs lookup fails, get secretkey elsewhere secretkey = self.secretkey or resolve_secretkey() args = kwargs.items() args.sort() param_string = '' for key, value in args: param_string += str(key) param_string += str(value) return b64encode(str(new_hmac(secretkey, param_string, sha1).digest()))
def decrypt(key, ciphertext, workload=100000): """ Decrypts `plaintext` with `key` using AES-128, an HMAC to verify integrity, and PBKDF2 to stretch the given key. The exact algorithm is specified in the module docstring. """ assert len(ciphertext) % 16 == 0, "Ciphertext must be made of full 16-byte blocks." assert len(ciphertext) >= 32, """ Ciphertext must be at least 32 bytes long (16 byte salt + 16 byte block). To encrypt or decrypt single blocks use `AES(key).decrypt_block(ciphertext)`. """ if isinstance(key, str): key = key.encode('utf-8') hmac, ciphertext = ciphertext[:HMAC_SIZE], ciphertext[HMAC_SIZE:] salt, ciphertext = ciphertext[:SALT_SIZE], ciphertext[SALT_SIZE:] key, hmac_key, iv = get_key_iv(key, salt, workload) expected_hmac = new_hmac(hmac_key, salt + ciphertext, 'sha256').digest() assert compare_digest(hmac, expected_hmac), 'Ciphertext corrupted or tampered.' return AES(key).decrypt_cbc(ciphertext, iv)
def decrypt(key, ciphertext, workload=100000): """ Decrypts `plaintext` with `key` using AES-128, an HMAC to verify integrity, and PBKDF2 to stretch the given key. The exact algorithm is specified in the module docstring. """ assert len(ciphertext ) % 16 == 0, "Ciphertext must be made of full 16-byte blocks." assert len(ciphertext) >= 32, """ Ciphertext must be at least 32 bytes long (16 byte salt + 16 byte block). To encrypt or decrypt single blocks use `AES(key).decrypt_block(ciphertext)`. """ if isinstance(key, str): key = key.encode('utf-8') hmac, ciphertext = ciphertext[:HMAC_SIZE], ciphertext[HMAC_SIZE:] salt, ciphertext = ciphertext[:SALT_SIZE], ciphertext[SALT_SIZE:] key, hmac_key, iv = get_key_iv(key, salt, workload) expected_hmac = new_hmac(hmac_key, salt + ciphertext, 'sha256').digest() assert compare_digest(hmac, expected_hmac), 'Ciphertext corrupted or tampered.' return AES(key).decrypt_cbc(ciphertext, iv)
def POST(self): data = web_input() keys = data.keys() if 'I' in keys and 'A' in keys: login.salt = urandom(4) login.A = int(data.A) login.b = randint(0, login.N - 1) B = pow(login.g, login.b, login.N) login.u = getrandbits(128) return str({'salt': login.salt, 'B': B, 'u': login.u}) elif 'hmac' in keys: with open('/usr/share/dict/words') as f: words = f.read().split('\n') for guess in words: xh = sha256(login.salt + guess.encode()).hexdigest() x = int(xh, 16) v = pow(login.g, x, login.N) base = login.A * pow(v, login.u, login.N) S = pow(base, login.b, login.N) K = sha256(str(S).encode()).digest() print(f'Server computed K = {K[:20]}...') raw_hmac = new_hmac(K, login.salt, sha256) server_hmac = raw_hmac.hexdigest() if compare_digest(data.hmac, server_hmac): return dumps({'password': guess})
def _prepare_request(self, url, params=None): r""" Prepare a request for a call to the Public Transport Victoria API. :param url: The url to sign (relative to the base URL, e.g., `/v3/routes`) :param params: [optional] The parameters to supply to the API call. :param user_id: [optional] The PTV API user ID. If `None` is supplied then this will be retrieved from the `PTV_USER_ID` environment variable. :param api_key: [optional] The PTV API key associated with the `user_id`. If `None` is supplied then this will be retrieved from the `PTV_API_KEY` environment variable. :returns: An absolute URL and a dictionary containing any existing params, as well as the required user id and signature. """ url = "/v{:.0f}/{}".format(self.API_VERSION, url.lstrip(" /")) params = params.copy() if params is not None else {} params["devid"] = self._user_id hashed = new_hmac( self._api_key, "{}?{}".format(url, requests.PreparedRequest._encode_params(params)), sha1) params["signature"] = hashed.hexdigest() return (self.API_URL + url, params)
def p37() -> str: server = Server() base_url = 'http://0.0.0.0:8080/login' N = DiffieHellman.default_p I, P = '*****@*****.**', 'abhorrentaardvark' A = 0 # same as N, N^2 etc since they're in the same equivalence class mod N print('Sending I and A to server...') try: args = '?I={}&A={}'.format(I, A) response = post(base_url + args) response_content = eval(response.content) except ConnectionError: response_content = server.get_client_ids(I, A) salt, B = response_content.get('salt'), response_content.get('B') print(f'Server responded with salt = {salt} and B = {str(B)[:20]}...') K = sha256(b'0').digest() print(f'Client computed K = {K[:20]}...') client_hmac = new_hmac(K, salt, sha256).hexdigest() print('Sending HMAC to server...') try: args = '?hmac={}'.format(client_hmac) response = post(base_url + args) except ConnectionError: response = server.check_hmac(client_hmac) if response.status_code != 200: return 'Server responded with "403 Forbidden"' return 'Server responded with "200 OK"'
def POST(self): data = web_input() keys = data.keys() if 'I' in keys and 'A' in keys: login.salt = getrandbits(32) login.A = int(data.A) login.b = randint(0, login.N-1) B = pow(login.g, login.b, login.N) login.u = getrandbits(128) return dumps({'salt': login.salt, 'B': B, 'u': login.u}) elif 'hmac' in keys: with open('/usr/share/dict/words') as f: words = f.read().split('\n') for guess in words: xH = sha256(str(login.salt) + guess).hexdigest() x = int(xH, 16) v = pow(login.g, x, login.N) base = login.A * pow(v, login.u, login.N) S = pow(base, login.b, login.N) K = sha256(str(S)).hexdigest() print 'Server computed K = {}...'.format(K[:20]) raw_hmac = new_hmac(K, str(login.salt), sha256) server_hmac = raw_hmac.hexdigest() client_hmac = str(data.hmac) if compare_digest(client_hmac, server_hmac): return dumps({'password': guess})
def check_hmac(self, client_hmac: str) -> Response: raw_hmac = new_hmac(self.K, self.salt, sha256) server_hmac = raw_hmac.hexdigest() mac_equal = compare_digest(client_hmac, server_hmac) if mac_equal: return self.Response(200) else: return self.Response(403)
def check_hmac(self, client_hmac): class Response: def __init__(self, code): self.status_code = code raw_hmac = new_hmac(self.K, str(self.salt), sha256) server_hmac = raw_hmac.hexdigest() mac_equal = compare_digest(client_hmac, server_hmac) if mac_equal: return Response(200) else: return Response(403)
def encrypt(key, plaintext, workload=100000): if isinstance(key, str): key = key.encode('utf-8') if isinstance(plaintext, str): plaintext = plaintext.encode('utf-8') salt = os.urandom(SALT_SIZE) key, hmac_key, iv = get_key_iv(key, salt, workload) ciphertext = AES(key).encrypt_cbc(plaintext, iv) hmac = new_hmac(hmac_key, salt + ciphertext, 'sha256').digest() assert len(hmac) == HMAC_SIZE return hmac + salt + ciphertext
def sinch_api_request( # IGNORE:too-many-arguments self, api_subdomain, path, data=None, method=None, authorization_scheme='basic'): request = Request('%s%s' % (self.url_prefix_template % api_subdomain, path)) request.add_header('X-Timestamp', '%sZ' % datetime.utcnow().isoformat()) # TODO: important note about method before auth if method: request.get_method = lambda: method if data is not None: request.data = dumps(data) request.add_header('Content-type', 'application/json') if authorization_scheme == 'basic': request.add_header('Authorization', self.cached_basic_authorization) elif authorization_scheme == 'public': request.add_header('Authorization', self.cached_public_authorization) elif authorization_scheme == 'user': request.add_header('Authorization', self.cached_user_authorization) elif authorization_scheme == 'instance': request.add_header( 'Authorization', 'Instance %s:%s' % (self.cached_instance_authorization['id'], b64encode( new_hmac(b64decode( self.cached_instance_authorization['secret']), msg=unicode( self._form_string_to_sign( path, request, self._generate_content_md5( request.data))), digestmod=sha256).digest()))) else: # TODO: exception about unknown auth scheme pass response = urlopen(request).read() if response: return loads(response)
def checksum(**kwargs): """Base64-encoded HMAC signature of the parameters string The checksum is caclulated as documented at: http://monitis.com/api/api.html#checkSum """ # remove secretkey from kwargs, lookup if missing secretkey = kwargs.pop('secretkey', resolve_secretkey()) # sort the args, and concatenate them param_string = ''.join([''.join([str(x), str(y)]) for x, y in sorted(kwargs.items())]) return b64encode(str(new_hmac(secretkey, param_string, sha1).digest()))
def p36(): server = Server() base_url = 'http://0.0.0.0:8080/login' N = DiffieHellman.default_p g, k = 2, 3 I, P = '*****@*****.**', 'abhorrentaardvark' a = randint(0, N - 1) A = pow(g, a, N) print 'Sending I and A to server...' try: args = '?I={}&A={}'.format(I, A) response = post(base_url + args) response_content = loads(response.content) except ConnectionError: response_content = server.get_client_ids(I, A) salt, B = response_content.get('salt'), response_content.get('B') print 'Server responded with salt = {} and B = {}...'.format( salt, str(B)[:20]) uH = sha256(str(A) + str(B)).hexdigest() u = int(uH, 16) xH = sha256(str(salt) + str(P)).hexdigest() x = int(xH, 16) base = B - k * pow(g, x, N) exp = a + u * x S = pow(base, exp, N) K = sha256(str(S)).hexdigest() print 'Client computed K = {}...'.format(K[:20]) client_hmac = new_hmac(K, str(salt), sha256).hexdigest() print 'Sending HMAC to server...' try: args = '?hmac={}'.format(client_hmac) response = post(base_url + args) except ConnectionError: response = server.check_hmac(client_hmac) if response.status_code != 200: return 'Server responded with "403 Forbidden"' return 'Server responded with "200 OK"'
def encrypt(key, data, n=100000): if isinstance(key, str): key = key.encode('utf-8') if isinstance(data, str): data = data.encode('utf-8') salt = os.urandom(16) t = pbkdf2_hmac('sha256', key, salt, n, 16 * 3) key = t[:16] hmacKey = t[:16] iv = t[:16] data = AES128(key).CBCEnc(data, iv) return new_hmac(hmacKey, salt + data, 'sha256').digest() + salt + data
def hmac_openssl_sha256(message: bytes, key: bytes) -> bytes: """ Peudo random function for key and bitmask generation This functions wraps a pseudo random function in a way that it takes a byte-sequence as an argument and returns a value which can be used for further generation of keys. Args: message: Byte-sequence to be hashed key: key to be used Returns: HMAC-sha256 hash """ return new_hmac(key=key, msg=message, digestmod=sha256).digest()
def get_code(secret, value, length, hash_algorithm): # Given the OTP secret, value, length, and hash algorithm, return the OTP # code code_length = _digits_mod[length] if not isinstance(value, bytes): value = value.to_bytes(8, "big") digest = new_hmac(secret, value, hash_algorithm.value).digest() offset = digest[-1] & 0xf code = int.from_bytes(digest[offset:offset + 4], "big") code &= 0x7FFFFFFF code %= code_length return str(code).zfill(length)
def check_hmac(self, client_hmac: str) -> Dict[str, str]: with open('/usr/share/dict/words') as f: words = f.read().split('\n') for guess in words: xh = sha256(self.salt + guess.encode()).hexdigest() x = int(xh, 16) v = pow(Server.g, x, Server.N) base = self.A * pow(v, self.u, Server.N) S = pow(base, self.b, Server.N) K = sha256(str(S).encode()).digest() raw_hmac = new_hmac(K, self.salt, sha256) server_hmac = raw_hmac.hexdigest() if compare_digest(client_hmac, server_hmac): return {'password': guess}
def encrypt(key, plaintext, workload=100000): """ Encrypts `plaintext` with `key` using AES-128, an HMAC to verify integrity, and PBKDF2 to stretch the given key. The exact algorithm is specified in the module docstring. """ if isinstance(key, str): key = key.encode('utf-8') if isinstance(plaintext, str): plaintext = plaintext.encode('utf-8') salt = os.urandom(SALT_SIZE) key, hmac_key, iv = get_key_iv(key, salt, workload) ciphertext = AES(key).encrypt_cbc(plaintext, iv) hmac = new_hmac(hmac_key, salt + ciphertext, 'sha256').digest() assert len(hmac) == HMAC_SIZE return hmac + salt + ciphertext
def __call__(self, request): if not self.keystore.decoded: self.decode() timestamp = str(time()) message = (timestamp + request.method + request.path_url).encode() + (request.body or b'') hmac_key = b64decode(self.secret_key) signature = new_hmac(hmac_key, message, sha256) signature_b64 = b64encode(signature.digest()) request.headers.update({ 'CB-ACCESS-SIGN': signature_b64, 'CB-ACCESS-TIMESTAMP': timestamp, 'CB-ACCESS-KEY': self.api_key, 'CB-ACCESS-PASSPHRASE': self.passphrase, 'Content-Type': 'application/json' }) return request
def p38() -> str: server = Server() base_url = 'http://0.0.0.0:8080/login/simplified' N = DiffieHellman.default_p g = 2 I, P = '*****@*****.**', 'abhorrent' a = randint(0, N - 1) A = pow(g, a, N) print('Sending I and A to server...') try: args = '?I={}&A={}'.format(I, A) response = post(base_url + args) content = eval(response.content) except ConnectionError: content = server.get_client_ids(I, A) salt, B, u = content.get('salt'), content.get('B'), content.get('u') print( f'Server responded with salt = {salt} and B = {str(B)[:20]}... u = {u}' ) xh = sha256(salt + str(P).encode()).hexdigest() x = int(xh, 16) S = pow(B, (a + u * x), N) K = sha256(str(S).encode()).digest() print(f'Client computed K = {K[:20]}...') client_hmac = new_hmac(K, salt, sha256).hexdigest() print('Sending HMAC to server...') try: args = '?hmac={}'.format(client_hmac) response = post(base_url + args).json() except ConnectionError: response = server.check_hmac(client_hmac) return 'User password is {}'.format(response.get('password'))
def decrypt(key, ciphertext, workload=100000): assert len(ciphertext ) % 16 == 0, " Ciphertext must be made of full 16-byte blocks." assert len(ciphertext) >= 32, """ Ciphertext must be at least 32 bytes long (16 byte salt + 16 byte block). To encrypt or decrypt single blocks use `AES(key).decrypt_block(ciphertext)`. """ if isinstance(key, str): key = key.encode('utf-8') hmac, ciphertext = ciphertext[:HMAC_SIZE], ciphertext[HMAC_SIZE:] salt, ciphertext = ciphertext[:SALT_SIZE], ciphertext[SALT_SIZE:] key, hmac_key, iv = get_key_iv(key, salt, workload) expected_hmac = new_hmac(hmac_key, salt + ciphertext, 'sha256').digest() assert compare_digest(hmac, expected_hmac), 'Ciphertext corrupted or tampered.' return AES(key).decrypt_cbc(ciphertext, iv)
def POST(self): data = web_input() keys = data.keys() if 'I' in keys and 'A' in keys: login.salt = getrandbits(32) P = login.passwd[data.I] xH = sha256(str(login.salt) + P).hexdigest() x = int(xH, 16) v = pow(login.g, x, login.N) A = int(data.A) b = randint(0, login.N - 1) exp_term = pow(login.g, b, login.N) B = (login.k * v + exp_term) % login.N uH = sha256(str(A) + str(login.B)).hexdigest() u = int(uH, 16) base = A * pow(v, u, self.N) % self.N S = pow(base, b, login.N) login.K = sha256(str(S)).hexdigest() return dumps({'salt': login.salt, 'B': B}) elif 'hmac' in keys: raw_hmac = new_hmac(login.K, str(login.salt), sha256) server_hmac = raw_hmac.hexdigest() client_hmac = str(data.hmac) mac_equal = compare_digest(client_hmac, server_hmac) if mac_equal: ctx.status = '200 OK' return 'explicit 200' else: ctx.status = '403 Forbidden' return 'explicit 403'
def POST(self) -> str: data = web_input() keys = data.keys() if 'I' in keys and 'A' in keys: login.salt = urandom(4) P = login.passwd[data.I] xh = sha256(login.salt + P.encode()).hexdigest() x = int(xh, 16) v = pow(login.g, x, login.N) A = int(data.A) b = randint(0, Server.N - 1) exp_term = pow(login.g, b, login.N) B = (login.k * v + exp_term) % login.N uh = sha256(str(A).encode() + str(B).encode()).hexdigest() u = int(uh, 16) base = A * pow(v, u, self.N) % self.N S = pow(base, b, login.N) login.K = sha256(str(S).encode()).digest() return str({'salt': login.salt, 'B': B}) elif 'hmac' in keys: raw_hmac = new_hmac(login.K, login.salt, sha256) server_hmac = raw_hmac.hexdigest() mac_equal = compare_digest(data.hmac, server_hmac) if mac_equal: ctx.status = '200 OK' return 'explicit 200' else: ctx.status = '403 Forbidden' return 'explicit 403'
def encrypt(key, plaintext, workload=100000): """ Encrypts `plaintext` with `key` using AES-128, an HMAC to verify integrity, and PBKDF2 to stretch the given key. The exact algorithm is specified in the module docstring. """ #----------------------------------descomentar per veure com canvia la key o el missatge per cada encrypt ----------- #print(bytes2matrix(key)) #print(bytes2matrix(plaintext)) if isinstance(key, str): key = key.encode('utf-8') if isinstance(plaintext, str): plaintext = plaintext.encode('utf-8') salt = os.urandom(SALT_SIZE) key, hmac_key, iv = get_key_iv(key, salt, workload) ciphertext = AES(key).encrypt_cbc(plaintext, iv) hmac = new_hmac(hmac_key, salt + ciphertext, 'sha256').digest() assert len(hmac) == HMAC_SIZE #return hmac + salt + ciphertext return ciphertext
def verify_cra_response(response: CRAResponse, secret: Union[bytes, bytearray]): hmac = new_hmac(key=secret, msg=response.challenge.encode('utf-8'), digestmod=sha256) return response.signature.encode('utf-8') == hmac.digest()
def sinch_api_request( # IGNORE:too-many-arguments self, api_subdomain, path, data=None, method=None, authorization_scheme='basic' ): request = Request( '%s%s' % (self.url_prefix_template % api_subdomain, path) ) request.add_header( 'X-Timestamp', '%sZ' % datetime.utcnow().isoformat() ) # TODO: important note about method before auth if method: request.get_method = lambda: method if data is not None: request.data = dumps(data) request.add_header('Content-type', 'application/json') if authorization_scheme == 'basic': request.add_header( 'Authorization', self.cached_basic_authorization ) elif authorization_scheme == 'public': request.add_header( 'Authorization', self.cached_public_authorization ) elif authorization_scheme == 'user': request.add_header('Authorization', self.cached_user_authorization) elif authorization_scheme == 'instance': request.add_header( 'Authorization', 'Instance %s:%s' % ( self.cached_instance_authorization['id'], b64encode( new_hmac( b64decode( self.cached_instance_authorization['secret'] ), msg=unicode( self._form_string_to_sign( path, request, self._generate_content_md5(request.data) ) ), digestmod=sha256 ).digest() ) ) ) else: # TODO: exception about unknown auth scheme pass response = urlopen(request).read() if response: return loads(response)