def compute_response( response_key_nt: bytes, response_key_lm: bytes, server_challenge: bytes, server_name: AVPairSequence, client_challenge: Optional[bytes] = None, time: Optional[bytes] = None ) -> Tuple[NTLMv2Response, bytes, bytes]: """ [MS-NLMP]: NTLM v2 Authentication https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-nlmp/5e550938-91d4-459f-b67d-75d70009e3f3 :param response_key_nt: The result of a call to `NTOWFv2`. :param response_key_lm: The result of a call to `LMOWFv2`. :param server_challenge: An 8-byte challenge generated by the server. :param server_name: A sequence of `AVPair` structures. :param client_challenge: An 8-byte challenge generated by the client. :param time: A byte representation of a FILETIME timestamp. :return: """ client_challenge = client_challenge if client_challenge is not None else token_bytes(nbytes=8) if len(client_challenge) != 8: # TODO: Use proper exception. raise ValueError ntlm_v2_client_challenge = NTLMv2ClientChallenge( time_stamp=time if time is not None else datetime_to_filetime(datetime.now()), challenge_from_client=client_challenge, av_pairs=server_name ) temp = bytes(ntlm_v2_client_challenge) nt_proof_str: bytes = compute_net_ntlm_v2_hash( key=response_key_nt, server_challenge_bytes=server_challenge, client_temp_bytes=temp ) # `NtChallengeResponse`, `LmChallengeResponse`, and `SessionBaseKey`. return ( NTLMv2Response(response=nt_proof_str, ntlmv2_client_challenge=ntlm_v2_client_challenge), hmac_new( key=response_key_lm, msg=server_challenge + client_challenge, digestmod=hashlib_md5 ).digest() + client_challenge, hmac_new(key=response_key_nt, msg=nt_proof_str, digestmod=hashlib_md5).digest() )
def authenticate(self, params): param_keys = params.keys() if 'sKey' in param_keys: hmac_received = params['sKey'] elif 'logout' in param_keys: hmac_received = params['logout'] else: return None # make sure order is correct by creating a new list and putting in the available keys one by one values = '' for key in ['oid', 'mn', 'firstName', 'lastName', 'mail']: if key in param_keys: values += params[key] shared_secret = settings.SSO_SHARED_SECRET.encode(encoding='latin1') utc_now = (datetime.utcnow() - datetime(1970, 1, 1)).total_seconds() now = int(utc_now / 10) user = None for offset in [0, -1, 1, -2, 2]: values_string = values + str(now + offset) values_string = values_string.encode(encoding='latin1') hmac_calced = hmac_new(shared_secret, values_string, sha1).hexdigest() if hmac_calced == hmac_received: try: user = AuroraUser.objects.get(matriculation_number=params['mn']) except AuroraUser.DoesNotExist: try: user = AuroraUser.objects.get(oid=params['oid']) except AuroraUser.DoesNotExist: user = None return user
def poloniex_http_post(url, data, api_keys): data['nonce'] = int((time.time() * 1000) + (threading.get_ident() * 1000)) sign = hmac_new(api_keys['secret'].encode('utf-8'), urlencode(data).encode('utf-8'), sha512).hexdigest() headers = {'Key': api_keys['key'], 'Sign': sign} return http_post(url, data, headers)
def ipython_test(): user = AuroraUser.objects.get(username='******') c = Client() shared_secret = settings.SSO_SHARED_SECRET.encode(encoding='latin1') oid = '258' now = int((datetime.utcnow() - datetime(1970, 1, 1)).total_seconds() / 10) values_string = oid + user.matriculation_number + user.first_name + user.last_name + user.email + str(now) hmac_calced = hmac_new(shared_secret, values_string.encode(encoding='latin1'), sha1).hexdigest() values = {'oid': oid, 'mn': user.matriculation_number, 'firstName': user.first_name, 'lastName': user.last_name, 'mail': user.email, 'sKey': hmac_calced} # response = c.get('sso_auth_callback', values, follow=True) from django.http import QueryDict q = QueryDict('', mutable=True) for key in values.keys(): q[key] = values[key] url = 'http://localhost:8000/sso_auth_callback?' + q.urlencode() return url
def recognizer(self, audio): timestamp = str(time()) f = open(audio, "rb") example = b64encode(f.read(bytes_to_read)) f.close() string_to_sign = ("%s\n%s\n%s\n%s\n%s\n%s" % ("POST", "/v1/identify", self.key, "audio", "1", timestamp)).encode() sign = b64encode( hmac_new(bytes(self.secret), bytes(string_to_sign), sha1).digest()) data = { "access_key": self.key, "sample_bytes": bytes_to_read, "sample": example, "timestamp": timestamp, "signature": sign, "data_type": "audio", "signature_version": "1" } result = post(self.host, data).json() return result
def ipython_test(): user = AuroraUser.objects.get(username='******') c = Client() shared_secret = settings.SSO_SHARED_SECRET.encode(encoding='latin1') oid = '258' now = int( (datetime.utcnow() - datetime(1970, 1, 1)).total_seconds() / 10) values_string = oid + user.matriculation_number + user.first_name + user.last_name + user.email + str( now) hmac_calced = hmac_new(shared_secret, values_string.encode(encoding='latin1'), sha1).hexdigest() values = { 'oid': oid, 'mn': user.matriculation_number, 'firstName': user.first_name, 'lastName': user.last_name, 'mail': user.email, 'sKey': hmac_calced } # response = c.get('sso_auth_callback', values, follow=True) from django.http import QueryDict q = QueryDict('', mutable=True) for key in values.keys(): q[key] = values[key] url = 'http://localhost:8000/sso_auth_callback?' + q.urlencode() return url
def test_authenticator_missing_auth_param(self): with self.app.test_client() as c: response = c.post('/authenticate', data={ 'username': '******', 'password': '******' }) self.assertEqual(response.headers['content-type'], 'application/json', response.data) response = json.loads(response.data) session_id = response['session_id'] secret = response['session_secret'] payload_hash = sha256('').hexdigest() now = arrow.utcnow().format("YYYYMMDDTHHmmssZ") headers = { 'content-type': '', 'host': 'localhost', 'x-woodbox-content-sha256': payload_hash, 'x-woodbox-timestamp': now } signed_headers = sorted([ 'content-type', 'host', 'x-woodbox-content-sha256', 'x-woodbox-timestamp' ]) canonical_headers = [] for h in signed_headers: canonical_headers.append(h + ':' + headers[h]) canonical_headers = '\n'.join(canonical_headers).encode('utf-8') signed_headers = ';'.join(signed_headers) canonical_request = '\n'.join([ 'GET', '/test', '', canonical_headers, signed_headers, payload_hash ]) string_to_sign = '\n'.join([ 'WOODBOX-HMAC-SHA256', now, sha256(canonical_request).hexdigest() ]) signing_key = secret.encode('utf-8') signature = hmac_new(signing_key, string_to_sign, sha256).hexdigest() auth = {'Credential': session_id, 'Signature': signature} auth = [k + '=' + v for k, v in auth.iteritems()] auth = ','.join(auth) auth_str = ' '.join(['Woodbox-HMAC-SHA256', auth]) request_headers = { 'Authorization': auth_str, 'x-woodbox-content-sha256': payload_hash, 'x-woodbox-timestamp': now } response = c.get('/test', headers=request_headers) self.assertEqual(g.user_reason, 'Missing parameter: signedheaders') self.assertEqual(response.data, 'anonymous', g.user_reason)
def ser_maker(actions,bacics,users): bacics['Timestamp'] = strftime("%Y-%m-%dT%H:%M:%SZ", gmtime()) bacics['SignatureNonce'] = token_hex(16) url = url_maker(actions,bacics) f_string = "GET&%2F&"+quote(url[0].rstrip('&')) h = hmac_new((users['AccessKeySec']+'&').encode(), f_string.encode(), digestmod='SHA1') h1 = b64encode(h.digest()).decode() return [url[0] + quote('Signature') + '=' + quote(h1), url,h1]
def save(self): super(Pago, self).save() self.auth_code = u'{}'.format( hmac_new( self.pst.rif.encode('utf-8'), self.numero_documento.encode('utf-8'), ).hexdigest()) super(Pago, self).save()
def validate_auth(self, _key, _data): _payload = self.strip_hash(_data) _hash = _data[-10:] _chk_hash = bhex((hmac_new(_key,_payload,sha1)).hexdigest()[:20]) if _chk_hash == _hash: return True else: return False
def sign(dict): global Secret str2sign = sorted(dict.iteritems(), key=lambda d: d[0]) encodestring = 'GET&%2F&' + quote(urlencode(str2sign)) encodestring = b64encode( hmac_new(Secret + '&', encodestring, sha1).digest()) logging.debug(encodestring) return encodestring
def validate_auth(self, _key, _data): _payload = self.strip_hash(_data) _hash = _data[-10:] _chk_hash = bhex((hmac_new(_key, _payload, sha1)).hexdigest()[:20]) if _chk_hash == _hash: return True else: return False
def send_system(self, _packet): if _packet[:4] == 'DMRD': _packet = _packet[:11] + self._config['NETWORK_ID'] + _packet[15:] _packet += hmac_new(self._config['PASSPHRASE'],_packet,sha1).digest() self.transport.write(_packet, (self._config['TARGET_IP'], self._config['TARGET_PORT'])) # KEEP THE FOLLOWING COMMENTED OUT UNLESS YOU'RE DEBUGGING DEEPLY!!!! # logger.debug('(%s) TX Packet to OpenBridge %s:%s -- %s', self._system, self._config['TARGET_IP'], self._config['TARGET_PORT'], ahex(_packet)) else: logger.error('(%s) OpenBridge system was asked to send non DMRD packet', self._system)
def get_hmac(token): ''' Check the HMAC hexadigest signature of a token (GitHub's way of creating hashes for authentication). Arguments: - token (str) -> Secret key to use for the hash. ''' token_sig = hmac_new(token.encode('utf-8'), digestmod='sha1') return 'sha1' + token_sig.hexdigest()
def compute_net_ntlm_v2_hash(key: bytes, server_challenge_bytes: bytes, client_temp_bytes: bytes) -> bytes: """ Compute a Net-NTLMv2 hash. :param key: :param server_challenge_bytes: :param client_temp_bytes: :return: """ return hmac_new(key=key, msg=server_challenge_bytes + client_temp_bytes, digestmod=hashlib_md5).digest()
def send_to_ipsc(self, _packet): if self._local['AUTH_ENABLED']: _hash = bhex((hmac_new(self._local['AUTH_KEY'],_packet,sha1)).hexdigest()[:20]) _packet = _packet + _hash # Send to the Master if self._master['STATUS']['CONNECTED']: self.transport.write(_packet, (self._master['IP'], self._master['PORT'])) # Send to each connected Peer for peer in self._peers.keys(): if self._peers[peer]['STATUS']['CONNECTED']: self.transport.write(_packet, (self._peers[peer]['IP'], self._peers[peer]['PORT']))
def MakeMIC(self, ptk, data, wpa=False): #Compute the 1st message integrity check for a WPA 4-way handshake #ptk: The Pairwise Transient Key #data: A list of 802.1x frames with the MIC field zeroed #WPA uses md5 to compute the MIC while WPA2 uses sha1 hmacFunc = md5 if wpa else sha1 #Create the MICs using HMAC-SHA1 of data and return all computed values mic = hmac_new(ptk[0:16], data, hmacFunc).digest() return mic[:16]
def password_matches(self, login, password): # For security reasons the password is rarely passed in # en-clear. Instead the password is hashed with a seed (ph, # below). To compare the password with the one on file # (password, passed in) the system hashes the stored # version, and then does a comparison. pw = self.request.get('password', '') seed = self.request.get('seed', '') ph = self.request.get('ph', '') if ph: passhmac = ph else: # blindly try the password, even if it's set to nothing msg = login + pw + seed passhmac = hmac_new(pw, msg, sha).hexdigest() msg = login + password + seed myhmac = hmac_new(password, msg, sha).hexdigest() retval = passhmac == myhmac assert type(retval) == bool return retval
def test_authenticator_missing_header_value(self): with self.app.test_client() as c: response = c.post('/authenticate', data={'username': '******', 'password': '******'}) response = json.loads(response.data) session_id = response['session_id'] secret = response['session_secret'] c.post('/invalidate-session', data={'session_id': session_id}) payload_hash = sha256('').hexdigest() now = arrow.utcnow().format("YYYYMMDDTHHmmssZ") headers = { 'content-type': '', 'host': 'localhost', 'x-woodbox-content-sha256': payload_hash, 'x-woodbox-timestamp': now, 'x-this-value-is-missing': 'missing-in-request' } signed_headers = sorted(['x-woodbox-content-sha256', 'content-type', 'host', 'x-woodbox-timestamp', 'x-this-value-is-missing']) canonical_headers = [] for h in signed_headers: canonical_headers.append(h+':'+headers[h]) canonical_headers = '\n'.join(canonical_headers).encode('utf-8') signed_headers = ';'.join(signed_headers) canonical_request = '\n'.join(['GET', '/test', '', canonical_headers, signed_headers, payload_hash]) string_to_sign = '\n'.join(['WOODBOX-HMAC-SHA256', now, sha256(canonical_request).hexdigest()]) signing_key = secret.encode('utf-8') signature = hmac_new(signing_key, string_to_sign, sha256).hexdigest() auth = { 'Credential': session_id, 'SignedHeaders': signed_headers, 'Signature': signature } auth = [k+'='+v for k,v in auth.iteritems()] auth = ','.join(auth) auth_str = ' '.join(['Woodbox-HMAC-SHA256', auth]); request_headers = { 'Authorization': auth_str, 'x-woodbox-content-sha256': payload_hash, 'x-woodbox-timestamp': now } response = c.get('/test', headers=request_headers) self.assertEqual(g.user_reason, 'Missing headers: x-this-value-is-missing') self.assertEqual(response.data, 'anonymous', g.user_reason)
def test_authenticator_request_too_old(self): with self.app.test_client() as c: response = c.post('/authenticate', data={'username': '******', 'password': '******'}) self.assertEqual(response.headers['content-type'], 'application/json', response.data) response = json.loads(response.data) session_id = response['session_id'] secret = response['session_secret'] payload_hash = sha256('').hexdigest() now = "20150101T123456" headers = { 'content-type': '', 'host': 'localhost', 'x-woodbox-content-sha256': payload_hash, 'x-woodbox-timestamp': now } signed_headers = sorted(['content-type', 'host','x-woodbox-content-sha256','x-woodbox-timestamp']) canonical_headers = [] for h in signed_headers: canonical_headers.append(h+':'+headers[h]) canonical_headers = '\n'.join(canonical_headers).encode('utf-8') signed_headers = ';'.join(signed_headers) canonical_request = '\n'.join(['GET', '/test', '', canonical_headers, signed_headers, payload_hash]) string_to_sign = '\n'.join(['WOODBOX-HMAC-SHA256', now, sha256(canonical_request).hexdigest()]) signing_key = secret.encode('utf-8') signature = hmac_new(signing_key, string_to_sign, sha256).hexdigest() auth = { 'Credential': session_id, 'SignedHeaders': signed_headers, 'Signature': signature } auth = [k+'='+v for k,v in auth.iteritems()] auth = ','.join(auth) auth_str = ' '.join(['Woodbox-HMAC-SHA256', auth]); request_headers = { 'Authorization': auth_str, 'x-woodbox-content-sha256': payload_hash, 'x-woodbox-timestamp': now } response = c.get('/test', headers=request_headers) self.assertEqual(g.user_reason, 'Request is too old.') self.assertEqual(response.data, 'anonymous', g.user_reason)
def do_login(): print 'step: do_login() with request method - ', request.method user = None _is_authenticated = False try: if request.method == 'GET': if 'user_id' in session: user = User.get_by_id(get_user_id_from_session()) if user is None: raise print 'user %s is not existing.' % get_user_id_from_session() else: _is_authenticated = check_signin() print 'user exists' elif request.method == 'POST': #Check e-mail email = request.form['email'] if validate_email(email) == None: flash('This e-mail address is invalid.', 'error') raise user = User.get_by_id(email) if user is None: flash('This e-mail is not registered.', 'error') raise #Check password if user.verify_password(request.form['password']) == False: flash('Password is invalid!', 'error') raise session['user_id'] = email _is_authenticated = True except: session.pop('user_id', None) finally: if _is_authenticated == True: print '<authenticated>' response = make_response(redirect_common(url_for('user.myaccount'))) key_random = urandom(24) session['random_auth'] = hmac_new(key_random, get_user_id_from_session()).hexdigest() response.set_cookie('random_auth', session['random_auth']) return response else: print '<NOT authenticated>' return render_template('login.html', email = get_user_id_from_session())
def compare_secret(*args, **kwargs): if secret: digest = 'sha1={}'.format( hmac_new(str.encode(secret), request.data, hashlib.sha1).hexdigest()) if not compare_digest( digest, request.headers.get('X-Hub-Signature', '')): return make_response( jsonify({ 'error': True, 'message': 'Unauthorized request' }), 401) return f(*args, **kwargs)
def send_to_ipsc(self, _packet): if self._local['AUTH_ENABLED']: _hash = bhex((hmac_new(self._local['AUTH_KEY'], _packet, sha1)).hexdigest()[:20]) _packet = _packet + _hash # Send to the Master if self._master['STATUS']['CONNECTED']: self.transport.write(_packet, (self._master['IP'], self._master['PORT'])) # Send to each connected Peer for peer in self._peers.keys(): if self._peers[peer]['STATUS']['CONNECTED']: self.transport.write( _packet, (self._peers[peer]['IP'], self._peers[peer]['PORT']))
def authenticate(self, params): param_keys = params.keys() if 'sKey' in param_keys: hmac_received = params['sKey'] elif 'logout' in param_keys: hmac_received = params['logout'] else: logger.error("Missing parameters for authentication. Abort.") return None # make sure order is correct by creating a new list and putting in the available keys one by one values = '' for key in ['oid', 'mn', 'firstName', 'lastName', 'mail']: if key in param_keys: values += params[key] shared_secret = settings.SSO_SHARED_SECRET.encode(encoding='latin1') utc_now = (datetime.utcnow() - datetime(1970, 1, 1)).total_seconds() now = int(utc_now / 10) user = None for offset in [0, -1, 1, -2, 2]: values_string = values + str(now + offset) values_string = values_string.encode(encoding='latin1') hmac_calced = hmac_new(shared_secret, values_string, sha1).hexdigest() if hmac_calced == hmac_received: try: user = AuroraUser.objects.get( matriculation_number=params['mn']) except AuroraUser.DoesNotExist: logger.debug("User with Matr.Nr.: %s not found" % params['mn']) try: user = AuroraUser.objects.get(oid=params['oid']) except AuroraUser.DoesNotExist: logger.debug("User with OID:%s not found" % params['oid']) user = None if user is None: logger.debug("HMAC doesn't match. Abort authentication.") return user
def ensure_strong_key(key): """ Translates a given key to a computed strong key of length 320 bit suitable for encryption. >>> from wheezy.security.crypto.comp import n >>> k = ensure_strong_key(b('')) >>> len(k) 40 >>> n(b64encode(k)) '+9sdGxiqbAgyS31ktx+3Y3BpDh1fA7dyIanFu+fzE/Lc5EaX+NQGsA==' >>> n(b64encode(ensure_strong_key(b('abc')))) 'zEfjwKoMKYRFRHbQYRCMCxEBd66sLMHe/H6umZFFQMixhLcp8jfwGQ==' """ hmac = hmac_new(key, digestmod=sha1) key = hmac.digest() hmac.update(key) return key + hmac.digest()
def test_sso(self): c = Client() shared_secret = settings.SSO_SHARED_SECRET.encode(encoding='latin1') oid = '258' user = self.users[0] now = int((datetime.utcnow() - datetime(1970, 1, 1)).total_seconds() / 10) values_string = oid + user.matriculation_number + user.first_name + user.last_name + user.email + str(now) hmac_calced = hmac_new(shared_secret, values_string.encode(encoding='latin1'), sha1).hexdigest() values = {'oid': oid, 'mn': user.matriculation_number, 'firstName': user.first_name, 'lastName': user.last_name, 'mail': user.email, 'sKey': hmac_calced} response = c.get('sso_auth_callback', values, follow=True)
def auth_flow(self, request: Request) -> Generator[Request, Response, None]: """ Update the request. :param request: A request to be updated with OAuth parameters. """ oauth_parameters = self.oauth_base_parameters hmac_message_query_string = str( QueryParams( sorted( chain( QueryParams(request.url.query).items(), (QueryParams(request.content.decode()).items() if request.method == 'POST' and request.headers.get('content-type') == 'application/x-www-form-urlencoded' else []), oauth_parameters.items(), )))) oauth_parameters['oauth_signature'] = b64encode(s=hmac_new( key='&'.join([ quote(string=self.consumer_secret, safe=b"~"), quote(string=self.oauth_access_token_secret or '', safe=b"~") ]).encode(), msg='&'.join( quote(string=element, safe=b'~') for element in (request.method.upper(), f'{request.url.scheme}://{request.url.host}{request.url.path}', hmac_message_query_string)).encode(), digestmod=sha1).digest()).decode() # The OAuth parameters are added to the query. request.url = URL(url=request.url, params=oauth_parameters) # request.headers['Authorization'] = 'OAuth ' + ', '.join([ # f'{key}="{value}"' for key, value in oauth_parameters.items()] # ) yield request
def APIConnect(self,method,params,uri,eid=None): """Encapsulates all the API encoding, starts the HTTP request, returns deferred eid is used to pass Data along the chain to be used later """ encoded_string = '' if params: for key, value in sorted(params.iteritems(),key=lambda (key,value,) : key ): encoded_string += str(key) + '=' + str(value) + '&' encoded_string = encoded_string[:-1] url = uri + '?' + encoded_string else: url = uri self.nonce += 1 if method == 'POST': md5_encoded_query_string = md5(encoded_string).hexdigest() else: md5_encoded_query_string = md5('').hexdigest() hmac_data = method + '#' + url + '#' + self.api_key + '#' + str(self.nonce) + '#' + md5_encoded_query_string hmac_signed = hmac_new(self.api_secret,digestmod=sha256, msg=hmac_data).hexdigest() header = {'content-type':['application/x-www-form-urlencoded;charset=utf-8']} header[b"X-API-KEY"] = [self.api_key] header[b"X-API-NONCE"] = [b"%d"%self.nonce] header[b"X-API-SIGNATURE"] = [hmac_signed] h = Headers({}) for k,v in header.items(): h.setRawHeaders(k,v) bodyProducer = None if method == 'POST': bodyProducer = StringProducer(encoded_string) d = self.agent.request(method,url,headers=h,bodyProducer=bodyProducer) d.addCallback(self.APIResponse,eid=eid) def Error(result): print "API-Connect-Error",result d.addErrback(Error) return d
def __init__(self, max_age=900, salt='', digestmod=None, cypher=aes128, options=None): self.max_age = max_age if not digestmod: warn('Ticket: digestmod is not specified, fallback to sha1', stacklevel=2) digestmod = sha1 options = options or {} key = b(salt + options.get('CRYPTO_VALIDATION_KEY', '')) key = ensure_strong_key(key) self.hmac = hmac_new(key, digestmod=digestmod) self.digest_size = digest_size(digestmod) if cypher: key = b(salt + options.get('CRYPTO_ENCRYPTION_KEY', '')) key = ensure_strong_key(key) self.cypher = cypher(key) self.block_size = block_size(self.cypher()) else: self.cypher = None warn('Ticket: cypher not available', stacklevel=2)
def test_mac(self): pfx, tail = PFX().decode(self.pfx_raw) self.assertSequenceEqual(tail, b"") _, outer_safe_contents = pfx["authSafe"]["content"].defined mac_data = pfx["macData"] mac_key = gost34112012_pbkdf2( password=self.password.encode('utf-8'), salt=bytes(mac_data["macSalt"]), iterations=int(mac_data["iterations"]), dklen=96, )[-32:] # mac_key = hexdec("cadbfbf3bceaa9b79f651508fac5abbeb4a13d0bd0e1876bd3c3efb2112128a5") self.assertSequenceEqual( hmac_new( key=mac_key, msg=SafeContents(outer_safe_contents).encode(), digestmod=GOST34112012512, ).digest(), bytes(mac_data["mac"]["digest"]), )
def _api_query(self, protection=None, path_dict=None, options=None): """ Queries Bittrex :param request_url: fully-formed URL to request :type options: dict :return: JSON response from Bittrex :rtype : dict """ if not options: options = {} if self.api_version not in path_dict: raise Exception( 'method call not available under API version {}'.format( self.api_version)) request_url = BASE_URL_V2_0 if self.api_version == API_V2_0 else BASE_URL_V1_1 request_url = request_url.format(path=path_dict[self.api_version]) nonce = str(int(time() * 1000)) if protection != PROTECTION_PUB: request_url = "{0}apikey={1}&nonce={2}&".format( request_url, self.api_key, nonce) request_url += urlencode(options) try: apisign = hmac_new(self.api_secret.encode(), request_url.encode(), sha512).hexdigest() return self.dispatch(request_url, apisign) except: return { 'success': False, 'message': 'NO_API_RESPONSE', 'result': None }
def decrypt_cipher_string(key_enc: bytes, key_mac: bytes, cipher_string: CipherString) -> bytes: # we only support enc_type == 2 # i.e: AesCbc256_HmacSha256_B64 (jslib/src/enums/encryptionType.ts) assert(cipher_string.enc_type == 2) # verify the MAC mac_data = cipher_string.iv + cipher_string.data r = hmac_new(key_mac, mac_data, sha256) assert(cipher_string.mac == r.digest()) # decrypt the content c = AES.new(key_enc, AES.MODE_CBC, cipher_string.iv) plaintext = c.decrypt(cipher_string.data) # remove PKCS#7 padding from payload, see RFC 5652 # https://tools.ietf.org/html/rfc5652#section-6.3 pad_len = plaintext[-1] padding = bytes([ pad_len ] * pad_len) if plaintext[-pad_len:] == padding: plaintext = plaintext[:-pad_len] return plaintext
def rfc6979_raw(prv, m, hasher=default_hasher): hash_size = len(m) prv_and_m = int2octets(prv) + bits2octets(m) v = b'\x01' * hash_size k = b'\x00' * hash_size k = hmac_new(k, v + b'\x00' + prv_and_m, hasher).digest() v = hmac_new(k, v, hasher).digest() k = hmac_new(k, v + b'\x01' + prv_and_m, hasher).digest() v = hmac_new(k, v, hasher).digest() while True: t = b'' while len(t) * 8 < qlen: v = hmac_new(k, v, hasher).digest() t = t + v nonce = bits2int(t) if nonce >= 1 and nonce < ec.order: # here it should be checked that nonce do not yields a invalid signature # but then I should put the signature generation here return nonce k = hmac_new(k, v + b'\x00', hasher).digest() v = hmac_new(k, v, hasher).digest()
def MakePTK(self, pmk, A, B): #Pseudo-random function for generation of #the pairwise transient key (PTK) #key: The PMK #A: b'Pairwise key expansion' #B: The apMac, staMac, aNonce, and sNonce concatenated # like mac1 mac2 nonce1 nonce2 # such that mac1 < mac2 and nonce1 < nonce2 #return: The ptk #Number of bytes in the PTK nByte = 48 i = 0 R = b'' #Each iteration produces 160-bit value and 512 bits are required while (i <= ((nByte * 8 + 159) / 160)): hmacsha1 = hmac_new(pmk, A + chr(0x00).encode() + B + chr(i).encode(), sha1) R = R + hmacsha1.digest() i += 1 return R[0:nByte]
def test_sso(self): c = Client() shared_secret = settings.SSO_SHARED_SECRET.encode(encoding='latin1') oid = '258' user = self.users[0] now = int( (datetime.utcnow() - datetime(1970, 1, 1)).total_seconds() / 10) values_string = oid + user.matriculation_number + user.first_name + user.last_name + user.email + str( now) hmac_calced = hmac_new(shared_secret, values_string.encode(encoding='latin1'), sha1).hexdigest() values = { 'oid': oid, 'mn': user.matriculation_number, 'firstName': user.first_name, 'lastName': user.last_name, 'mail': user.email, 'sKey': hmac_calced } response = c.get('sso_auth_callback', values, follow=True)
def datagramReceived(self, _packet, _sockaddr): # Keep This Line Commented Unless HEAVILY Debugging! #logger.debug('(%s) RX packet from %s -- %s', self._system, _sockaddr, ahex(_packet)) if _packet[:4] == DMRD: # DMRData -- encapsulated DMR data frame _data = _packet[:53] _hash = _packet[53:] _ckhs = hmac_new(self._config['PASSPHRASE'],_data,sha1).digest() if compare_digest(_hash, _ckhs) and _sockaddr == self._config['TARGET_SOCK']: _peer_id = _data[11:15] _seq = _data[4] _rf_src = _data[5:8] _dst_id = _data[8:11] _bits = _data[15] _slot = 2 if (_bits & 0x80) else 1 #_call_type = 'unit' if (_bits & 0x40) else 'group' if _bits & 0x40: _call_type = 'unit' elif (_bits & 0x23) == 0x23: _call_type = 'vcsbk' else: _call_type = 'group' _frame_type = (_bits & 0x30) >> 4 _dtype_vseq = (_bits & 0xF) # data, 1=voice header, 2=voice terminator; voice, 0=burst A ... 5=burst F _stream_id = _data[16:20] #logger.debug('(%s) DMRD - Seqence: %s, RF Source: %s, Destination ID: %s', self._system, int_id(_seq), int_id(_rf_src), int_id(_dst_id)) # Sanity check for OpenBridge -- all calls must be on Slot 1 for Brandmeister or DMR+. Other HBlinks can process timeslot on OPB if the flag is set if _slot != 1 and not self._config['BOTH_SLOTS'] and not _call_type == 'unit': logger.error('(%s) OpenBridge packet discarded because it was not received on slot 1. SID: %s, TGID %s', self._system, int_id(_rf_src), int_id(_dst_id)) return # ACL Processing if self._CONFIG['GLOBAL']['USE_ACL']: if not acl_check(_rf_src, self._CONFIG['GLOBAL']['SUB_ACL']): if _stream_id not in self._laststrid: logger.info('(%s) CALL DROPPED WITH STREAM ID %s FROM SUBSCRIBER %s BY GLOBAL ACL', self._system, int_id(_stream_id), int_id(_rf_src)) self._laststrid.append(_stream_id) return if _slot == 1 and not acl_check(_dst_id, self._CONFIG['GLOBAL']['TG1_ACL']): if _stream_id not in self._laststrid: logger.info('(%s) CALL DROPPED WITH STREAM ID %s ON TGID %s BY GLOBAL TS1 ACL', self._system, int_id(_stream_id), int_id(_dst_id)) self._laststrid.append(_stream_id) return if self._config['USE_ACL']: if not acl_check(_rf_src, self._config['SUB_ACL']): if _stream_id not in self._laststrid: logger.info('(%s) CALL DROPPED WITH STREAM ID %s FROM SUBSCRIBER %s BY SYSTEM ACL', self._system, int_id(_stream_id), int_id(_rf_src)) self._laststrid.append(_stream_id) return if not acl_check(_dst_id, self._config['TG1_ACL']): if _stream_id not in self._laststrid: logger.info('(%s) CALL DROPPED WITH STREAM ID %s ON TGID %s BY SYSTEM ACL', self._system, int_id(_stream_id), int_id(_dst_id)) self._laststrid.append(_stream_id) return # Userland actions -- typically this is the function you subclass for an application self.dmrd_received(_peer_id, _rf_src, _dst_id, _seq, _slot, _call_type, _frame_type, _dtype_vseq, _stream_id, _data) else: logger.info('(%s) OpenBridge HMAC failed, packet discarded - OPCODE: %s DATA: %s HMAC LENGTH: %s HMAC: %s', self._system, _packet[:4], repr(_packet[:53]), len(_packet[53:]), repr(_packet[53:]))
def datagramReceived(self, _packet, _sockaddr): # Keep This Line Commented Unless HEAVILY Debugging! #logger.debug('(%s) RX packet from %s -- %s', self._system, _sockaddr, ahex(_packet)) if _packet[:4] == 'DMRD': # DMRData -- encapsulated DMR data frame _data = _packet[:53] _hash = _packet[53:] _ckhs = hmac_new(self._config['PASSPHRASE'],_data,sha1).digest() if compare_digest(_hash, _ckhs) and _sockaddr == self._config['TARGET_SOCK']: _peer_id = _data[11:15] _seq = _data[4] _rf_src = _data[5:8] _dst_id = _data[8:11] _bits = int_id(_data[15]) _slot = 2 if (_bits & 0x80) else 1 #_call_type = 'unit' if (_bits & 0x40) else 'group' if _bits & 0x40: _call_type = 'unit' elif (_bits & 0x23) == 0x23: _call_type = 'vcsbk' else: _call_type = 'group' _frame_type = (_bits & 0x30) >> 4 _dtype_vseq = (_bits & 0xF) # data, 1=voice header, 2=voice terminator; voice, 0=burst A ... 5=burst F _stream_id = _data[16:20] #logger.debug('(%s) DMRD - Seqence: %s, RF Source: %s, Destination ID: %s', self._system, int_id(_seq), int_id(_rf_src), int_id(_dst_id)) # Sanity check for OpenBridge -- all calls must be on Slot 1 if _slot != 1: logger.error('(%s) OpenBridge packet discarded because it was not received on slot 1. SID: %s, TGID %s', self._system, int_id(_rf_src), int_id(_dst_id)) return # ACL Processing if self._CONFIG['GLOBAL']['USE_ACL']: if not acl_check(_rf_src, self._CONFIG['GLOBAL']['SUB_ACL']): if _stream_id not in self._laststrid: logger.info('(%s) CALL DROPPED WITH STREAM ID %s FROM SUBSCRIBER %s BY GLOBAL ACL', self._system, int_id(_stream_id), int_id(_rf_src)) self._laststrid.append(_stream_id) return if _slot == 1 and not acl_check(_dst_id, self._CONFIG['GLOBAL']['TG1_ACL']): if _stream_id not in self._laststrid: logger.info('(%s) CALL DROPPED WITH STREAM ID %s ON TGID %s BY GLOBAL TS1 ACL', self._system, int_id(_stream_id), int_id(_dst_id)) self._laststrid.append(_stream_id) return if self._config['USE_ACL']: if not acl_check(_rf_src, self._config['SUB_ACL']): if _stream_id not in self._laststrid: logger.info('(%s) CALL DROPPED WITH STREAM ID %s FROM SUBSCRIBER %s BY SYSTEM ACL', self._system, int_id(_stream_id), int_id(_rf_src)) self._laststrid.append(_stream_id) return if not acl_check(_dst_id, self._config['TG1_ACL']): if _stream_id not in self._laststrid: logger.info('(%s) CALL DROPPED WITH STREAM ID %s ON TGID %s BY SYSTEM ACL', self._system, int_id(_stream_id), int_id(_dst_id)) self._laststrid.append(_stream_id) return # Userland actions -- typically this is the function you subclass for an application self.dmrd_received(_peer_id, _rf_src, _dst_id, _seq, _slot, _call_type, _frame_type, _dtype_vseq, _stream_id, _data) else: logger.info('(%s) OpenBridge HMAC failed, packet discarded - OPCODE: %s DATA: %s HMAC LENGTH: %s HMAC: %s', self._system, _packet[:4], repr(_packet[:53]), len(_packet[53:]), repr(_packet[53:]))
def _calculate_registration_hmac(mpserver_secret, ip): h = hmac_new(mpserver_secret, str(ip), sha1) return urlsafe_b64encode(h.digest()).rstrip('=')
def _calculate_heartbeat_hmac(mpserver_secret, ip, num_players, active_sessions): h = hmac_new(mpserver_secret, str(ip), sha1) h.update(str(num_players)) if active_sessions: h.update(str(active_sessions)) return urlsafe_b64encode(h.digest()).rstrip('=')
def _calculate_session_hmac(mpserver_secret, ip, session_id): h = hmac_new(mpserver_secret, str(ip), sha1) h.update(str(session_id)) return urlsafe_b64encode(h.digest()).rstrip('=')
def _calculate_new_client_hmac(secret, ip, session_id, client_id): h = hmac_new(secret, str(ip), sha1) h.update(session_id) h.update(client_id) return urlsafe_b64encode(h.digest()).rstrip('=')
def hashed_packet(self, _key, _data): _hash = bhex((hmac_new(_key,_data,sha1)).hexdigest()[:20]) return _data + _hash
def _calculate_merge_session_hmac(secret, session_id_a, session_id_b): h = hmac_new(secret, str(session_id_a), sha1) h.update(session_id_b) return urlsafe_b64encode(h.digest()).rstrip('=')
def get_authorization_headers(session_id, secret, path, query_string=None, method='GET', content_type='', body='', host='localhost'): canonical_uri = urllib.quote(path.strip()) if query_string is not None: canonical_query_string = urlparse.parse_qsl( query_string, True, True) canonical_query_string.sort() # will sort by name, then by value canonical_query_string = urllib.urlencode(canonical_query_string) else: canonical_query_string = '' payload_hash = sha256(body).hexdigest() now = arrow.utcnow().format("YYYYMMDDTHHmmssZ") headers = { 'content-type': content_type, 'host': host, 'x-woodbox-content-sha256': payload_hash, 'x-woodbox-timestamp': now } signed_headers = sorted([ 'content-type', 'host', 'x-woodbox-content-sha256', 'x-woodbox-timestamp' ]) canonical_headers = [] for h in signed_headers: canonical_headers.append(h + ':' + headers[h]) canonical_headers = '\n'.join(canonical_headers).encode('utf-8') signed_headers = ';'.join(signed_headers) canonical_request = '\n'.join([ method, path, canonical_query_string, canonical_headers, signed_headers, payload_hash ]) string_to_sign = '\n'.join([ 'WOODBOX-HMAC-SHA256', now, sha256(canonical_request).hexdigest() ]) signing_key = secret.encode('utf-8') signature = hmac_new(signing_key, string_to_sign, sha256).hexdigest() auth = { 'Credential': session_id, 'SignedHeaders': signed_headers, 'Signature': signature } auth = [k + '=' + v for k, v in auth.iteritems()] auth = ','.join(auth) auth_str = ' '.join(['Woodbox-HMAC-SHA256', auth]) auth_headers = { 'Authorization': auth_str, 'x-woodbox-content-sha256': payload_hash, 'x-woodbox-timestamp': now } return auth_headers
def verify(algo, auth, headers): """ Expected headers: Content-Type: application/vnd.api+json Authorization: Woodbox-HMAC-SHA256 Credential=2a241ea1e4672ee91f2ef8051e00eb52f03e39c97404a487,SignedHeaders=host;x-woodbox-content-sha256;x-woodbox-timestamp,Signature=422a358ac3e9e27b00838b6aa4192d74788a0d1634b418a13e0a18aaf7ca65f8 x-woodbox-content-sha256: e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855 x-woodbox-timestamp: 20160122T211203Z """ # Check that we know the authentication algorithm. if algo.lower() not in frozenset(['hmac-sha256']): g.user = None g.user_reason = 'Unknown authentication method: ' + algo return False # Check that we have all the required authentication parameters. try: # Values were stripped in parse_authorization_header(). credential = auth['credential'] # session_id signed_headers = sorted(auth['signedheaders'].lower().split(';')) signature = auth['signature'] except KeyError as e: g.user = None g.user_reason = 'Missing parameter: {}'.format(e.args[0]) return False # Required headers are the headers that MUST be included in the canonical headers. required_headers = set( ['host', 'x-woodbox-content-sha256', 'x-woodbox-timestamp']) for h in six.iterkeys(headers): if h[:10] == 'x-woodbox-': required_headers.add(h) elif h == 'content-type': required_headers.add(h) # Check that all required headers were signed. if required_headers > set(signed_headers): g.user = None missing = (required_headers - set(signed_headers)) g.user_reason = 'Some required headers were not signed: ' + ', '.join( missing) return False # Check that all signed headers are part of the request. missing_headers = set(signed_headers) - set(six.iterkeys(headers)) if missing_headers: g.user = None g.user_reason = 'Missing headers: ' + ', '.join(missing_headers) return False # Check the age of the request. It must not be older than 5 minutes. request_time = arrow.get(headers['x-woodbox-timestamp'], ["YYYYMMDDTHHmmssZ", "YYYYMMDDTHHmmss"]) now = arrow.utcnow() max_age = timedelta(minutes=5) if abs(request_time - now) > max_age: g.user = None g.user_reason = 'Request is too old.' return False # FIXME Implement a nonce to prevent replay attacks. # Check the content hash. payload_hash = sha256(request.data).hexdigest() if payload_hash != headers['x-woodbox-content-sha256']: g.user = None g.user_reason = 'Content hash does not match.' return False # Load the session session = WBSessionModel.query.filter_by(session_id=credential).first() if not session: g.user = None g.user_reason = 'Invalid credential.' return False method = request.method.strip() canonical_uri = urllib.quote(request.path.strip()) # Build the canonical query string canonical_query_string = [] args = request.args.items(multi=True) args.sort() canonical_query_string = urllib.urlencode(args) # Build the canonical headers string. canonical_headers = [] for h in signed_headers: canonical_headers.append(h + ':' + headers[h]) canonical_headers = '\n'.join(canonical_headers).encode('utf-8') signed_headers = ';'.join(signed_headers) canonical_request = '\n'.join([ method, canonical_uri, canonical_query_string, canonical_headers, signed_headers, payload_hash ]) timestamp = headers['x-woodbox-timestamp'] string_to_sign = '\n'.join([ 'WOODBOX-HMAC-SHA256', timestamp, sha256(canonical_request).hexdigest() ]) signing_key = session.secret.encode('utf-8') computed_signature = hmac_new(signing_key, string_to_sign, sha256).hexdigest() # Compare our signature with the signature in the request. if compare_digest(signature.encode('ascii', 'ignore'), computed_signature.encode('ascii', 'ignore')): g.user = session.user_id g.user_reason = 'Authenticated' success = True else: g.user = None g.user_reason = 'Signature do not match' log.debug( "Authentication failure: signature do not match.\nExpected signature: {expected}\nComputed signature: {computed}\n\nString to sign:\n{sts}\n\nCanonical request:\n{cr}", expected=signature.encode('ascii', 'ignore'), computed=computed_signature.encode('ascii', 'ignore'), sts=string_to_sign, cr=canonical_request) success = False log.info("User {user} authenticated ({reason})", user=g.user, reason=g.user_reason) return success
def test_signatures_match(self): data = b"data" digest = "sha1" key = b"key" signature = hmac_new(key, data, digest).hexdigest() assert signatures_match(data, key, digest, signature) is True
def hmac_sha1(msg, consumer_key='', access_token=''): hashed = hmac_new(f'{consumer_key}&{access_token}'.encode('ascii'), msg.encode('ascii'), sha1) return quote(b64encode(hashed.digest()).decode('ascii'))