def symmetric_encrypt(key, data): """ Perform symmetric encryption using libsodium secretbox (XSalsa20-Poly1305)) """ nonce = nacl_random(24) data = _convert_to_bytes(data) return SecretBox(key).encrypt(data, nonce)
def _write_header(self, f): file_key = nacl_random(KEY_SIZE) header = self.box.encrypt(file_key) assert len(header) == _header_size(self.box) f.write(header) file_box = nacl_SecretBox(file_key) return file_box
def _write_index_header(self, f, data_length): payload_length = (data_length + _box_overhead(self.index_box)).to_bytes( MANIFEST_INDEX_BYTES, byteorder='big') file_key = nacl_random(KEY_SIZE) header = self.index_box.encrypt(payload_length + file_key) assert len(header) == _header_size( self.index_box) + MANIFEST_INDEX_BYTES f.write(header) file_box = nacl_SecretBox(file_key) return file_box
def __init__(self, mode, user_key, filepath): self.mode = mode self.user_key = user_key self.filepath = filepath self.key = None self.EOF = False self.index = 0 if self.mode == 'ENCRYPT': self.fd = open(filepath, 'wb') self.key = nacl_random(32) self.partial_nonce = nacl_random(16) key = GCE.asymmetric_encrypt(self.user_key, self.key) self.fd.write(key) self.fd.write(self.partial_nonce) else: self.fd = open(filepath, 'rb') x = self.fd.read(80) self.key = GCE.asymmetric_decrypt(self.user_key, x) self.partial_nonce = self.fd.read(16) self.box = SecretBox(self.key)
def _pad_data(self, data): ''' We use zstd skippable frames to pad the data to a round number. Only applicable for data that is < chunk_size, since (1) chunk_size is already a nice round number, (2) we don't really want to pad the middle of the stream anyway ex: data = data + b'\x50\x2A\x4D\x18\x02\x00\x00\x00ab' ''' ll = len(data) if ll < self.chunk_size: pad_length = ll % 256 # 8 bytes for frame header, then pad padding = b'\x50\x2A\x4D\x18' + (pad_length).to_bytes( 4, byteorder='little') + nacl_random(pad_length) return data + padding return data
def generate_key(): """ Generate a 128 bit key """ return nacl_random(32)
def generateRandomKey(): """ Return a random secret of 256bits """ return sha256(nacl_random(32)).decode()
def encode(self, version_str='0.1', payload_encryptor=lambda b,pyld: base64_encode(pyld)): #feels like HACK, may remove defaults """Creates a raw broadcast byte string. :version_str: version being used in form: ('#.#') :payload_encryptor: callback to a function (such as in a node) that takes the broadcast and constructed payload (without encryption) and encrypts the _payload_(not broadcast) as necessary; the result (with encrption or not) must be base 64 encoded. """ if version_str not in ['0.1']: raise ValueError('Invalid version: %s' % version_str) pre_payload = self.payload.raw_bytes if self.kind == 'REQ' and pre_payload== None: props_encoded = [p.encode('utf-8') for p in self.payload.request_prop_names] actions_encoded = [] for action_name, args in self.payload.request_actions.items(): args_join_encoded = b''.join([m_encode(arg) for arg in args]) encoded_action = b'%s(%s)' % ( action_name.encode('utf-8'), args_join_encoded) actions_encoded.append(encoded_action) pre_payload = b','.join(props_encoded+actions_encoded) if (self.kind == 'RESP' or self.kind == 'ANNC') and pre_payload == None: if self.payload.resp_annc_obj: pre_payload = m_encode(self.payload.resp_annc_obj) else: # else there is no payload, make null pre_payload = m_encode(None) # may be encrypted if broadcast 'to' warents it b64d_final_payload = payload_encryptor(self, pre_payload) fill = { b'v': bytes([int(n) for n in version_str.split('.')]), b'nonce': nacl_random(4), b'kind': self.kind.encode('utf-8'), b'to': self.to, b'frm': self.frm, b'payload_b64': b64d_final_payload, b'annc_result': self.annc_result.encode('utf-8') if self.annc_result else b'\x00', b'resp_code': self.resp_code or b'n' } if self.kind == 'REQ': template = b'%(v)s%(nonce)s|%(kind)s|%(to)s|%(frm)s|%(payload_b64)s|%(annc_result)s' elif self.kind == 'ANNC': template = b'%(v)s%(nonce)s|%(kind)s|%(to)s|%(frm)s|%(payload_b64)s' elif self.kind == 'RESP': template = b'%(v)s%(nonce)s|%(kind)s|%(to)s|%(frm)s|%(resp_code)s|%(payload_b64)s' return template % fill