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 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 __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 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 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 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 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 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 __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 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 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 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 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 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 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 __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 _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()
def get_secret(awsclient, name, version="", region_name=None, table="credential-store", context=None, **kwargs): ''' fetch and decrypt the secret called `name` ''' if context is None: context = {} client_ddb = awsclient.get_client('dynamodb', region_name) client_kms = awsclient.get_client('kms', region_name) if version == "": # do a consistent fetch of the credential with the highest version # note KeyConditionExpression: Key("name").eq(name)) response = client_ddb.query( TableName=table, Limit=1, ScanIndexForward=False, ConsistentRead=True, KeyConditionExpression='#S = :val', ExpressionAttributeNames={'#S': 'name'}, ExpressionAttributeValues={':val': {'S': name}} ) if response["Count"] == 0: raise ItemNotFound("Item {'name': '%s'} couldn't be found." % name) material = response["Items"][0] else: response = client_ddb.get_item( TableName=table, Key={ "name": {'S': name}, "version": {'S': 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 = client_kms.decrypt(CiphertextBlob=b64decode(material['key']['S']), 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 GracefulExit: raise 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']['S']), digestmod=SHA256) if hmac.hexdigest() != material['hmac']['S']: 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']['S'])).decode( "utf-8") return plaintext