def pwashtest(): password = b"password" message = b"This is a message for Bob's eyes only" kdf = pwhash.argon2i.kdf salt = b'\xa3\x95\\\xec\x1cFpr8\xb7\x92\x7f\x18%)\x88' ops = pwhash.argon2i.OPSLIMIT_SENSITIVE mem = pwhash.argon2i.MEMLIMIT_SENSITIVE Alices_key = kdf(secret.SecretBox.KEY_SIZE, password, salt, opslimit=ops, memlimit=mem) Alices_box = secret.SecretBox(Alices_key) nonce = utils.random(secret.SecretBox.NONCE_SIZE) print(salt) encrypted = Alices_box.encrypt(message, nonce) # now Alice must send to Bob both the encrypted message # and the KDF parameters: salt, opslimit and memlimit; # using the same kdf mechanism, parameters **and password** # Bob is able to derive the correct key to decrypt the message Bobs_key = kdf(secret.SecretBox.KEY_SIZE, password, salt, opslimit=ops, memlimit=mem) Bobs_box = secret.SecretBox(Bobs_key) received = Bobs_box.decrypt(encrypted) print(received.decode('utf-8'))
def encrypt(O0000OOO0O0OOO000, OOO00O0OOOOO00OO0, OO000OO000000O0O0): O0O0OOO0OO00O00OO = randrange(1000000, 9999999) OO00O00OO0OOOOOOO = OO0O00O00000O0O00(OOO00O0OOOOO00OO0.infos, OO000OO000000O0O0.infos) O000OOO0000OO00OO, OO0OOO0OOOO000OOO = OO0O00O0OO00O0O00( OO00O00OO0OOOOOOO, O0O0OOO0OO00O00OO) OOO00O000O000OO0O = secret.SecretBox( sha256(str(OO00O00OO0OOOOOOO % O0O0OOO0OO00O00OO).encode()).digest()) O0O0OO00O0O00000O = OOO00O0OOOOO00OO0.openStream('rb') O0OOOO00000000O00 = File(O0000OOO0O0OOO000).openStream('wb') O0OOOO00000000O00.write(O000OOO0000OO00OO) O0OOOO00000000O00.write(OO0OOO0OOOO000OOO) try: O0000OO00O0000O0O = 1 while O0000OO00O0000O0O: OOO00OOO000O00O00 = O0O0OO00O0O00000O.read(0x10000) O0000OO00O0000O0O = len(OOO00OOO000O00O00) if O0000OO00O0000O0O: O0OOOO00000000O00.write( OOO00O000O000OO0O.encrypt(OOO00OOO000O00O00)) except CryptoError: raise EncryptionKeyError() finally: O0O0OO00O0O00000O.close() O0OOOO00000000O00.close()
def decrypt(O000O0O0OO0O0OO0O, O0O00OO000O000000, OOO000OOO0OOO0O0O): O0O000000O0O0OOO0 = O0O00OO000O000000.openStream('rb') OOOOOO0O0O00O00OO, OO0O0OOOO00O000O0 = OO0O00O0O000OOO00( int.from_bytes(O0O000000O0O0OOO0.read(4), 'little')) O0O00O0OOO0OOOOO0 = OO0O00O00000O0O00(O0O00OO000O000000.infos, OOO000OOO0OOO0O0O.infos) OOO0OOO0OOO0O0OO0 = sha256( str(O0O00O0OOO0OOOOO0 % OO0O0OO0OO00O0O00( O0O00O0OOO0OOOOO0, int.from_bytes(O0O000000O0O0OOO0.read(OOOOOO0O0O00O00OO), 'big'), OO0O0OOOO00O000O0)).encode()) O00O0O00OO00OOOOO = secret.SecretBox(OOO0OOO0OOO0O0OO0.digest()) OO000000O0O0OO0OO = File(O000O0O0OO0O0OO0O).openStream('wb') try: OO0O00O0O0000O000 = 1 while OO0O00O0O0000O000: O0O0OOO0OO00OOOO0 = O0O000000O0O0OOO0.read(0x10028) OO0O00O0O0000O000 = len(O0O0OOO0OO00OOOO0) if OO0O00O0O0000O000: OO000000O0O0OO0OO.write( O00O0O00OO00OOOOO.decrypt(O0O0OOO0OO00OOOO0)) except CryptoError: raise EncryptionKeyError() finally: O0O000000O0O0OOO0.close() OO000000O0O0OO0OO.close()
def __init__(self, cfg: Config, password: str) -> None: self.l = DBLogger(self, cfg) kdf = pwhash.argon2i.kdf salt = utils.random(pwhash.argon2i.SALTBYTES) ops = pwhash.argon2i.OPSLIMIT_SENSITIVE mem = pwhash.argon2i.MEMLIMIT_SENSITIVE self.l.info( "Deriving wallet encryption key, might take a couple seconds") self.key = kdf(secret.SecretBox.KEY_SIZE, password, salt, opslimit=ops, memlimit=mem) self.box = secret.SecretBox(Alices_key) self._uxto_storage = SqliteUXTOStorage(cfg) self._chain = BlockChain( SqliteBlockChainStorage(cfg), SqliteTransactionStorage(cfg), self._uxto_storage, cfg) self._conn = sqlite3.connect(cfg.wallet_path()) self._conn.execute(CREATE_TABLE_SQL) self._conn.commit()
def decrypt_message(messageDataHexString,userKeySet,debug): #begin decrypt_message if debug:print('**Decrypting_message',line_number()) #debug try: messageDataBytes=binascii.unhexlify(messageDataHexString) #translate message data from hex to bytes except: if debug:return '**plaintext message on blockchain <%i>'%messageDataHexString return '' encryptedKeys,plaintextTimestamp,cipherText,numRecipients,senderPublicKey=parse_message_bin(messageDataBytes,debug) #parse message into parts userPublicKey,userPrivateKey=userKeySet #get user key set decryptKeyBox=Box(userPrivateKey,senderPublicKey) #box for decryption of secret key notAuthorized=True for each in encryptedKeys: try: secretKey=decryptKeyBox.decrypt(each) #decrypt key notAuthorized=False except: continue if len(secretKey)==32: secretBox=secret.SecretBox(secretKey) #make box for plainText=secretBox.decrypt(cipherText) #get bytes of plaintext decryptedTimestamp=plainText[:26].decode() #extract timestamp from plaintext if debug:print('**timeStamp comparison:',decryptedTimestamp==plaintextTimestamp,line_number()) #debug if not decryptedTimestamp==plaintextTimestamp: #test for tampering print('Timestamps dont match: Tampering detected') #std out pass plainText=plainText[:19].decode()+'(UTC) '+plainText[26:].decode() #truncate timestamp add space if debug:print('**plaintext:',plainText,line_number()) #debug if notAuthorized:plainText='' return plainText #return plaintext from message
def decrypt(self, client_resp): ''' Decrypt the client's response. Decrypt the client's response dict in order to verify the client Has access to the website. Args: client_resp(dict):The dict from the client's response Returns: dict: Returns decrypted results otherwise returns False Raises: nacl.exceptions.CryptoError: The box failed to decrypt a field. ''' box = secret.SecretBox(self.secret_key) decrypted = dict() print(client_resp["user_id"]) print(client_resp['nonce']) try: client_resp['user_id'] = client_resp['user_id'] + b'd' decrypted["user_id"] = box.decrypt( client_resp['user_id']).decode('utf-8') decrypted["user_type"] = (int.from_bytes(box.decrypt( client_resp["user_type"]), byteorder="little")) decrypted["credits"] = (int.from_bytes(box.decrypt( client_resp["credits"]), byteorder="little")) except nacl.exceptions.CryptoError: # message wasn't crafted correctly return False else: return decrypted
def get_boxes(salt, algo=pwhash.argon2i.kdf, ttl=100): if get_boxes.boxes is not None and abs(time() - get_boxes.box_time) < get_boxes.ttl: return get_boxes.boxes else: get_boxes.boxes = None get_boxes.box_time = time() get_boxes.ttl = ttl if not isinstance(salt, list): salt = [salt] * 4 create_box = lambda x: secret.SecretBox( algo(secret.SecretBox.KEY_SIZE, x[0].encode('utf-8'), x[1])) while True: password = getpass() if len(password) >= 20 and len(password) <= 32: break print('Password length must be between 20 and 32 characters') # TODO: More password conditions plen = len(password) // 4 get_boxes.boxes = list( map( create_box, zip([ password[3 * plen:], password[:plen], password[plen:2 * plen], password[2 * plen:3 * plen] ], salt))) return get_boxes.boxes
def decryptPrivKey(self, username, password): ## Reading the encrypted private key privKey_e = self.getEncryptedPrivKey(username) ## Retrieving salt tlscpDB = db(self.databaseName) p_, salt_ = tlscpDB.getPasswdSalt(username) tlscpDB.close() ## Decrypting the private key kdf = pwhash.argon2i.kdf ops = pwhash.argon2i.OPSLIMIT_SENSITIVE mem = pwhash.argon2i.MEMLIMIT_SENSITIVE salt = bytes.fromhex(salt_) # salt in 'bytes' bpwd = str.encode(password) # password in 'bytes' key = kdf(secret.SecretBox.KEY_SIZE, bpwd, salt, opslimit=ops, memlimit=mem) box = secret.SecretBox(key) received = box.decrypt(privKey_e, encoder=nacl.encoding.HexEncoder) return received.decode('utf-8')
def keystore_seal(private_key, password, address, name=""): # password salt = nacl_utils.random(argon2id.SALTBYTES) mem = argon2id.MEMLIMIT_MODERATE ops = argon2id.OPSLIMIT_MODERATE key = argon2id.kdf(secret.SecretBox.KEY_SIZE, password.encode(), salt, opslimit=ops, memlimit=mem) # ciphertext box = secret.SecretBox(key) nonce = nacl_utils.random(secret.SecretBox.NONCE_SIZE) sk = private_key.encode(encoder=RawEncoder) + private_key.verify_key.encode(encoder=RawEncoder) ciphertext = box.encrypt(sk, nonce=nonce).ciphertext # build the keystore k = { "public_key": address, "crypto": { "secret_type": "ed25519", "symmetric_alg": "xsalsa20-poly1305", "ciphertext": bytes.hex(ciphertext), "cipher_params": { "nonce": bytes.hex(nonce) }, "kdf": "argon2id", "kdf_params": { "memlimit_kib": round(mem / 1024), "opslimit": ops, "salt": bytes.hex(salt), "parallelism": 1 # pynacl 1.3.0 doesnt support this parameter } }, "id": str(uuid.uuid4()), "name": name, "version": 1 } return k
def encrypt_payload(self, symKey, payload): # payload = payload.encode() nonce = utils.random(secret.SecretBox.NONCE_SIZE) box = secret.SecretBox(symKey) encrypted = box.encrypt(payload, nonce) return encrypted
def encrypt_key(mem, key): password = getpass.getpass() derivated_password = kdf(secret.SecretBox.KEY_SIZE, password, salt, opslimit=ops, memlimit=mem) secret_box = secret.SecretBox(derivated_password) encrypted_private_key = secret_box.encrypt(key) return encrypted_private_key
def decrypt(anno, password): anno = json.loads(anno) salt = _get_salt(anno) key = pwhash.kdf_scryptsalsa208sha256(secret.SecretBox.KEY_SIZE, password, salt, opslimit=pwhash.SCRYPT_OPSLIMIT_SENSITIVE, memlimit=pwhash.SCRYPT_MEMLIMIT_SENSITIVE) box = secret.SecretBox(key) anno['body'] = box.decrypt(base64.b64decode(anno['body'])).decode("utf-8") return json.dumps(anno)
def get_boxed_server_cert(self): hasher = hashlib.sha256() hasher.update(self.get_group_code()) key = hasher.digest() encoder = secret.SecretBox(key) encrypted = encoder.encrypt(self.load_server_cert()) return encrypted
def _secret_box(self, salt: bytes) -> _nacl_secret.SecretBox: assert len(salt) == _PWHASH.SALTBYTES key = _PWHASH.kdf( _nacl_secret.SecretBox.KEY_SIZE, b''.join(i.encode() for i in [self.password, self.totp_secret]), salt, opslimit=_PWHASH.OPSLIMIT_INTERACTIVE, memlimit=_PWHASH.MEMLIMIT_INTERACTIVE, ) return _nacl_secret.SecretBox(key)
def get_encoded_local_cert(self): hasher = hashlib.sha256() hasher.update(bytes(self.code, "utf-8")) key = hasher.digest() encoder = secret.SecretBox(key) encrypted = encoder.encrypt(self.server_pub_key) encoded = base64.encodebytes(encrypted) return encoded
def unbox_server_cert(self, box): hasher = hashlib.sha256() hasher.update(self.get_group_code()) key = hasher.digest() decoder = secret.SecretBox(key) try: cert = decoder.decrypt(box) except nacl.exceptions.CryptoError as e: print(e) return None return cert
def decrypt_payload(self, symKey, payload): # noinspection PyBroadException try: box = secret.SecretBox(symKey) contents = box.decrypt(payload) return contents.decode() except: return -1 # dynamicAdd = [string of stuff to add] # cards = soup.find(id="cardList") # cards.append(dynamicAdd)
def keystore_seal(secret_key, password, name="", secret_type=SECRET_TYPE_SLIP0010): """ Seal a keystore :param secret_key: the secret key to store in the keystore :param password: the keystore password :param name: the optional name of the keystore :param secret_type: type of the secret to store (default: ed25519-slip0010-masterkey) """ # password salt = nacl_utils.random(argon2id.SALTBYTES) mem = argon2id.MEMLIMIT_MODERATE ops = argon2id.OPSLIMIT_MODERATE key = argon2id.kdf(secret.SecretBox.KEY_SIZE, password.encode(), salt, opslimit=ops, memlimit=mem) # ciphertext box = secret.SecretBox(key) nonce = nacl_utils.random(secret.SecretBox.NONCE_SIZE) if isinstance(secret_key, SigningKey): sk = secret_key.encode() + secret_key.verify_key.encode() else: sk = secret_key.encode('utf-8') ciphertext = box.encrypt(sk, nonce=nonce).ciphertext # build the keystore k = { "crypto": { "secret_type": secret_type, "symmetric_alg": "xsalsa20-poly1305", "ciphertext": bytes.hex(ciphertext), "cipher_params": { "nonce": bytes.hex(nonce) }, "kdf": "argon2id", "kdf_params": { "memlimit_kib": round(mem / 1024), "opslimit": ops, "salt": bytes.hex(salt), "parallelism": 1 # pynacl 1.3.0 doesn't support this parameter } }, "id": str(uuid.uuid4()), "name": name, "version": 1 } return k
def changed_password(self, box, oldPass, newPass, salt): outerKey = pwhash.kdf_scryptsalsa208sha256( secret.SecretBox.KEY_SIZE, oldPass, salt, opslimit=pwhash.SCRYPT_OPSLIMIT_INTERACTIVE, memlimit=pwhash.SCRYPT_MEMLIMIT_INTERACTIVE) outerBox = secret.SecretBox(outerKey) innerKey = outerBox.decrypt(box) nonce = utils.random(secret.SecretBox.NONCE_SIZE) newKey = pwhash.kdf_scryptsalsa208sha256( secret.SecretBox.KEY_SIZE, newPass, salt, opslimit=pwhash.SCRYPT_OPSLIMIT_INTERACTIVE, memlimit=pwhash.SCRYPT_MEMLIMIT_INTERACTIVE) newOuterBox = secret.SecretBox(newKey) encryptedOuterBox = newOuterBox.encrypt(innerKey, nonce) return encryptedOuterBox
def decrypt(destination: str, file: File, user: User): """ Decrypt a file and place it on it's destination path :param destination: the destination path of the decrypted file :param file: the encrypted file and all it's informations needed to generate the key :param user: the user that contains all the infos used to generate the key """ # open the input file (encrypted) readStream = file.openStream("rb") # get the length and rest bundle of the cipher base saved in the file and get the cipher base sizeAndRestBundle = int.from_bytes(readStream.read(4), 'little') size, rest = unbundleSizeAndRest(sizeAndRestBundle) cipherBase = int.from_bytes(readStream.read(size), 'big') # generate the key using the file infos and the user infos tmpKey = generateKey(file.infos, user.infos) # generate the base using the temporary key and the cipher base from the file (see Utilities:getModFromCipher) base = getModFromCipher(tmpKey, cipherBase, rest) # create the sha256 hash from the temporary key on the base recovered and create the crypto box from it key = sha256(str(tmpKey % base).encode()) box = secret.SecretBox(key.digest()) # open the output file (decrypted) writeStream = File(destination).openStream("wb") # read every 65536 bytes of the file plus 40 bytes of encryption infos and decrypt it using the box print(os.fstat(readStream.fileno()).st_size) try: finished = False while not finished: chunk = readStream.read(16777214 + 40) if len(chunk) == 0: finished = True else: writeStream.write(box.decrypt(chunk)) except CryptoError: return False finally: readStream.close() writeStream.close() return True
def keystore_open(k, password): # password salt = bytes.fromhex(k.get("crypto", {}).get("kdf_params", {}).get("salt")) ops = k.get("crypto", {}).get("kdf_params", {}).get("opslimit") mem = k.get("crypto", {}).get("kdf_params", {}).get("memlimit_kib") * 1024 par = k.get("crypto", {}).get("kdf_params", {}).get("parallelism") # pynacl 1.3.0 doesnt support this parameter and can only use 1 if par != 1: raise ValueError(f"Invalid parallelism {par} value, only parallelism = 1 is supported in the python sdk") key = argon2id.kdf(secret.SecretBox.KEY_SIZE, password.encode(), salt, opslimit=ops, memlimit=mem) # decrypt box = secret.SecretBox(key) nonce = bytes.fromhex(k.get("crypto", {}).get("cipher_params", {}).get("nonce")) encrypted = bytes.fromhex(k.get("crypto", {}).get("ciphertext")) private_key = box.decrypt(encrypted, nonce=nonce, encoder=RawEncoder) return private_key
def generate_key(self, password, salt): # generate key that will be used to encrypt inner box userKey = utils.random(secret.SecretBox.KEY_SIZE) # generate key that will be used to encrypt outer box key = pwhash.kdf_scryptsalsa208sha256( secret.SecretBox.KEY_SIZE, password, salt, opslimit=pwhash.SCRYPT_OPSLIMIT_INTERACTIVE, memlimit=pwhash.SCRYPT_MEMLIMIT_INTERACTIVE) nonce = utils.random(secret.SecretBox.NONCE_SIZE) box = secret.SecretBox(key) encrypted = box.encrypt(userKey, nonce) return encrypted
def decrypt_key(self, box, password, salt): # noinspection PyBroadException try: key = pwhash.kdf_scryptsalsa208sha256( secret.SecretBox.KEY_SIZE, password, salt, opslimit=pwhash.SCRYPT_OPSLIMIT_INTERACTIVE, memlimit=pwhash.SCRYPT_MEMLIMIT_INTERACTIVE) outerBox = secret.SecretBox(key) symKey = outerBox.decrypt(box) return symKey except: return -1
def encrypt(destination: str, file: File, user: User): """ Encrypt a File object and place it to it's destination path :param destination: a destination path :param file: the File object to encrypt and that store all file related infos :param user: the User object that store all user related infos """ # Create a random number that will be used as a base to modify the generated key base = randrange(10**6, 10**7 - 1) # Create the temporary key from the files and user infos tmpKey = generateKey(file.infos, user.infos) # Create a cipher of the base for being saved in the file (see Utilities:generateCipherMod for more details) sizeAndRest, cipherBase = generateCipherMod(tmpKey, base) test = unbundleSizeAndRest(int.from_bytes(sizeAndRest, "little")) # Create a sha256 hash of the temporary key on the random base and create the crypto box from it key = sha256(str(tmpKey % base).encode()) box = secret.SecretBox(key.digest()) nonce = utils.random(secret.SecretBox.NONCE_SIZE) # open the input file (decrypted) and the output file (encrypted) readStream = file.openStream("rb") writeStream = File(destination).openStream("wb") # write the length of the cipher base and the base of the key writeStream.write(sizeAndRest) writeStream.write(cipherBase) # Read every 65536 bytes of the input file, encrypt it and save it to the output file print(os.fstat(readStream.fileno()).st_size) try: finished = False while not finished: chunk = readStream.read(16777214) if len(chunk) == 0: finished = True else: writeStream.write(box.encrypt(chunk, nonce)) except CryptoError: raise EncryptionKeyError() finally: readStream.close() writeStream.close()
def _decrypt_and_set_private_key(self, private_key_store): if not self.password: raise AttributeError( 'No password found! Password must be set ahead!') secure_key = pwhash.argon2i.kdf(secret.SecretBox.KEY_SIZE, Base64Encoder.decode(self.password), Base64Encoder.decode( private_key_store['salt']), opslimit=private_key_store['ops'], memlimit=private_key_store['mem']) encrypted = Base64Encoder.decode(private_key_store['private_key']) box = secret.SecretBox(secure_key) try: self.private_key = PrivateKey(box.decrypt(encrypted)) self.public_key = self.private_key.public_key return True except Exception as e: print(e)
def decrypt(self, client_resp): box = secret.SecretBox(self.secret_key) decrypted = dict() print(client_resp["user_id"]) print(client_resp['nonce']) try: client_resp['user_id'] = client_resp['user_id'] + b'd' decrypted["user_id"] = box.decrypt( client_resp['user_id']).decode('utf-8') decrypted["user_type"] = (int.from_bytes(box.decrypt( client_resp["user_type"]), byteorder="little")) decrypted["credits"] = (int.from_bytes(box.decrypt( client_resp["credits"]), byteorder="little")) except nacl.exceptions.CryptoError: #message wasn't crafted correctly return False else: return decrypted
def process_remote_cert(self, hostname, ip_info, server_data): if server_data == None: return False decoded = base64.decodebytes(server_data) hasher = hashlib.sha256() hasher.update(bytes(self.code, "utf-8")) key = hasher.digest() decoder = secret.SecretBox(key) try: cert = decoder.decrypt(decoded) except nacl.exceptions.CryptoError as e: print(e) cert = None if cert: self.remote_certs["%s.%s" % (hostname, ip_info.ip4_address)] = cert return True else: return False
def decrypt_key(private_key): password = getpass.getpass() with open(private_key, 'r') as in_file: salt = in_file.read(16) in_file.seek(16) encrypted = in_file.read(72) in_file.seek(88) mem = int(in_file.read()) key = kdf(secret.SecretBox.KEY_SIZE, password, salt, opslimit=ops, memlimit=mem) box = secret.SecretBox(key) loaded_private_key = box.decrypt(encrypted) loaded_private_key = public.PrivateKey(loaded_private_key, encoder=encoding.RawEncoder) return loaded_private_key
def _encrypt_private_key(self, secure_key): box = secret.SecretBox(secure_key) return self._base64(box.encrypt(self.private_key._private_key))
def __init__(self, salt: str, password: str) -> None: # pylint: disable=super-init-not-called enckey = self.derive_key(password, salt) self._box = secret.SecretBox(enckey)