def hmactest(key, data, hexdigests): hmac_name = "hmac-" + hash_name h = hmac.HMAC(key, data, digestmod=hashfunc) self.assertEqual(h.hexdigest().lower(), hexdigests[hashfunc]) self.assertEqual(h.name, hmac_name) self.assertEqual(h.digest_size, digest_size) self.assertEqual(h.block_size, block_size) h = hmac.HMAC(key, data, digestmod=hash_name) self.assertEqual(h.hexdigest().lower(), hexdigests[hashfunc]) self.assertEqual(h.name, hmac_name) self.assertEqual(h.digest_size, digest_size) self.assertEqual(h.block_size, block_size) self.assertEqual( hmac.digest(key, data, digest=hashfunc), binascii.unhexlify(hexdigests[hashfunc]) ) self.assertEqual( hmac.digest(key, data, digest=hash_name), binascii.unhexlify(hexdigests[hashfunc]) ) with unittest.mock.patch('hmac._openssl_md_meths', {}): self.assertEqual( hmac.digest(key, data, digest=hashfunc), binascii.unhexlify(hexdigests[hashfunc]) ) self.assertEqual( hmac.digest(key, data, digest=hash_name), binascii.unhexlify(hexdigests[hashfunc]) )
def _ckd(d: XkeyDict, index: bytes) -> None: # d is a prvkey if d['key'][0] == 0: d['depth'] += 1 Pbytes = bytes_from_point(mult(d['q'])) d['parent_fingerprint'] = hash160(Pbytes)[:4] d['index'] = index if index[0] >= 0x80: # hardened derivation h = hmac.digest(d['chain_code'], d['key'] + index, 'sha512') else: # normal derivation h = hmac.digest(d['chain_code'], Pbytes + index, 'sha512') d['chain_code'] = h[32:] offset = int.from_bytes(h[:32], byteorder='big') d['q'] = (d['q'] + offset) % ec.n d['key'] = b'\x00' + d['q'].to_bytes(32, 'big') d['Q'] = INF # d is a pubkey else: if index[0] >= 0x80: raise ValueError("hardened derivation from pubkey is impossible") d['depth'] += 1 d['parent_fingerprint'] = hash160(d['key'])[:4] d['index'] = index h = hmac.digest(d['chain_code'], d['key'] + index, 'sha512') d['chain_code'] = h[32:] offset = int.from_bytes(h[:32], byteorder='big') Offset = mult(offset) d['Q'] = ec.add(d['Q'], Offset) d['key'] = bytes_from_point(d['Q']) d['q'] = 0
def generate_challenge_reply(game_key, challenge_key, challenge_data, nonce): key = hmac.digest(game_key, challenge_key, hashlib.sha256)[:16] data = hmac.digest(game_key, challenge_data, hashlib.sha256)[:16] aes = AES.new(key, AES.MODE_GCM, nonce=nonce) ciphertext, tag = aes.encrypt_and_digest(data) return tag + ciphertext
def __ckd(d: _ExtendedBIP32KeyDict, index: bytes) -> None: # FIXME the following check should be enforced # if d["depth"] == 0 and index[0] < 0x80: # raise UserWarning("public derivation at depth one level") # d is a prvkey if d["key"][0] == 0: d["depth"] += 1 Pbytes = bytes_from_point(mult(d["q"])) d["parent_fingerprint"] = hash160(Pbytes)[:4] d["index"] = index if index[0] >= 0x80: # hardened derivation h = hmac.digest(d["chain_code"], d["key"] + index, "sha512") else: # normal derivation h = hmac.digest(d["chain_code"], Pbytes + index, "sha512") d["chain_code"] = h[32:] offset = int.from_bytes(h[:32], byteorder="big") d["q"] = (d["q"] + offset) % ec.n d["key"] = b"\x00" + d["q"].to_bytes(32, "big") d["Q"] = INF # d is a pubkey else: if index[0] >= 0x80: raise ValueError("hardened derivation from public key") d["depth"] += 1 d["parent_fingerprint"] = hash160(d["key"])[:4] d["index"] = index h = hmac.digest(d["chain_code"], d["key"] + index, "sha512") d["chain_code"] = h[32:] offset = int.from_bytes(h[:32], byteorder="big") Offset = mult(offset) d["Q"] = ec.add(d["Q"], Offset) d["key"] = bytes_from_point(d["Q"]) d["q"] = 0
def _ckd(d: ExtendedBIP32KeyDict, index: bytes) -> None: # d is a prvkey if d["key"][0] == 0: d["depth"] += 1 Pbytes = bytes_from_point(mult(d["q"])) d["parent_fingerprint"] = hash160(Pbytes)[:4] d["index"] = index if index[0] >= 0x80: # hardened derivation h = hmac.digest(d["chain_code"], d["key"] + index, "sha512") else: # normal derivation h = hmac.digest(d["chain_code"], Pbytes + index, "sha512") d["chain_code"] = h[32:] offset = int.from_bytes(h[:32], byteorder="big") d["q"] = (d["q"] + offset) % ec.n d["key"] = b"\x00" + d["q"].to_bytes(32, "big") d["Q"] = INF # d is a pubkey else: if index[0] >= 0x80: raise ValueError("hardened derivation from pubkey is impossible") d["depth"] += 1 d["parent_fingerprint"] = hash160(d["key"])[:4] d["index"] = index h = hmac.digest(d["chain_code"], d["key"] + index, "sha512") d["chain_code"] = h[32:] offset = int.from_bytes(h[:32], byteorder="big") Offset = mult(offset) d["Q"] = ec.add(d["Q"], Offset) d["key"] = bytes_from_point(d["Q"]) d["q"] = 0
def login(self, username, password): # Request a challenge/uid/public key (this requires a valid username) request_data = {"Action": "request", "Username": username} response = self.hnap_request("Login", request_data) if response is None: self.logger.warn( "Failed to request login challenge, ensure host and username are correct" ) return False self.session.cookies.set("uid", response["Cookie"]) # Generate the private key from the public key/password/challenge self.private_key = (hmac.digest( (response["PublicKey"] + password).encode(), response["Challenge"].encode(), "md5", ).hex().upper()) self.session.cookies.set("PrivateKey", self.private_key) # Generate the passphrase for logging in passphrase = (hmac.digest(self.private_key.encode(), response["Challenge"].encode(), "md5").hex().upper()) request_data = { "Action": "login", "Username": username, "LoginPassword": passphrase, } response = self.hnap_request("Login", request_data) return response["LoginResult"] == "OK"
def login_page(): name = flask.request.form.get('name') password = flask.request.form.get('password') salt = uuid.uuid4().hex passwordhash = hashlib.sha256(password.encode('utf-8') + salt.encode('utf-8')).hexgigset() hmac.new(os.environ['SIGNATURE_KEY'].encode('utf-8'), msg = flask.request.cookies.get('name').encode('utf-8') + salt.encode('utf-8'), digestmod = 'sha256') already_auth = flask.request.cookies.get('ssid') == hmac.digest() just_auth = authenticate(name, passwordhash, salt) if already_auth or just_auth: redirect_url = cgi.escape(flask.request.args.get('redirect_url', '/')) if redirect_url: response = flask.make_response(flask.redirect(redirect_url)) if just_auth: response.set_cookie('ssid', hmac.digest(), max_age = 86400, secure=True, httponly=True, samesite='Strict')) return response return """ <html> <body> Successfully logged in </body> </html> """ return """
def login_page(): name = flask.request.form.get('name') password = flask.request.form.get('password') hmac.new(os.environ['SIGNATURE_KEY'].encode('utf8'), msg=flask.request.cookies.get('name').encode('utf8'), digestmod='sha256') already_auth = flask.request.cookies.get('ssid') == hmac.digest() just_auth = authenticate(name, password) if already_auth or just_auth: redirect_url = flask.request.args.get('redirect_url', '/') if redirect_url: response = flask.make_response(flask.redirect(redirect_url)) if just_auth: response.set_cookie('ssid', hmac.digest()) return response return """ <html> <body> Successfully logged in </body> </html> """ return """
def sso(request): if settings.SECRET_KEY == None: logger.error("django_commento_sso - COMMENTO_SECRET_KEY not found in settings.py") return HttpResponse(status=204) if request.GET['token']: logger.debug("token as received %s" % request.GET['token']) else: return HttpResponse(status=204) if request.GET['hmac']: logger.debug("hmac as recevied %s" % request.GET['hmac']) else: return HttpResponse(status=204) receivedHmacBytes = bytes.fromhex(request.GET['hmac']) tokenBytes = bytes.fromhex(request.GET['token']) secretKeyBytes = bytes.fromhex(settings.COMMENTO_SECRET_KEY) expectedHmacBytes = hmac.digest(secretKeyBytes, tokenBytes, 'sha256') print ("expected hmac was %s" % expectedHmacBytes.hex() ) if expectedHmacBytes==receivedHmacBytes: logger.debug("HMAC comparison of token - match") if not request.user.is_authenticated: return redirect('%s?next=https://%s?hmac=%s&token=%s' % (settings.LOGIN_URL, request.get_full_path(), request.GET['hmac'], request.GET['token'])) else: logger.info("django_commento_sso SSO Success for User %s" % request.user.username ) payload = { "token": request.GET['token'], } if not request.user.email: logger.error('django_commento_sso User must have email for Commento SSO') return False else: payload['email']=request.user.email payload['name']=settings.COMMENTO_USER_NAME_FUNCTION(get_user(request)) if settings.COMMENTO_USER_LINK_FUNCTION: payload['link']=settings.COMMENTO_USER_LINK_FUNCTION(get_user(request)) if settings.COMMENTO_USER_PHOTO_FUNCTION: payload['photo']=settings.COMMENTO_USER_PHOTO_FUNCTION(get_user(request)) payloadHMACHex=(hmac.digest( secretKeyBytes, bytes(json.dumps(payload),'utf8'),'sha256')).hex() payloadHex=bytes(json.dumps(payload),'utf8').hex() return redirect("https://commento.io/api/oauth/sso/callback?payload={0}&hmac={1}".format(payloadHex, payloadHMACHex)) else: #spoofed token attempt or error logger.warning("django_commento_sso SSO HMAC comparison - No match") return HttpResponse(status=404)
def ckd_prv(k_par, c_par, i): if i >= 1 << 31: I = hmac.digest(c_par, b'\x00' + ser256(k_par) + ser32(i), 'sha512') else: I = hmac.digest(c_par, serP(point(k_par)) + ser32(i), 'sha512') I_L, I_R = I[:32], I[32:] k_i = (parse256(I_L) + k_par) % n c_i = I_R if parse256(I_L) >= n or k_i == 0: raise BIP32Error("invalid i") return k_i, c_i
def compareHMAC(self, hmac, digest): """verify HMACs equality, using the most secure way available """ result = False # use compare_digest() instead of a == b to prevent timing analysis # if python version >= 2.7.7 # ref https://docs.python.org/2/library/hmac.html if sys.version_info[1] >= 7 and sys.version_info[2] >= 7: result = hmac.compare_digest(hmac.digest(), digest) else: result = hmac.digest() == digest return result
def __init__(self, app=None): if app is None: app = flask.current_app bits = app.config.get('SESSION_KEY_BITS', self.uid_bits) if not 64 <= bits <= 256: raise ValueError('SESSION_KEY_BITS must be between 64 and 256!') uid_bytes = bits // 8 + (bits % 8 > 0) sid_bytes = self.sid_bits // 8 key = want_bytes(app.secret_key) self._hmac = hmac.new(hmac.digest(key, b'SESSION_UID_HASH', digest='sha256'), digestmod='sha256') self._uid_len = uid_bytes self._uid_b64 = len(self._encode(bytes(uid_bytes))) self._sid_len = sid_bytes self._sid_b64 = len(self._encode(bytes(sid_bytes))) self._key_min = self._uid_b64 + self._sid_b64 self._key_max = self._key_min + len( self._encode(bytes(self.time_bits // 8)))
def generate_hmac(self, secret_key, counter): """Create a 160-bit HMAC from secret and counter. Args: secret_key: a byte string (recommended minimum 20 bytes) that is the shared secret between the client and server. counter: an integer value represented in an 8-byte string with the most significant byte first and least significant byte last Returns: The HMAC digest; a byte string, 20 bytes long. Raises: TypeError: if the counter and secret are not byte strings. ValueError: if the counter is not 8 bytes long. """ from hashlib import sha1 import hmac if not isinstance(secret_key, bytes): raise TypeError('secret_key must be a byte string') if not isinstance(counter, bytes): raise TypeError('counter must be a byte string') if (8 != len(counter)): raise ValueError('counter must be 8 bytes') hmac = hmac.new(secret_key, counter, sha1) hash = hmac.digest() return hash
def compute_hash(self): # Try to compute the hash expected by # the public function check(). # # return (string) url encoded ( base64 encoded ( hmac ) ). self.hash = base64.b64encode( hmac.digest(self.secret.encode(), self.payload.encode(), "sha256"))
def packFiles(path="", outputPath=""): import hmac import binascii if not outputPath: outputPath = os.path.join(path, "packed") os.makedirs(outputPath, exist_ok=True) for filename in VALID_FILE_NAMES: try: with open(os.path.join(path, filename + '.txt'), 'r') as f: data = json.load(f, object_pairs_hook=OrderedDict) minimizedString = json.dumps(data, separators=(',', ':')) hashString = hmac.digest(bytes(OFFLINE_KEY, 'utf-8'), bytes(minimizedString, 'utf-8'), 'sha1') hashString = binascii.hexlify(hashString) logger.debug("Hash for %s is %s", filename, hashString) try: with gzip.open(os.path.join(outputPath, filename), 'w+b') as outputFile: outputFile.write(hashString) outputFile.write(b'\n') outputFile.write((bytes(minimizedString, 'utf-8'))) outputFile.write(b'\0') logger.info('Generated %s', filename) except: logger.error("failed to generate output %s", filename, exc_info=True) except (IOError, FileNotFoundError): logger.info("Ignore %s.txt, not found", filename)
def test_github_sponsor_slack_message(rf: RequestFactory, settings: SettingsWrapper, test_data: Dict) -> None: """Test to ensure webhooks from GitHub Sponsors trigger appropriate slack pings.""" slack_client.chat_postMessage = MagicMock() request = rf.post( "slack/github/sponsors/", data={ "action": test_data["action"], "sponsorship": { "sponsor": { "login": test_data["username"] }, "tier": { "name": test_data["tier"] }, }, }, content_type="application/json", ) request.headers = { "x-hub-signature": "sha1={}".format( binascii.hexlify( hmac.digest( msg=request.body, key=settings.GITHUB_SPONSORS_SECRET_KEY.encode(), digest="sha1", )).decode()) } response = github_sponsors_endpoint(request) assert slack_client.chat_postMessage.call_args[1]["text"] == test_data[ "result"] assert response.status_code == test_data["status_code"]
def sign_string(self, string_to_sign): if self._hmac_256: hmac = self._hmac_256.copy() else: hmac = self._hmac.copy() hmac.update(string_to_sign) return base64.encodestring(hmac.digest()).strip()
def _decode_jwt(self, jwt, token_type="auth"): parts = jwt.encode().split(b".") if len(parts) != 3: raise self.server.error(f"Invalid JWT length of {len(parts)}") header = json.loads(base64url_decode(parts[0])) payload = json.loads(base64url_decode(parts[1])) if header != JWT_HEADER: raise self.server.error("Invalid JWT header") recd_type = payload.get('token_type', "") if token_type != recd_type: raise self.server.error( f"JWT Token type mismatch: Expected {token_type}, " f"Recd: {recd_type}", 401) if time.time() > payload['exp']: raise self.server.error("JWT expired", 401) username = payload.get('username') user_info = self.users.get(username, None) if user_info is None: raise self.server.error( f"Invalid JWT, no registered user {username}", 401) jwt_secret = user_info.get('jwt_secret', None) if jwt_secret is None: raise self.server.error( f"Invalid JWT, user {username} not logged in", 401) secret = bytes.fromhex(jwt_secret) # Decode and verify signature signature = base64url_decode(parts[2]) calc_sig = hmac.digest(secret, parts[0] + b"." + parts[1], "sha256") if signature != calc_sig: raise self.server.error("Invalid JWT signature") return user_info
def main_loop(sock): while True: # noinspection PyBroadException try: conn, addr = sock.accept() print("Incoming connection from", addr) data, sent_signature = conn.recv(1024).split(b".") data = base64.b64decode(data) if secret: msg_signature = hmac.digest(secret, data, 'sha512') if not hmac.compare_digest(base64.b64decode(sent_signature), msg_signature): print("Signature mismatch!") continue data = json.loads(data.decode()) if abs((datetime.fromtimestamp(data['timestamp']) - datetime.utcnow()).total_seconds()) >= 300: print("Timestamp expired") continue print("Got command:", data) if data.get('custom'): cmd = shlex.split("{} {}".format(BIN, data['custom']).format(saddr=data['saddr'])) else: cmd = [BIN, 'insert', 'rule', *data['table'].split(), data['chain'], 'ip', 'saddr', data['saddr'], data['proto'], 'dport', data['dport'], 'counter', 'accept'] if sudo: cmd.insert(0, 'sudo') print("Exec:", cmd) subprocess.run(cmd) except KeyboardInterrupt: sock.close() except Exception: print("Unhandled exception:", traceback.format_exc())
def _get_header(self): headers = list() request_id = str(uuid.uuid4()) timestamp = datetime.utcnow().replace(microsecond=0).isoformat() + "Z" elements = { "shopId": self.sp_config["site_id"], "requestId": request_id, "timestamp": timestamp, "mode": "PRODUCTION" if self.sp_config["production"] else "TEST", "authToken": b64encode( hmac.digest( self.sp_config["certificate"].encode(), (request_id + timestamp).encode(), "sha256", ) ).decode(), } for elem in elements: header = xsd.ComplexType( [xsd.Element(header_namespace + elem, xsd.String())] ) headers.append(header(**{elem: elements[elem]})) return headers
def rootxprv_from_seed( seed: Octets, version: Octets = NETWORKS["mainnet"]["bip32_prv"]) -> bytes: """Return BIP32 root master extended private key from seed.""" seed = bytes_from_octets(seed) bitlenght = len(seed) * 8 if bitlenght < 128: raise ValueError( f"too few bits for seed: {bitlenght} in '{hex_string(seed)}'") if bitlenght > 512: raise ValueError( f"too many bits for seed: {bitlenght} in '{hex_string(seed)}'") hd = hmac.digest(b"Bitcoin seed", seed, "sha512") k = b"\x00" + hd[:32] v = bytes_from_octets(version, 4) if v not in _XPRV_VERSIONS_ALL: raise ValueError(f"unknown private key version: {v.hex()}") d: BIP32KeyDict = { "version": v, "depth": 0, "parent_fingerprint": b"\x00\x00\x00\x00", "index": b"\x00\x00\x00\x00", "chain_code": hd[32:], "key": k, } return serialize(d)
def _calc_signature(self, params, verb, path, server_name): boto.log.debug('using _calc_signature_2') string_to_sign = '%s\n%s\n%s\n' % (verb, server_name.lower(), path) if self._hmac_256: hmac = self._hmac_256.copy() params['SignatureMethod'] = 'HmacSHA256' else: hmac = self._hmac.copy() params['SignatureMethod'] = 'HmacSHA1' keys = params.keys() keys.sort() pairs = [] for key in keys: val = boto.utils.get_utf8_value(params[key]) pairs.append(urllib.quote(key, safe='') + '=' + urllib.quote(val, safe='-_~')) qs = '&'.join(pairs) boto.log.debug('query string: %s' % qs) string_to_sign += qs boto.log.debug('string_to_sign: %s' % string_to_sign) hmac.update(string_to_sign) b64 = base64.b64encode(hmac.digest()) boto.log.debug('len(b64)=%d' % len(b64)) boto.log.debug('base64 encoded digest: %s' % b64) return (qs, b64)
def _mac(self, fh): hmac = self.hmac.copy() d = self._read(fh, BUFFER_SIZE, 0) while d: hmac.update(d) d = self._read(fh, BUFFER_SIZE) return hmac.digest()[:MAC_SIZE]
def test_with_sha256_module(self): h = hmac.HMAC(b"key", b"hash this!", digestmod=sha256_module.sha256) self.assertEqual(h.hexdigest(), self.expected) self.assertEqual(h.name, "hmac-sha256") digest = hmac.digest(b"key", b"hash this!", sha256_module.sha256) self.assertEqual(digest, binascii.unhexlify(self.expected))
def validate(token, secret): # read parts from token token = token.decode() parts = token.split(".", 3) headerWithPayload = (parts[0] + "." + parts[1]).encode() header = parts[0] payload = parts[1] signature = parts[2] # parse stringified json headerDecoded = json.loads(base64.b64decode(header)) # read algorithm from header part - not used yet algorithm = headerDecoded["alg"] # hash header.payload using provided secret headerPayloadHash = hmac.digest(secret.encode(), headerWithPayload, hashlib.sha256) # convert to base64url headerPayloadBase64 = base64.b64encode(headerPayloadHash).decode() headerPayloadBase64 = headerPayloadBase64.replace("+", "-") headerPayloadBase64 = headerPayloadBase64.replace("/", "_") headerPayloadBase64 = headerPayloadBase64.replace("=", "") # check if the generated base64-encoded string matches the initial signature # this proves whether the token was generated using the provided key return headerPayloadBase64 == signature
async def add_secret(app: Sanic, secret: str, passphrase: str, ttl: Optional[int]) -> str: """ Add a secret to app.db. :param app: Sanic app :param secret: secret to add :param passphrase: passphrase associated with a secret :param ttl: secret time to live (optional) :return: secret key to acquire secret afterwards """ key = get_fernet_key(app, passphrase) sign = hmac.digest(key=key, msg=passphrase.encode(), digest='sha512').hex() secret_key = secrets.token_hex(16) cipher = fernet.Fernet(key) encrypted = cipher.encrypt(secret.encode()).decode() expires = None if ttl: expires = datetime.utcnow() + timedelta(seconds=ttl) await app.db.secrets.insert_one({ 'secret': encrypted, 'secret_key': secret_key, 'signature': sign, 'expires': expires, # for mongo index 'ttl': ttl, # for fernet check }) return secret_key
def sign(self, req): canon_hash = canonical_hash(req) scope = '{date}/{region}/{service}/aws4_request'.format( date=format_date(req.timestamp), region=self.region, service=self.service) signing_key = self.signing_key(scope) string_to_sign = '\n'.join([ 'AWS4-HMAC-SHA256', format_time(req.timestamp), scope, canon_hash, ]) string_to_sign = string_to_sign.encode('utf8') signature = hmac.digest(signing_key, string_to_sign, hashlib.sha256) req.add_header( 'Authorization', 'AWS4-HMAC-SHA256 Credential={key}/{scope}, SignedHeaders={signed_headers}, Signature={signature}' .format(key=self.key, scope=scope, signed_headers=canonical_headers(req).rsplit('\n', 1)[1], signature=signature.hex()))
def _calc_signature(self, params, verb, path, server_name): boto.log.debug("using _calc_signature_2") string_to_sign = "%s\n%s\n%s\n" % (verb, server_name.lower(), path) if self._hmac_256: hmac = self._hmac_256.copy() params["SignatureMethod"] = "HmacSHA256" else: hmac = self._hmac.copy() params["SignatureMethod"] = "HmacSHA1" if self._provider.security_token: params["SecurityToken"] = self._provider.security_token keys = params.keys() keys.sort() pairs = [] for key in keys: val = boto.utils.get_utf8_value(params[key]) pairs.append(urllib.quote(key, safe="") + "=" + urllib.quote(val, safe="-_~")) qs = "&".join(pairs) boto.log.debug("query string: %s" % qs) string_to_sign += qs boto.log.debug("string_to_sign: %s" % string_to_sign) hmac.update(string_to_sign) b64 = base64.b64encode(hmac.digest()) boto.log.debug("len(b64)=%d" % len(b64)) boto.log.debug("base64 encoded digest: %s" % b64) return (qs, b64)
def calc_signature_2(self, params, verb, path): boto.log.debug('using calc_signature_2') string_to_sign = '%s\n%s\n%s\n' % (verb, self.server_name().lower(), path) if self.hmac_256: hmac = self.hmac_256.copy() params['SignatureMethod'] = 'HmacSHA256' else: hmac = self.hmac.copy() params['SignatureMethod'] = 'HmacSHA1' keys = params.keys() keys.sort() pairs = [] for key in keys: val = self.get_utf8_value(params[key]) pairs.append( urllib.quote(key, safe='') + '=' + urllib.quote(val, safe='-_~')) qs = '&'.join(pairs) boto.log.debug('query string: %s' % qs) string_to_sign += qs boto.log.debug('string_to_sign: %s' % string_to_sign) hmac.update(string_to_sign) b64 = base64.b64encode(hmac.digest()) boto.log.debug('len(b64)=%d' % len(b64)) boto.log.debug('base64 encoded digest: %s' % b64) return (qs, b64)
def datagram_received(self, data, addr): cmd = int.from_bytes(data[0:4], 'little') if cmd == 1 and len(data) == 148: HASH = lambda x: hashlib.blake2s(x).digest() MAC = lambda key, x: hashlib.blake2s(x, key=key, digest_size=16).digest() HMAC = lambda key, x: hmac.digest(key, x, hashlib.blake2s) p, mac1, mac2 = struct.unpack('<116s16s16s', data) assert mac1 == MAC(HASH(b"mac1----" + self.public_key), p) assert mac2 == b'\x00'*16 index = next(self.sender_index_generator) sender_index, unencrypted_ephemeral, encrypted_static, encrypted_timestamp = struct.unpack('<4xI32s48s28s', data[:-32]) chaining_key = HASH(b"Noise_IKpsk2_25519_ChaChaPoly_BLAKE2s") hash0 = HASH(HASH(HASH(chaining_key + b"WireGuard v1 zx2c4 [email protected]") + self.public_key) + unencrypted_ephemeral) chaining_key = HMAC(HMAC(chaining_key, unencrypted_ephemeral), b"\x01") temp = HMAC(chaining_key, crypto.X25519(self.private_key, unencrypted_ephemeral)) chaining_key = HMAC(temp, b"\x01") static_public = crypto.aead_chacha20poly1305_decrypt(HMAC(temp, chaining_key + b"\x02"), 0, encrypted_static, hash0) hash0 = HASH(hash0 + encrypted_static) temp = HMAC(chaining_key, crypto.X25519(self.private_key, static_public)) chaining_key = HMAC(temp, b"\x01") timestamp = crypto.aead_chacha20poly1305_decrypt(HMAC(temp, chaining_key + b"\x02"), 0, encrypted_timestamp, hash0) hash0 = HASH(hash0 + encrypted_timestamp) ephemeral_private = os.urandom(32) ephemeral_public = crypto.X25519(ephemeral_private, 9) hash0 = HASH(hash0 + ephemeral_public) chaining_key = HMAC(HMAC(HMAC(HMAC(HMAC(HMAC(chaining_key, ephemeral_public), b"\x01"), crypto.X25519(ephemeral_private, unencrypted_ephemeral)), b"\x01"), crypto.X25519(ephemeral_private, static_public)), b"\x01") temp = HMAC(chaining_key, self.preshared_key) chaining_key = HMAC(temp, b"\x01") temp2 = HMAC(temp, chaining_key + b"\x02") key = HMAC(temp, temp2 + b"\x03") hash0 = HASH(hash0 + temp2) encrypted_nothing = crypto.aead_chacha20poly1305_encrypt(key, 0, b"", hash0) #hash0 = HASH(hash0 + encrypted_nothing) msg = struct.pack('<III32s16s', 2, index, sender_index, ephemeral_public, encrypted_nothing) msg = msg + MAC(HASH(b"mac1----" + static_public), msg) + b'\x00'*16 self.transport.sendto(msg, addr) print('login', addr, sender_index) temp = HMAC(chaining_key, b"") receiving_key = HMAC(temp, b"\x01") sending_key = HMAC(temp, receiving_key + b"\x02") self.keys[index] = (sender_index, receiving_key, sending_key) self.index_generators[index] = itertools.count() elif cmd == 4 and len(data) >= 32: _, index, counter = struct.unpack('<IIQ', data[:16]) sender_index, receiving_key, sending_key = self.keys[index] packet = crypto.aead_chacha20poly1305_decrypt(receiving_key, counter, data[16:], b'') def reply(data): counter = next(self.index_generators[index]) data = data + b'\x00'*((-len(data))%16) msg = crypto.aead_chacha20poly1305_encrypt(sending_key, counter, data, b'') msg = struct.pack('<IIQ', 4, sender_index, counter) + msg self.transport.sendto(msg, addr) return True if packet: self.ippacket.handle_ipv4(addr[:2], packet, reply) else: reply(b'')
def enc_session_data(passphrase, json_data): # Figure out our parameters. version, S, IV, N = b"\x01", get_random_bytes(16), get_random_bytes( 16), 500000 # Clear bit 63 of IV -- apparently this is required to work around a quirk # of the Android AES-CTR's counter implementation. IV = int.from_bytes(IV, byteorder="big") & ~(1 << 63) # Get our keys. K, Kp = stretch_keys(passphrase, S, N) # Encrypt the JSON. ctr = Counter.new(128, initial_value=IV) cipher = AES.new(K, AES.MODE_CTR, counter=ctr) plaintext = json_data ciphertext = cipher.encrypt(plaintext) # Prepend the crypto parameters. params = CryptoParams.pack(version, S, IV.to_bytes(16, "big"), N) body = params + ciphertext # Compute the MAC. body += hmac.digest(Kp, body, "sha256") # Base64 everything, wrap it at 128-chars, and add the header+footer. session_data = bytes_wrap(base64.b64encode(body), 128) return b"\n".join([HEADER, session_data, FOOTER])
def dec_session_data(passphrase, session_data): # Get rid of any trailing newlines. session_data = session_data.strip() # Does it have the header and footer? if not session_data.startswith(HEADER): bail("session data invalid: missing header %r" % (HEADER, )) if not session_data.endswith(FOOTER): bail("session data invalid: missing footer %r" % (FOOTER, )) # Get the body and base64-decode it. body = base64.b64decode(session_data[len(HEADER):-len(FOOTER)]) if len(body) < CryptoParams.size + MAC_SIZE: bail("session data invalid: data packet too small") # Get the parameters (we need S and N to check the MAC). params = body[:CryptoParams.size] version, S, IV, N = CryptoParams.unpack(params) IV = int.from_bytes(IV, byteorder="big") # Figure out the keys. K, Kp = stretch_keys(passphrase, S, N) # Check the MAC. mac = body[-MAC_SIZE:] our_mac = hmac.digest(Kp, body[:-MAC_SIZE], "sha256") if not hmac.compare_digest(mac, our_mac): bail("session data corrupted or bad passphrase: mac check failed") # Okay, decrypt the JSON. ctr = Counter.new(128, initial_value=IV) cipher = AES.new(K, AES.MODE_CTR, counter=ctr) ciphertext = body[CryptoParams.size:-MAC_SIZE] return cipher.decrypt(ciphertext)
def __init__(self, seed, key="Bitcoin seed"): I = hmac.digest(b"Bitcoin seed", seed, 'sha512') I_L, I_R = I[:32], I[32:] self.m = parse256(I_L) self.M = SigningKey.from_string(I_L, curve=SECP256k1) \ .get_verifying_key().pubkey.point self.c = I_R
def sign_string(self, string_to_sign): boto.log.debug('Canonical: %s' % string_to_sign) if self._hmac_256: hmac = self._hmac_256.copy() else: hmac = self._hmac.copy() hmac.update(string_to_sign) return base64.encodestring(hmac.digest()).strip()
def add_aws_auth_header(self, headers, method, path): if not headers.has_key('Date'): headers['Date'] = time.strftime("%a, %d %b %Y %H:%M:%S GMT", time.gmtime()) c_string = boto.utils.canonical_string(method, path, headers) boto.log.debug('Canonical: %s' % c_string) hmac = self.hmac.copy() hmac.update(c_string) b64_hmac = base64.encodestring(hmac.digest()).strip() headers['Authorization'] = "AWS %s:%s" % (self.aws_access_key_id, b64_hmac)
def add_aws_auth_header(self, headers, method, path): path = self.get_path(path) if not headers.has_key("Date"): headers["Date"] = time.strftime("%a, %d %b %Y %H:%M:%S GMT", time.gmtime()) c_string = boto.utils.canonical_string(method, path, headers, None, self.provider) boto.log.debug("Canonical: %s" % c_string) hmac = self.hmac.copy() hmac.update(c_string) b64_hmac = base64.encodestring(hmac.digest()).strip() auth_hdr = self.provider.auth_header headers["Authorization"] = "%s %s:%s" % (auth_hdr, self.aws_access_key_id, b64_hmac)
def test_hmac(self): iio = BytesIO() for tv in self.__class__.TEST_VECTORS: iio.truncate(0) iio.seek(0) iio.write(tv.text) iio.seek(0) digest = hmac.digest(iio, tv.key, digestcls=tv.digestcls) self.assertEqual(tv.mac, digest, "{}{}".format(tv.digestcls, tv.text))
def getSignedUrl(base_url, params, timestamp=None): global HMAC hmac = HMAC.copy() # Add a ISO 8601 compliant timestamp (in GMT) if timestamp: params["Timestamp"] = timestamp else: params["Timestamp"] = time.strftime("%Y-%m-%dT%H:%M:%S", time.gmtime()) # params['SignatureVersion']='1' # Sort the URL parameters by key keys = params.keys() # keys.sort(cmp = lambda x, y: cmp(x.lower(), y.lower())) keys.sort() # Reconstruct the URL parameters and encode them pairs = [] for key in keys: # val = urllib.quote(params[key]) val = params[key] pairs.append(key + "=" + val) url_string = "&".join(pairs) url_string = url_string.replace("+", "%20") url_string = url_string.replace(":", "%3A") # Construct the string to sign urlparts = base_url.split("/") string_to_sign = """GET %s /%s/%s %s""" % ( urlparts[2], urlparts[3], urlparts[4], url_string, ) url_string = url_string.replace(";", urllib.quote(";")) # Sign the request hmac.update(string_to_sign) signature = hmac.digest() # Base64 encode the signature signature = base64.encodestring(signature).strip() signature = signature.replace("+", "%2B") signature = signature.replace("=", "%3D") signature = signature.replace("/", "%2F") # Make the signature URL safe url_string += "&Signature=%s" % signature return "%s?%s" % (base_url, url_string)
def _calc_signature(self, params, *args): boto.log.debug('using _calc_signature_1') hmac = self._get_hmac() keys = list(params.keys()) keys.sort(key=lambda x: x.lower()) pairs = [] for key in keys: hmac.update(key.encode('utf-8')) val = boto.utils.get_utf8_value(params[key]) hmac.update(val) pairs.append(key + '=' + urllib.parse.quote(val)) qs = '&'.join(pairs) return (qs, base64.b64encode(hmac.digest()))
def _calc_signature(self, params, *args): boto.log.debug('using _calc_signature_0') hmac = self._hmac.copy() s = params['Action'] + params['Timestamp'] hmac.update(s) keys = params.keys() keys.sort(key=str.lower) pairs = [] for key in keys: val = boto.utils.get_utf8_value(params[key]) pairs.append(key + '=' + quote(val)) qs = '&'.join(pairs) return (qs, base64.b64encode(hmac.digest()))
def calc_signature_0(self, params): boto.log.debug('using calc_signature_0') hmac = self.hmac.copy() s = params['Action'] + params['Timestamp'] hmac.update(s) keys = params.keys() keys.sort(cmp = lambda x, y: cmp(x.lower(), y.lower())) pairs = [] for key in keys: val = self.get_utf8_value(params[key]) pairs.append(key + '=' + urllib.quote(val)) qs = '&'.join(pairs) return (qs, base64.b64encode(hmac.digest()))
def _calc_signature(self, params, *args): txboto.log.debug('using _calc_signature_0') hmac = self._get_hmac() s = params['Action'] + params['Timestamp'] hmac.update(s.encode('utf-8')) keys = params.keys() keys.sort(cmp=lambda x, y: cmp(x.lower(), y.lower())) pairs = [] for key in keys: val = txboto.utils.get_utf8_value(params[key]) pairs.append(key + '=' + quote(val)) qs = '&'.join(pairs) return (qs, base64.b64encode(hmac.digest()))
def calc_signature_1(self, params): boto.log.debug("using calc_signature_1") hmac = self.hmac.copy() keys = params.keys() keys.sort(cmp=lambda x, y: cmp(x.lower(), y.lower())) pairs = [] for key in keys: hmac.update(key) val = self.get_utf8_value(params[key]) hmac.update(val) pairs.append(key + "=" + urllib.quote(val)) qs = "&".join(pairs) return (qs, base64.b64encode(hmac.digest()))
def _calc_signature(self, params, *args): boto.log.debug("using _calc_signature_0") hmac = self._get_hmac() s = params["Action"] + params["Timestamp"] hmac.update(s) keys = params.keys() keys.sort(cmp=lambda x, y: cmp(x.lower(), y.lower())) pairs = [] for key in keys: val = boto.utils.get_utf8_value(params[key]) pairs.append(key + "=" + urllib.quote(val)) qs = "&".join(pairs) return (qs, base64.b64encode(hmac.digest()))
def _calc_signature(self, params, *args): boto.log.debug('using _calc_signature_1') hmac = self._hmac.copy() keys = params.keys() keys.sort(cmp = lambda x, y: cmp(x.lower(), y.lower())) pairs = [] for key in keys: hmac.update(key) val = boto.utils.get_utf8_value(params[key]) hmac.update(val) pairs.append(key + '=' + urllib.quote(val)) qs = '&'.join(pairs) return (qs, base64.b64encode(hmac.digest()))
def decrypt(self, data): iv, ciphertext, data_hmac = data[:16], data[16:-32], data[-32:] if hmac.compare_digest(data_hmac, hmac.digest(self.derived_key, (iv + ciphertext), 'sha256')): aes = Cipher(algorithms.AES(self.derived_key), modes.CBC(iv), backend=default_backend()) decryptor = aes.decryptor() decrypted_data = decryptor.update(ciphertext) + decryptor.finalize() unpadder = padding.PKCS7(128).unpadder() return unpadder.update(decrypted_data) + unpadder.finalize() #logging.error('HMAC not valid') raise CryptoException("HMAC not valid")
def md5test(key, data, digest): h = hmac.HMAC(key, data, digestmod=hashlib.md5) self.assertEqual(h.hexdigest().upper(), digest.upper()) self.assertEqual(h.digest(), binascii.unhexlify(digest)) self.assertEqual(h.name, "hmac-md5") self.assertEqual(h.digest_size, 16) self.assertEqual(h.block_size, 64) h = hmac.HMAC(key, data, digestmod='md5') self.assertEqual(h.hexdigest().upper(), digest.upper()) self.assertEqual(h.digest(), binascii.unhexlify(digest)) self.assertEqual(h.name, "hmac-md5") self.assertEqual(h.digest_size, 16) self.assertEqual(h.block_size, 64) self.assertEqual( hmac.digest(key, data, digest='md5'), binascii.unhexlify(digest) ) with unittest.mock.patch('hmac._openssl_md_meths', {}): self.assertEqual( hmac.digest(key, data, digest='md5'), binascii.unhexlify(digest) )
def encrypt(self, data): iv = token_bytes(16) aes = Cipher(algorithms.AES(self.derived_key), modes.CBC(iv), backend=default_backend()) encryptor = aes.encryptor() padder = padding.PKCS7(128).padder() padded_data = padder.update(data) + padder.finalize() encrypted_data = encryptor.update(padded_data) + encryptor.finalize() mac = hmac.digest(self.derived_key, (iv + encrypted_data), 'sha256') #logging.debug(f"IV: {to_byte_array(iv)}") #logging.debug(f"HMAC: {to_byte_array(mac)}") #logging.debug(f"DATA: {to_byte_array(encrypted_data)}") return iv + encrypted_data + mac
def dtapicall(appliance, query, publickey, privatekey, timemod=0, verifySSL=False): """Returns JSON-formatted data from the Darktrace <appliance> specified, using the <query> specified, and the <publickey> and <privatekey> supplied <appliance> is the full URL of the appliance, for example 'https://10.1.2.3' <query> is the API query you are passing to the appliance, for example '/metrics' <publickey> is the public key which is provided from the Darktrace appliance (provided by the reseller) <privatekey> is the private key which is provided from the Darktrace appliance (provided by the reseller) optional <timemod> allows you to modify the current time passed (default=0) to the API to allow for timezone differences, e.g., passing 59 will add 59 minutes to the time, -59 will take off 59 minutes. optional <verifySSL> allow you to ignore cert errors (default=False) when making the call If successful it returns an object containing JSON-formatted data matching your query. @leighhall / madsky.co.uk Version: 1.0 / Aug 2015 """ import datetime import hmac import hashlib import requests #today = datetime.datetime.today() today = datetime.datetime.utcnow() today = today + datetime.timedelta(minutes=timemod) format = "%Y%m%dT%H%M%S" dt = today.strftime(format) hmac = hmac.new(privatekey, query+"\n"+publickey+"\n"+dt, hashlib.sha1) sig = hashlib.sha1() sig.update(hmac.digest()) payload = { 'DTAPI-Token': publickey, 'DTAPI-Date': dt, 'DTAPI-Signature': sig.hexdigest() } r = requests.get(appliance+query, headers=payload, verify=verifySSL) ret = r.json() return ret
def shatest(key, data, digest): h = hmac.HMAC(key, data, digestmod=hashlib.sha1) self.assertEqual(h.hexdigest().upper(), digest.upper()) self.assertEqual(h.digest(), binascii.unhexlify(digest)) self.assertEqual(h.name, "hmac-sha1") self.assertEqual(h.digest_size, 20) self.assertEqual(h.block_size, 64) h = hmac.HMAC(key, data, digestmod='sha1') self.assertEqual(h.hexdigest().upper(), digest.upper()) self.assertEqual(h.digest(), binascii.unhexlify(digest)) self.assertEqual(h.name, "hmac-sha1") self.assertEqual(h.digest_size, 20) self.assertEqual(h.block_size, 64) self.assertEqual( hmac.digest(key, data, digest='sha1'), binascii.unhexlify(digest) )
def calc_signature(self, args): scheme, host, port = requests.packages.urllib3.get_host(args['url']) string_to_sign = '%s\n%s\n%s\n' % (args['method'], host, '/') hmac = self.hmac.copy() args['params']['SignatureMethod'] = 'HmacSHA256' if self.credentials.token: args['params']['SecurityToken'] = self.credentials.token sorted_params = sorted(args['params']) pairs = [] for key in sorted_params: value = args['params'][key] pairs.append(quote(key, safe='') + '=' + quote(value, safe='-_~')) qs = '&'.join(pairs) string_to_sign += qs print('string_to_sign') print(string_to_sign) hmac.update(string_to_sign.encode('utf-8')) b64 = base64.b64encode(hmac.digest()).strip().decode('utf-8') return (qs, b64)
def _calc_signature(self, params, verb, path, server_name): boto.log.debug('using _calc_signature_2') string_to_sign = '%s\n%s\n%s\n' % (verb, server_name.lower(), path) hmac = self._get_hmac() params['SignatureMethod'] = self.algorithm() if self._provider.security_token: params['SecurityToken'] = self._provider.security_token keys = sorted(params.keys()) pairs = [] for key in keys: val = boto.utils.get_utf8_value(params[key]) pairs.append(urllib.quote(key, safe='') + '=' + urllib.quote(val, safe='-_~')) qs = '&'.join(pairs) boto.log.debug('query string: %s' % qs) string_to_sign += qs boto.log.debug('string_to_sign: %s' % string_to_sign) hmac.update(string_to_sign) b64 = base64.b64encode(hmac.digest()) boto.log.debug('len(b64)=%d' % len(b64)) boto.log.debug('base64 encoded digest: %s' % b64) return (qs, b64)
def hash(self, msg: bytes) -> bytes: return hmac.digest(self._cookie, msg, self.digest)
def sign_string(self, to_sign): hmac = self.hmac.copy() hmac.update(to_sign) return base64.b64encode(hmac.digest())
def hash(self, value): hmac = self.newHMAC() hmac.update(value) return hmac.digest()
def s3_authorization(self, headers, verb, path): c_string = boto.utils.canonical_string(verb, path, headers) hmac = self.hmac.copy() hmac.update(c_string) b64_hmac = base64.encodestring(hmac.digest()).strip() return b64_hmac
def hmac_oneshot(key: bytes, msg: bytes, digest) -> bytes: if hasattr(hmac, 'digest'): # requires python 3.7+; faster return hmac.digest(key, msg, digest) else: return hmac.new(key, msg, digest).digest()