def encrypt(self, plaintext, context=None): if not context: context = {} session = Session(profile_name=self.profile_name) kms = session.client('kms', region_name=self.region) kms_response = kms.generate_data_key( KeyId=self.kms_key, EncryptionContext=context, NumberOfBytes=64, ) data_key = kms_response['Plaintext'][:32] hmac_key = kms_response['Plaintext'][32:] wrapped_key = kms_response['CiphertextBlob'] enc_ctr = Counter.new(128) encryptor = AES.new(data_key, AES.MODE_CTR, counter=enc_ctr) c_text = encryptor.encrypt(plaintext) # compute an HMAC using the hmac key and the ciphertext hmac = HMAC(hmac_key, msg=c_text, digestmod=SHA256) b64hmac = hmac.hexdigest() return EncryptedValue( b64encode(wrapped_key).decode('utf-8'), b64encode(c_text).decode('utf-8'), b64hmac, )
def _hmacedString(key, string): """ Return the SHA-1 HMAC hash of the given key and string. """ hash = HMAC(key, digestmod=sha) hash.update(string) return hash.digest()
def closeAuction(): key = decrypt(request.form['key']) check_for_replay_attack(key) data = json.loads(decrypt_sym(request.form['symdata'], key)) received_mac = request.form['signature'] mac = HMAC(key, msg=request.form['symdata'], digestmod=SHA256) if (received_mac != mac.hexdigest()): return 'Data Integrity Compromised!' creator = json.loads(data['user']) auction = data['serial_number'] if not confirmSignature(creator["Certificate"], creator["Signature"]): return "Auction not created: User not authenticated." r = s.post(auction_repository_add + '/close_auction', data={ 'serial_number': auction, 'user': creator['BI'] }) return r.text
def getSecret(name, version="", region="us-east-1", table="credential-store"): ''' fetch and decrypt the secret called `name` ''' secretStore = Table(table, connection=boto.dynamodb2.connect_to_region(region)) if version == "": # do a consistent fetch of the credential with the highest version result_set = [x for x in secretStore.query_2(limit=1, reverse=True, consistent=True, name__eq=name)] if not result_set: raise ItemNotFound("Item {'name': '%s'} couldn't be found." % name) material = result_set[0] else: material = secretStore.get_item(name=name, version=version) kms = boto.kms.connect_to_region(region) # Check the HMAC before we decrypt to verify ciphertext integrity try: kms_response = kms.decrypt(b64decode(material['key'])) except: raise KmsError("Could not decrypt hmac key with KMS") key = kms_response['Plaintext'][:32] hmac_key = kms_response['Plaintext'][32:] hmac = HMAC(hmac_key, msg=b64decode(material['contents']), digestmod=SHA256) if hmac.hexdigest() != material['hmac']: raise IntegrityError("Computed HMAC on %s does not match stored HMAC" % name) dec_ctr = Counter.new(128) decryptor = AES.new(key, AES.MODE_CTR, counter=dec_ctr) plaintext = decryptor.decrypt(b64decode(material['contents'])) return plaintext
def __init__(self, stash_key, manager_provider, aws_profile=None, aws_region=None, aws_bucket=None): check_latest_version() self._aws_manager = manager_provider.aws_manager(aws_profile, aws_region or 'us-east-1') if aws_bucket is None: deployment_bucket_name = 'novastash_%s' % self._aws_manager.account_alias else: deployment_bucket_name = aws_bucket key = "%s.txt.enc" % stash_key existing_stash = self._aws_manager.s3_get(deployment_bucket_name, key) if existing_stash is None: raise NovaError("No stash '%s' found!" % stash_key) else: contents = existing_stash['Body'].read() metadata = existing_stash['Metadata'] encryption_key = metadata['encryption-key'] kms_response = self._aws_manager.kms_decrypt(b64decode(encryption_key), {}) key = kms_response['Plaintext'][:32] hmac_key = kms_response['Plaintext'][32:] hmac = HMAC(hmac_key, msg=b64decode(contents), digestmod=SHA256) if hmac.hexdigest() != metadata['hmac']: raise NovaError("Computed HMAC on '%s' does not match stored HMAC" % stash_key) dec_ctr = Counter.new(128) decryptor = AES.new(key, AES.MODE_CTR, counter=dec_ctr) print(decryptor.decrypt(b64decode(contents)).decode("utf-8"))
def putSecret(name, secret, version, kms_key="alias/credstash", region="us-east-1", context=None): ''' put a secret called `name` into the secret-store, protected by the key kms_key ''' if not context: context = {} kms = boto3.client('kms', region_name=region) # generate a a 64 byte key. # Half will be for data encryption, the other half for HMAC # try: kms_response = kms.generate_data_key(KeyId=kms_key, EncryptionContext=context, NumberOfBytes=64) # except: # raise KmsError("Could not generate key using KMS key %s" % kms_key) data_key = kms_response['Plaintext'][:32] hmac_key = kms_response['Plaintext'][32:] wrapped_key = kms_response['CiphertextBlob'] enc_ctr = Counter.new(128) encryptor = AES.new(data_key, AES.MODE_CTR, counter=enc_ctr) c_text = encryptor.encrypt(secret) # compute an HMAC using the hmac key and the ciphertext hmac = HMAC(hmac_key, msg=c_text, digestmod=SHA256) b64hmac = hmac.hexdigest() data = {} data['name'] = name data['version'] = version if version != "" else "1" data['key'] = b64encode(wrapped_key).decode('utf-8') data['contents'] = b64encode(c_text).decode('utf-8') data['hmac'] = b64hmac with open('{0}.{1}.json'.format(name,data['version']), 'w') as fp: json.dump(data, fp)
def decrypt(self, value, context=None): if not context: context = {} session = Session(profile_name=self.profile_name) kms = session.client('kms', region_name=self.region) # Check the HMAC before we decrypt to verify ciphertext integrity kms_response = kms.decrypt( CiphertextBlob=b64decode(value.key), EncryptionContext=context, ) key = kms_response['Plaintext'][:32] hmac_key = kms_response['Plaintext'][32:] hmac = HMAC( hmac_key, msg=b64decode(value.contents), digestmod=SHA256, ) if hmac.hexdigest() != value.hmac: raise Exception("Computed HMAC does not match stored HMAC") dec_ctr = Counter.new(128) decryptor = AES.new(key, AES.MODE_CTR, counter=dec_ctr) plaintext = decryptor.decrypt(b64decode( value.contents)).decode("utf-8") return plaintext
def putSecret(name, secret, version, kms_key="alias/credstash", region="us-east-1", table="credential-store", context=None): ''' put a secret called `name` into the secret-store, protected by the key kms_key ''' kms = boto.kms.connect_to_region(region) # generate a a 64 byte key. # Half will be for data encryption, the other half for HMAC try: kms_response = kms.generate_data_key(kms_key, context, 64) except: raise KmsError("Could not generate key using KMS key %s" % kms_key) data_key = kms_response['Plaintext'][:32] hmac_key = kms_response['Plaintext'][32:] wrapped_key = kms_response['CiphertextBlob'] enc_ctr = Counter.new(128) encryptor = AES.new(data_key, AES.MODE_CTR, counter=enc_ctr) c_text = encryptor.encrypt(secret) # compute an HMAC using the hmac key and the ciphertext hmac = HMAC(hmac_key, msg=c_text, digestmod=SHA256) b64hmac = hmac.hexdigest() secretStore = Table(table, connection=boto.dynamodb2.connect_to_region(region)) data = {} data['name'] = name data['version'] = version if version != "" else "1" data['key'] = b64encode(wrapped_key) data['contents'] = b64encode(c_text) data['hmac'] = b64hmac return secretStore.put_item(data=data)
def getSecret(name, version="", region=None, table="credential-store", context=None, **kwargs): ''' fetch and decrypt the secret called `name` ''' if not context: context = {} session = get_session(**kwargs) dynamodb = session.resource('dynamodb', region_name=region) secrets = dynamodb.Table(table) if version == "": # do a consistent fetch of the credential with the highest version response = secrets.query(Limit=1, ScanIndexForward=False, ConsistentRead=True, KeyConditionExpression=boto3.dynamodb.conditions.Key("name").eq(name)) if response["Count"] == 0: raise ItemNotFound("Item {'name': '%s'} couldn't be found." % name) material = response["Items"][0] else: response = secrets.get_item(Key={"name": name, "version": version}) if "Item" not in response: raise ItemNotFound("Item {'name': '%s', 'version': '%s'} couldn't be found." % (name, version)) material = response["Item"] kms = session.client('kms', region_name=region) # Check the HMAC before we decrypt to verify ciphertext integrity try: kms_response = kms.decrypt(CiphertextBlob=b64decode(material['key']), EncryptionContext=context) except botocore.exceptions.ClientError as e: if e.response["Error"]["Code"] == "InvalidCiphertextException": if context is None: msg = ("Could not decrypt hmac key with KMS. The credential may " "require that an encryption context be provided to decrypt " "it.") else: msg = ("Could not decrypt hmac key with KMS. The encryption " "context provided may not match the one used when the " "credential was stored.") else: msg = "Decryption error %s" % e raise KmsError(msg) except Exception as e: raise KmsError("Decryption error %s" % e) key = kms_response['Plaintext'][:32] hmac_key = kms_response['Plaintext'][32:] hmac = HMAC(hmac_key, msg=b64decode(material['contents']), digestmod=SHA256) if hmac.hexdigest() != material['hmac']: raise IntegrityError("Computed HMAC on %s does not match stored HMAC" % name) dec_ctr = Counter.new(128) decryptor = AES.new(key, AES.MODE_CTR, counter=dec_ctr) plaintext = decryptor.decrypt(b64decode(material['contents'])).decode("utf-8") return plaintext
def wrap(data, authKey, keyWrapKey): hmac = HMAC(authKey, digestmod=SHA256) hmac.update(data) kwa = hmac.digest()[:8] iv = os.urandom(16) cipher = AES.new(keyWrapKey, AES.MODE_CBC, iv) wrapped = cipher.encrypt(pad(data + kwa)) wrapped = wrapped + iv return wrapped
def getSecret(name, kms, dynamodb, version="", table="credential-store", context=None): ''' fetch and decrypt the secret called `name` ''' if not context: context = {} secrets = dynamodb.Table(table) if version == "": # do a consistent fetch of the credential with the highest version response = secrets.query(Limit=1, ScanIndexForward=False, ConsistentRead=True, KeyConditionExpression=boto3.dynamodb.conditions.Key("name").eq(name)) if response["Count"] == 0: raise ItemNotFound("Item {'name': '%s'} couldn't be found." % name) material = response["Items"][0] else: response = secrets.get_item(Key={"name": name, "version": version}) if "Item" not in response: raise ItemNotFound("Item {'name': '%s', 'version': '%s'} couldn't be found." % (name, version)) material = response["Item"] # Check the HMAC before we decrypt to verify ciphertext integrity try: kms_response = kms.decrypt(CiphertextBlob=b64decode(material['key']), EncryptionContext=context) except botocore.exceptions.ClientError as e: if e.response["Error"]["Code"] == "InvalidCiphertextException": if context is None: msg = ("Could not decrypt hmac key with KMS. The credential may " "require that an encryption context be provided to decrypt " "it.") else: msg = ("Could not decrypt hmac key with KMS. The encryption " "context provided may not match the one used when the " "credential was stored.") else: msg = "Decryption error %s" % e raise KmsError(msg) except Exception as e: raise KmsError("Decryption error %s" % e) key = kms_response['Plaintext'][:32] hmac_key = kms_response['Plaintext'][32:] hmac = HMAC(hmac_key, msg=b64decode(material['contents']), digestmod=SHA256) if hmac.hexdigest() != material['hmac']: raise IntegrityError("Computed HMAC on %s does not match stored HMAC" % name) dec_ctr = Counter.new(128) decryptor = AES.new(key, AES.MODE_CTR, counter=dec_ctr) plaintext = decryptor.decrypt(b64decode(material['contents'])).decode("utf-8") return plaintext
def getSecret(name, version="", region="us-east-1", table="credential-store", context=None): ''' fetch and decrypt the secret called `name` ''' if not context: context = {} if version == "": # do a consistent fetch of the credential with the highest version # list all files matching pattern pass # if not result_set: # raise ItemNotFound("Item {'name': '%s'} couldn't be found." % name) # material = result_set[0] with open("{0}.{1}.json".format(name, version), 'r') as fp: material = json.load(fp) kms = boto3.client('kms', region_name=region) # Check the HMAC before we decrypt to verify ciphertext integrity try: kms_response = kms.decrypt(CiphertextBlob=b64decode(material['key']), EncryptionContext=context) except InvalidCiphertextException: if context is None: msg = ("Could not decrypt hmac key with KMS. The credential may " "require that an encryption context be provided to decrypt " "it.") else: msg = ("Could not decrypt hmac key with KMS. The encryption " "context provided may not match the one used when the " "credential was stored.") raise KmsError(msg) except Exception as e: raise KmsError("Decryption error %s" % e) key = kms_response['Plaintext'][:32] hmac_key = kms_response['Plaintext'][32:] hmac = HMAC(hmac_key, msg=b64decode(material['contents']), digestmod=SHA256) if hmac.hexdigest() != material['hmac']: raise IntegrityError("Computed HMAC on %s does not match stored HMAC" % name) dec_ctr = Counter.new(128) decryptor = AES.new(key, AES.MODE_CTR, counter=dec_ctr) plaintext = decryptor.decrypt(b64decode( material['contents'])).decode("utf-8") return plaintext
def getSecret(name, version="", region="us-east-1", table="credential-store", context=None): ''' fetch and decrypt the secret called `name` ''' if not context: context = {} secretStore = Table(table, connection=boto.dynamodb2.connect_to_region(region)) if version == "": # do a consistent fetch of the credential with the highest version result_set = [ x for x in secretStore.query_2( limit=1, reverse=True, consistent=True, name__eq=name) ] if not result_set: raise ItemNotFound("Item {'name': '%s'} couldn't be found." % name) material = result_set[0] else: material = secretStore.get_item(name=name, version=version) kms = boto3.client('kms', region_name=region) # Check the HMAC before we decrypt to verify ciphertext integrity try: kms_response = kms.decrypt(CiphertextBlob=b64decode(material['key']), EncryptionContext=context) except boto.kms.exceptions.InvalidCiphertextException: if context is None: msg = ("Could not decrypt hmac key with KMS. The credential may " "require that an encryption context be provided to decrypt " "it.") else: msg = ("Could not decrypt hmac key with KMS. The encryption " "context provided may not match the one used when the " "credential was stored.") raise KmsError(msg) except Exception as e: raise KmsError("Decryption error %s" % e) key = kms_response['Plaintext'][:32] hmac_key = kms_response['Plaintext'][32:] hmac = HMAC(hmac_key, msg=b64decode(material['contents']), digestmod=SHA256) if hmac.hexdigest() != material['hmac']: raise IntegrityError("Computed HMAC on %s does not match stored HMAC" % name) dec_ctr = Counter.new(128) decryptor = AES.new(key, AES.MODE_CTR, counter=dec_ctr) plaintext = decryptor.decrypt(b64decode( material['contents'])).decode("utf-8") return plaintext
def __init__(self, stash_key, value, manager_provider, aws_profile=None, aws_region=None, aws_bucket=None, kms_key='alias/novastash'): check_latest_version() self._aws_manager = manager_provider.aws_manager(aws_profile, aws_region or 'us-east-1') if aws_bucket is None: deployment_bucket_name = 'novastash_%s' % self._aws_manager.account_alias else: deployment_bucket_name = aws_bucket if not self._aws_manager.kms_key_exists(kms_key): raise NovaError("Please setup the novastash KMS key.") self._aws_manager.create_bucket(deployment_bucket_name, "Creating novastash bucket '%s'" % deployment_bucket_name) # generate a a 64 byte key. # Half will be for data encryption, the other half for HMAC kms_response = self._aws_manager.kms_generate_data_key(kms_key, {}) data_key = tobytes(kms_response['Plaintext'][:32]) hmac_key = tobytes(kms_response['Plaintext'][32:]) wrapped_key = tobytes(kms_response['CiphertextBlob']) enc_ctr = Counter.new(128) encryptor = AES.new(data_key, AES.MODE_CTR, counter=enc_ctr) c_text = encryptor.encrypt(tobytes(value)) # compute an HMAC using the hmac key and the ciphertext hmac = HMAC(hmac_key, msg=c_text, digestmod=SHA256) b64hmac = hmac.hexdigest() key = "%s.txt.enc" % stash_key existing_stash = self._aws_manager.s3_head(deployment_bucket_name, key) if existing_stash is None: print(colored("Stashing '%s'" % stash_key)) self._aws_manager.s3_put( deployment_bucket_name, b64encode(c_text).decode('utf-8'), key, {'encryption-key': b64encode(wrapped_key).decode('utf-8'), 'hmac': b64hmac} ) else: perform_overwrite = query_yes_no("Stash '%s' already exists, want to overwrite?" % stash_key, default="no") if perform_overwrite: self._aws_manager.s3_put( deployment_bucket_name, b64encode(c_text).decode('utf-8'), key, {'encryption-key': b64encode(wrapped_key).decode('utf-8'), 'hmac': b64hmac} ) else: print(colored("Not stashing anything for key '%s'" % stash_key))
def place_bid(): key = decrypt(request.form['key']) check_for_replay_attack(key) data = json.loads(decrypt_sym(request.form['symdata'], key)) received_mac = request.form['signature'] mac = HMAC(key, msg=request.form['symdata'], digestmod=SHA256) if (received_mac != mac.hexdigest()): return 'Data Integrity Compromised!' serial_number = data['serial_number'] auction = get_auction(serial_number) if auction == None: return json.dumps("Auction does not exist") if auction.state == "Closed": return json.dumps("Bid refused") block = get_block_from_dict(json.loads(data['block'])) nonce = data['nonce'] if not block.verifyNonce(nonce, auction.chalenge): return json.dumps("Bid refused") r = s.post(auction_manager_add + '/bid_authenticate', data={ 'encrypted_user_data': request.form['encrypted_user_data'], 'user_mac': request.form['user_mac'], 'user_key': request.form['user_key'], 'auction': auction.serial_number, 'value': block.bid.value }) if r.text == 'False': return json.dumps("User authentication Failed") if r.text == 'Invalid': return json.dumps("Invalid value") bid_data = json.loads(r.text) block.bid.user = base64_decode(bid_data['user'].encode()) block.bid.value = base64_decode(bid_data['value'].encode()) if auction.auction_type == "English Auction" and auction.get_last_block( ).bid: if (auction.get_last_block().bid.value >= block.bid.value): return json.dumps( "Bid not added: Value must be higher than highest bid") auction.add_block(block) receipt = createReceipt(block) return json.dumps(("Bid added", receipt))
def compute_hash(key, pkt, pre=None, post=None): if (pre): h = HMAC(key, pre, Crypto.Hash.SHA) h.update(pkt) else: h = HMAC(key, pkt, Crypto.Hash.SHA) if post: h.update(post) return h.digest()
def putSecret(name, secret, version, kms_key="alias/credstash", region=None, table="credential-store", context=None, digest="SHA256", **kwargs): ''' put a secret called `name` into the secret-store, protected by the key kms_key ''' if not context: context = {} session = get_session(**kwargs) kms = session.client('kms', region_name=region) # generate a a 64 byte key. # Half will be for data encryption, the other half for HMAC try: kms_response = kms.generate_data_key(KeyId=kms_key, EncryptionContext=context, NumberOfBytes=64) except: raise KmsError("Could not generate key using KMS key %s" % kms_key) data_key = kms_response['Plaintext'][:32] hmac_key = kms_response['Plaintext'][32:] wrapped_key = kms_response['CiphertextBlob'] enc_ctr = Counter.new(128) encryptor = AES.new(data_key, AES.MODE_CTR, counter=enc_ctr) c_text = encryptor.encrypt(secret) # compute an HMAC using the hmac key and the ciphertext hmac = HMAC(hmac_key, msg=c_text, digestmod=get_digest(digest)) b64hmac = hmac.hexdigest() dynamodb = session.resource('dynamodb', region_name=region) secrets = dynamodb.Table(table) data = {} data['name'] = name data['version'] = version if version != "" else paddedInt(1) data['key'] = b64encode(wrapped_key).decode('utf-8') data['contents'] = b64encode(c_text).decode('utf-8') data['hmac'] = b64hmac data['digest'] = digest return secrets.put_item(Item=data, ConditionExpression=Attr('name').not_exists())
def get_anonymized_user(): """Return the HMAC value of the current user authenticated with the HMAC secret. """ return HMAC(key=config.WEB_SECRET, msg=get_user()).digest()[:9].encode('base64').rstrip()
async def upload_loop(init_buf=None): nonlocal reader, remote_writer, host, port try: buf = init_buf iv_up = random.read(16) crypto_up = AES.new(enc_key, AES.MODE_CFB, iv_up) host = host.encode() req_buf = struct.pack('BB', 0, len(host)) + host + struct.pack( '!H', port) mac = HMAC(mac_key, req_buf).digest()[:12] handshake_buf = iv_up + crypto_up.encrypt(req_buf + mac) while True: if buf == None: buf = await reader.read(65536) if handshake_buf != None: remote_writer.write(handshake_buf) handshake_buf = None if len(buf) == 0: break remote_writer.write(crypto_up.encrypt(buf)) buf = None await remote_writer.drain() except ConnectionResetError as e: pass except Exception as e: print(e) finally: remote_writer.close()
async def do_request(req_counter): global req_session nonlocal req_number, host, port remote_reader, remote_writer = None, None try: iv_up = random.read(16) crypto_up = AES.new(enc_key, AES.MODE_CFB, iv_up) req_buf = struct.pack( 'BB', 1, len(host)) + host.encode() + struct.pack('!H', port) mac = HMAC(mac_key, req_buf).digest()[:12] handshake_buf = iv_up + crypto_up.encrypt(req_buf + mac) remote_reader, remote_writer = await asyncio.open_connection( server_addr, server_port, loop=loop) req_info = req_session + struct.pack( '!QQI', req_number, req_counter, len(modified_req)) remote_writer.write(handshake_buf + crypto_up.encrypt(req_info + modified_req)) iv_down = await remote_reader.readexactly(16) crypto_down = AES.new(enc_key, AES.MODE_CFB, iv_down) result_len, = struct.unpack( '!I', crypto_down.decrypt(await remote_reader.readexactly(4))) result = crypto_down.decrypt(await remote_reader.readexactly(result_len)) remote_writer.close() return result except Exception: if remote_writer != None: remote_writer.close() raise
def get_anonymized_user(): """Return the HMAC value of the current user authenticated with the HMAC secret. """ return utils.encode_b64(HMAC(key=config.WEB_SECRET, msg=get_user()).digest()[:9])
def getSecret(name, version="", region="us-east-1", table="credential-store", context=None): ''' fetch and decrypt the secret called `name` ''' if not context: context = {} secretStore = Table(table, connection=boto.dynamodb2.connect_to_region(region)) if version == "": # do a consistent fetch of the credential with the highest version result_set = [x for x in secretStore.query_2(limit=1, reverse=True, consistent=True, name__eq=name)] if not result_set: raise ItemNotFound("Item {'name': '%s'} couldn't be found." % name) material = result_set[0] else: material = secretStore.get_item(name=name, version=version) kms = boto3.client('kms', region_name=region) # Check the HMAC before we decrypt to verify ciphertext integrity try: kms_response = kms.decrypt(CiphertextBlob=b64decode(material['key']), EncryptionContext=context) except boto.kms.exceptions.InvalidCiphertextException: if context is None: msg = ("Could not decrypt hmac key with KMS. The credential may " "require that an encryption context be provided to decrypt " "it.") else: msg = ("Could not decrypt hmac key with KMS. The encryption " "context provided may not match the one used when the " "credential was stored.") raise KmsError(msg) except Exception as e: raise KmsError("Decryption error %s" % e) key = kms_response['Plaintext'][:32] hmac_key = kms_response['Plaintext'][32:] hmac = HMAC(hmac_key, msg=b64decode(material['contents']), digestmod=SHA256) if hmac.hexdigest() != material['hmac']: raise IntegrityError("Computed HMAC on %s does not match stored HMAC" % name) dec_ctr = Counter.new(128) decryptor = AES.new(key, AES.MODE_CTR, counter=dec_ctr) plaintext = decryptor.decrypt(b64decode(material['contents'])).decode("utf-8") return plaintext
def getSecret(name, version="", region="us-east-1", table="credential-store", context=None): ''' fetch and decrypt the secret called `name` ''' if not context: context = {} if version == "": # do a consistent fetch of the credential with the highest version # list all files matching pattern pass # if not result_set: # raise ItemNotFound("Item {'name': '%s'} couldn't be found." % name) # material = result_set[0] with open("{0}.{1}.json".format(name, version), 'r') as fp: material = json.load(fp) kms = boto3.client('kms', region_name=region) # Check the HMAC before we decrypt to verify ciphertext integrity try: kms_response = kms.decrypt(CiphertextBlob=b64decode(material['key']), EncryptionContext=context) except InvalidCiphertextException: if context is None: msg = ("Could not decrypt hmac key with KMS. The credential may " "require that an encryption context be provided to decrypt " "it.") else: msg = ("Could not decrypt hmac key with KMS. The encryption " "context provided may not match the one used when the " "credential was stored.") raise KmsError(msg) except Exception as e: raise KmsError("Decryption error %s" % e) key = kms_response['Plaintext'][:32] hmac_key = kms_response['Plaintext'][32:] hmac = HMAC(hmac_key, msg=b64decode(material['contents']), digestmod=SHA256) if hmac.hexdigest() != material['hmac']: raise IntegrityError("Computed HMAC on %s does not match stored HMAC" % name) dec_ctr = Counter.new(128) decryptor = AES.new(key, AES.MODE_CTR, counter=dec_ctr) plaintext = decryptor.decrypt(b64decode(material['contents'])).decode("utf-8") return plaintext
def unwrap(data, authKey, keyWrapKey): iv = data[-16:] cipher = AES.new(keyWrapKey, AES.MODE_CBC, iv) unwrapped = cipher.decrypt(data[:-16]) unwrapped = unpad(unwrapped) kwa = unwrapped[-8:] unwrapped = unwrapped[:-8] hmac = HMAC(authKey, digestmod=SHA256) hmac.update(unwrapped) local_kwa = hmac.digest()[:8] if kwa != local_kwa: print("Unwrapped kwa does not match") return unwrapped
def ExtractEntropySeed(rounds, username, password, salt=None): # Concentrates and then extracts the random entropy provided # by the password into a seed value for the first hash stage. # If if an explicit salt value is missing, use a hash of # the username as if it were the salt. if salt is None: salt = SHA512.new(username).digest() # Confirm the supplied salt meets the minimum length of 64 # octets required, is aligned to a 32 octet boundary and does not # exceed 1,024 octets. Some implementations may not handle salt # values longer than 1,024 octets properly. elif len(salt) < 64: raise ValueError("The salt, if supplied, must be at least " \ "64 octets in length.") elif operator.mod(len(salt), 32) != 0: warnings.warn("The salt, if longer than 64 octets, should " \ "be aligned to a 32 octet boundary.") elif len(salt) > 1024: warnings.warn("The salt should not exceed 1,024 octets.") # For salt values which don't match the 128 octets required for # an HMAC key value, the salt is hashed twice using a 3 octet # counter value of 0 and 1, and the outputs are concatenated. if len(salt) != 128: key = \ SHA512.new(salt + struct.pack('>I', 0)[1:4]).digest() + \ SHA512.new(salt + struct.pack('>I', 1)[1:4]).digest() # If the supplied salt is 128 octets use it directly as the key value. else: key = salt # Initialize the HMAC instance using the key created above. hmac = HMAC(key, None, SHA512) # Repeat the plaintext password successively based on # the number of instances specified by the rounds variable. for unused in range(0, rounds): hmac.update(password) # Create the 64 octet seed value. seed = hmac.digest() return seed
def putSecret(name, secret, version, kms_key="alias/credstash", region="us-east-1", table="credential-store", context=None): ''' put a secret called `name` into the secret-store, protected by the key kms_key ''' if not context: context = {} kms = boto3.client('kms', region_name=region) # generate a a 64 byte key. # Half will be for data encryption, the other half for HMAC try: kms_response = kms.generate_data_key(KeyId=kms_key, EncryptionContext=context, NumberOfBytes=64) except: raise KmsError("Could not generate key using KMS key %s" % kms_key) data_key = kms_response['Plaintext'][:32] hmac_key = kms_response['Plaintext'][32:] wrapped_key = kms_response['CiphertextBlob'] enc_ctr = Counter.new(128) encryptor = AES.new(data_key, AES.MODE_CTR, counter=enc_ctr) c_text = encryptor.encrypt(secret) # compute an HMAC using the hmac key and the ciphertext hmac = HMAC(hmac_key, msg=c_text, digestmod=SHA256) b64hmac = hmac.hexdigest() secretStore = Table(table, connection=boto.dynamodb2.connect_to_region(region)) data = {} data['name'] = name data['version'] = version if version != "" else "1" data['key'] = b64encode(wrapped_key).decode('utf-8') data['contents'] = b64encode(c_text).decode('utf-8') data['hmac'] = b64hmac return secretStore.put_item(data=data)
def unlock(self, passphrase): # might eventually implement the following as specced and in a separate module: # http://www.w3.org/TR/2002/REC-xmlenc-core-20021210/Overview.html#aes256-cbc # http://www.w3.org/2008/xmlsec/Drafts/derived-key/derived-keys.xml # https://tools.ietf.org/html/rfc4051 # https://tools.ietf.org/html/rfc6030 # http://www.opensource.apple.com/source/libsecurity_asn1/libsecurity_asn1-29908/asn1/pkcs5.asn1 if self._privateKey: return encryption_elem = self._container.getElementsByTagNameNS(XMLENC_NS_URL, 'EncryptionMethod')[0] # jumping over the structure at the moment, see above derivation_func = PBKDF2 params_elem = encryption_elem.getElementsByTagNameNS(PKCS5_NS_URL, 'Parameters')[0] salt_elem = params_elem.getElementsByTagNameNS(PKCS5_NS_URL, 'Salt')[0] IV = salt = b64decode(salt_elem.firstChild.firstChild.nodeValue) iterations_elem = params_elem.getElementsByTagNameNS(PKCS5_NS_URL, 'IterationCount')[0] iterations = int(iterations_elem.firstChild.nodeValue) key_length_elem = params_elem.getElementsByTagNameNS(PKCS5_NS_URL, 'KeyLength')[0] key_length = int(key_length_elem.firstChild.nodeValue) assert key_length % 8 == 0 prf = lambda p, s: HMAC(p, s, SHA256).digest() key = derivation_func(passphrase, salt, count=iterations, dkLen=(key_length//8), prf=prf) encryption_scheme = AES encryption_mode = AES.MODE_CBC decryptor = encryption_scheme.new(key, mode=encryption_mode, IV=IV) # then the encrypted data key_elem = self._container.getElementsByTagNameNS(XMLENC_NS_URL, 'CipherValue')[0] ciphertext_elem = key_elem.firstChild ciphertext = b64decode(ciphertext_elem.nodeValue) padded_plaintext = decryptor.decrypt(ciphertext) padlen = ord(padded_plaintext[-1]) if padlen not in range(encryption_scheme.block_size) or \ chr(padlen)*padlen != padded_plaintext[-padlen:]: raise KeyLockedError("Key decryption failed") plaintext = padded_plaintext[:-padlen] key_elem = removeIgnorableWhitespace(parseString(plaintext)) keyparams = [RSA.bytes_to_long(b64decode(key_elem.getElementsByTagName(x)[0].firstChild.nodeValue)) for x in ['Modulus', 'Exponent', 'D', 'Q', 'P', 'InverseQ']] self._privateKey = RSA.construct(tuple(keyparams)) self._publicKey = self._privateKey.publickey() self.fingerprint = SHA256.new(self._publicKey.exportKey(format='DER')).hexdigest()
def putSecret(name, secret, version, kms_key="alias/credstash", region=None, table="credential-store", context=None, digest="SHA256", **kwargs): ''' put a secret called `name` into the secret-store, protected by the key kms_key ''' if not context: context = {} session = get_session(**kwargs) kms = session.client('kms', region_name=region) # generate a a 64 byte key. # Half will be for data encryption, the other half for HMAC try: kms_response = kms.generate_data_key( KeyId=kms_key, EncryptionContext=context, NumberOfBytes=64) except: raise KmsError("Could not generate key using KMS key %s" % kms_key) data_key = kms_response['Plaintext'][:32] hmac_key = kms_response['Plaintext'][32:] wrapped_key = kms_response['CiphertextBlob'] enc_ctr = Counter.new(128) encryptor = AES.new(data_key, AES.MODE_CTR, counter=enc_ctr) c_text = encryptor.encrypt(secret) # compute an HMAC using the hmac key and the ciphertext hmac = HMAC(hmac_key, msg=c_text, digestmod=get_digest(digest)) b64hmac = hmac.hexdigest() dynamodb = session.resource('dynamodb', region_name=region) secrets = dynamodb.Table(table) data = {} data['name'] = name data['version'] = version if version != "" else paddedInt(1) data['key'] = b64encode(wrapped_key).decode('utf-8') data['contents'] = b64encode(c_text).decode('utf-8') data['hmac'] = b64hmac data['digest'] = digest return secrets.put_item(Item=data, ConditionExpression=Attr('name').not_exists())
def srtp_sign_packet(auth_key, rtp_packet, roc, hash_function=Crypto.Hash.SHA, hash_length=80): assert (hash_length % 8 == 0) hash_length = hash_length // 8 h = HMAC(auth_key, rtp_packet + int_to_bytes(roc, 4), hash_function).digest() return rtp_packet + h[:hash_length]
def mac_sign(kwargs=None, expires=None, key='', mac_len=0, mac_format='hex'): key = key or config.SIGN_KEY if not key: raise Exception('No key configured for signing the HMAC') if not kwargs: raise Exception('No message provided to be signed') if expires: kwargs['_expires'] = int(time() + expires) parts = ["%s=%s" % (key, kwargs[key]) for key in sorted(kwargs.keys())] msg = "&".join(parts) hmac = HMAC(str(key), msg=str(msg), digestmod=SHA256Hash()) if mac_format == 'b64': tag = urlsafe_b64encode(hmac.digest()).rstrip('=') elif mac_format == 'bin': tag = hmac.digest() else: tag = hmac.hexdigest() if mac_len: tag = tag[:mac_len] kwargs['_mac'] = tag
def srtcp_sign_packet(auth_key, rtcp_packet, index, is_encrypted, hash_function=Crypto.Hash.SHA, hash_length=80): assert (hash_length % 8 == 0) hash_length = hash_length // 8 index = index % (2**30) if is_encrypted: index += 1 << 31 index = int_to_bytes(index, 4) h = HMAC(auth_key, rtcp_packet + index, hash_function).digest() return rtcp_packet + index + h[:hash_length]
def srtp_verify_and_strip_signature(auth_key, rtp_packet, roc, hash_function=Crypto.Hash.SHA, hash_length=80): assert hash_length % 8 == 0 hash_length = hash_length // 8 h = HMAC(auth_key, rtp_packet[:-hash_length] + int_to_bytes(roc, 4), hash_function).digest() if h[:hash_length] == rtp_packet[-hash_length:]: return rtp_packet[:-hash_length] else: raise AuthenticationFailure()
def srtcp_verify_and_strip_signature(auth_key, rtcp_packet, hash_function=Crypto.Hash.SHA, hash_length=80): assert hash_length % 8 == 0 hash_length = hash_length // 8 h = HMAC(auth_key, rtcp_packet[:-hash_length], hash_function).digest() if h[:hash_length] == rtcp_packet[-hash_length:]: packet_i = bytes_to_int(rtcp_packet[-hash_length - 4:-hash_length]) encrypted = packet_i & (1 << 31) != 0 packet_i = packet_i & ((1 << 31) - 1) return rtcp_packet[:-hash_length - 4], packet_i, encrypted else: raise AuthenticationFailure()
def create_auction(): key = decrypt(request.form['key']) data = json.loads(decrypt_sym(request.form['symdata'], key)) received_mac = request.form['signature'] mac = HMAC(key, msg=request.form['symdata'], digestmod=SHA256) if (received_mac != mac.hexdigest()): return 'Data Integrity Compromised!' name = data['name'] time_limit = datetime.strptime(data['timeLimit'], '%b %d %Y %I:%M%p') description = data['description'] auction_type = data['auctionType'] creator = data['creator'] bid_validations = (data['bid_validations'] if 'bid_validdations' in data else None) serial_number = data['serialNumber'] new_auction = auction(name, serial_number, time_limit, description, auction_type, creator, bid_validations) print(new_auction.blocks[0].nonce) now = datetime.now() if now > new_auction.time_limit: _close_auction(new_auction) else: delay = (new_auction.time_limit - now).total_seconds() threading.Timer(delay, _close_auction, [new_auction]).start() auctions.append(new_auction) print(creator) return "Auction Created"
def _verify_user(key, user_data, received_mac): mac = HMAC(key, msg=request.form['encrypted_user_data'], digestmod=SHA256) if (received_mac != mac.hexdigest()): return 'Data Integrity Compromised!' mac = HMAC(key, msg=user_data['encrypted_user_data'], digestmod=SHA256) if (received_mac != mac.hexdigest()): return 'Data Integrity Compromised!' return confirmSignature(user_data['Certificate'], user_data['Signature'])
def createAuction(): key = decrypt(request.form['key']) check_for_replay_attack(key) data = json.loads(decrypt_sym(request.form['symdata'], key)) received_mac = request.form['signature'] mac = HMAC(key, msg=request.form['symdata'], digestmod=SHA256) if (received_mac != mac.hexdigest()): return 'Data Integrity Compromised!' name = data['name'] timeLimit = data['timeLimit'] description = data['description'] auctionType = data['auctionType'] creator = json.loads(data['creator']) if not confirmSignature(creator["Certificate"], creator["Signature"]): return "Auction not created: User not authenticated." try: f = open("serialNumber", "r+") serialNumber = int(f.readline()) f.seek(0, 0) except FileNotFoundError: f = open("serialNumber", "w") serialNumber = 0 f.write(str(serialNumber + 1)) f.close() data = { 'serialNumber': serialNumber, 'name': name, 'timeLimit': timeLimit, 'description': description, 'auctionType': auctionType, 'creator': creator['BI'] } auctions[serialNumber] = (auctionType, Random.get_random_bytes(32)) key = Random.get_random_bytes(32) encrypted = encrypt_sym(json.dumps(data), key) mac = HMAC(key, msg=encrypted, digestmod=SHA256) r = s.post(auction_repository_ip + "/create_auction", data={ 'signature': mac.hexdigest(), 'symdata': encrypted, 'key': encrypt_repo(key) }) return "Auction " + str(serialNumber) + " created\n"
def index(): url_arg = request.args.get('-') if url_arg is not None: _id, _key, _key_hash, iv = b64decode(url_arg).split('||') if _key_hash == HMAC(HASH_KEY, _key).digest(): _aes = AES.new(_KEY, AES.MODE_CBC, _IV) key = _aes.decrypt(_key) encrypted_msg = R.get(_id) if encrypted_msg is not None: R.delete(_id) aes = AES.new(key, AES.MODE_CBC, iv) msg = aes.decrypt(b64decode(encrypted_msg)) return render_template('getMessage.html', message=msg.strip()) else: return render_template('noMessage.html'), 404 return render_template('index.html')
def encrypt(self, data): # získání key a salt key_part = SECRET_ENCRYPTION_KEY[8:] binary_key = binascii.unhexlify(key_part) key, salt = binary_key[:16], binary_key[16:] # Inicializační vektor iv = Random.new().read(AES.block_size) # získání šifry. cipher = AES.new(key, AES.MODE_CBC, iv) # konverze do UTF-8 serialized_data = json.dumps(data).encode('utf-8') # komprese dat serialized_data = zlib.compress(serialized_data, 9) # připojení velikosti dat v bajtech (big-endian) serialized_data = struct.pack('!L', len(serialized_data)) + serialized_data # kontrolní součet digest = HMAC(salt, serialized_data + iv, SHA256Hash()).digest() # padding serialized_data += bytes(16 - len(serialized_data) % 16) # šifrování encrypted_data = cipher.encrypt(serialized_data) str = base64.b64encode(iv + digest + encrypted_data) return str
def _check_hash_match(self, msg, hashed, db): for k in self.get_keys(db): h = HMAC(k[1], msg, self.algorithm) if h.hexdigest() == hashed: return True return False
def encode(self, msg, db): h = HMAC(self.get_current_key(db), msg, self.algorithm) return h.hexdigest()