def runTest(self): data = b"0123" key = b"9" * 32 nonce = b"t" * 8 # Encryption data_mv = memoryview(bytearray(data)) key_mv = memoryview(bytearray(key)) nonce_mv = memoryview(bytearray(nonce)) cipher1 = Salsa20.new(key=key, nonce=nonce) ct = cipher1.encrypt(data) cipher2 = Salsa20.new(key=key_mv, nonce=nonce_mv) key_mv[:1] = b'\xFF' nonce_mv[:1] = b'\xFF' ct_test = cipher2.encrypt(data_mv) self.assertEqual(ct, ct_test) self.assertEqual(cipher1.nonce, cipher2.nonce) # Decryption key_mv = memoryview(bytearray(key)) nonce_mv = memoryview(bytearray(nonce)) ct_mv = memoryview(bytearray(ct)) cipher3 = Salsa20.new(key=key_mv, nonce=nonce_mv) key_mv[:1] = b'\xFF' nonce_mv[:1] = b'\xFF' pt_test = cipher3.decrypt(ct_mv) self.assertEqual(data, pt_test)
def getBadPasswords(encryptedPasswords, key): iv = bytes.fromhex("e830094b97205d2a") s20 = Salsa20.new(key=sha256(key).digest(), nonce=iv) badPWs = [] for site, field, value in encryptedPasswords: encValue = base64.b64decode(value) zeros = b'\x00' * len(encValue) zerosEnc = s20.encrypt(zeros) if field != 'Password': continue pwHash = sha1(bytes([a ^ b for a, b in zip(encValue, zerosEnc) ])).hexdigest().upper() firstFive = pwHash[:5] remainder = pwHash[5:] url = 'https://api.pwnedpasswords.com/range/' reqUrl = url + firstFive req = requests.get(reqUrl) lines = req.text.split('\r\n') hashCounts = dict() for line in lines: h, n = line.split(':') hashCounts[h] = int(n) if remainder in hashCounts: badPWs.append(site) return badPWs
def unprotect_passwords(self): """Unprotect the password fields in the database""" if self.inner_random_stream_id == 2: # Decrypt Salsa20-protected data key = hashlib.sha256(self.inner_random_stream_key).digest() cipher = Salsa20.new(key, SALSA20_NONCE) elif self.inner_random_stream_id == 3: # Decrypt ChaCha20-protected data key_hash = hashlib.sha512(self.inner_random_stream_key).digest() cipher = ChaCha20.new(key=key_hash[:32], nonce=key_hash[32:44]) else: raise NotImplementedError( "Inner random stream variant {} not yet implemented".format( self.inner_random_stream_id)) # Perform like the XPath query //Value[@Protected='True'] for value_elem in self.xml_dom.getElementsByTagName('Value'): if value_elem.firstChild is None: # Empty passwords are skipped continue protected_attr = value_elem.getAttribute('Protected') if not protected_attr: continue if protected_attr != 'True': raise ValueError( "Unexpected Value/Protected attribute value: {}".format( repr(protected_attr))) protected_data_b64 = value_elem.firstChild.data.strip() protected_data = base64.b64decode(protected_data_b64) plain_text_bin = cipher.decrypt(protected_data) plain_text = plain_text_bin.decode(errors='replace') value_elem.firstChild.data = plain_text value_elem.setAttribute('Protected', 'Decrypted')
def xml2lst(xml: ET.Element, key) -> list: '''Restruct the root xml of kdbx to key-val pairs, and prepare plaintext password for clipboard. Return a list, each of whose element is a tuple: ({key: val, key: val, ...}, plainpsw) ''' ss = Salsa20.new(sha256(key).digest(), sal20_nounce) ret = [] for entry in (xml.findall('./Group/Entry') + xml.findall('./Group/Group/Entry')): kv = {} # as ret[*][0] pln = None # plaintext-psw as ret[*][1] # get the "most recent" k-v pairs of this entry, # i.e., note, psw, title, URL, username, etc. for pair in entry.findall('./String'): if pair[0].text == 'Password': # psw found: only the 1st is currently in use; # other old ones need to involve in salsa20. for psw in entry.findall(".//Value[@Protected='True']"): # psw may be empty t = psw.text and ss.decrypt(b64decode(psw.text)) pln = pln or psw.text == pair[1].text and t elif not pair[1].attrib.get('Protected', False): kv[pair[0].text] = pair[1].text ret.append(( kv, pln, )) return ret
def runTest(self): # Encrypt/Decrypt data and test output parameter key = b'4' * 32 nonce = b'5' * 8 cipher = Salsa20.new(key=key, nonce=nonce) pt = b'5' * 16 ct = cipher.encrypt(pt) output = bytearray(16) cipher = Salsa20.new(key=key, nonce=nonce) res = cipher.encrypt(pt, output=output) self.assertEqual(ct, output) self.assertEqual(res, None) cipher = Salsa20.new(key=key, nonce=nonce) res = cipher.decrypt(ct, output=output) self.assertEqual(pt, output) self.assertEqual(res, None) import sys if sys.version[:3] != '2.6': output = memoryview(bytearray(16)) cipher = Salsa20.new(key=key, nonce=nonce) cipher.encrypt(pt, output=output) self.assertEqual(ct, output) cipher = Salsa20.new(key=key, nonce=nonce) cipher.decrypt(ct, output=output) self.assertEqual(pt, output) cipher = Salsa20.new(key=key, nonce=nonce) self.assertRaises(TypeError, cipher.encrypt, pt, output=b'0' * 16) cipher = Salsa20.new(key=key, nonce=nonce) self.assertRaises(TypeError, cipher.decrypt, ct, output=b'0' * 16) shorter_output = bytearray(7) cipher = Salsa20.new(key=key, nonce=nonce) self.assertRaises(ValueError, cipher.encrypt, pt, output=shorter_output) cipher = Salsa20.new(key=key, nonce=nonce) self.assertRaises(ValueError, cipher.decrypt, ct, output=shorter_output)
def decrypt(data, number): enc = base64.b64decode(data) seckey = hashlib.sha256(str(number).encode('utf-8')).digest() nonce = enc[:8] cipher = Salsa20.new(key=seckey, nonce=nonce) ciphertext = enc[8:] plaintext = cipher.decrypt(ciphertext) return base64.b64decode(plaintext)
def encrypt(self, byte_input): """ Takes byte input and returns encrypted input using a key and encryption nonce. :param byte_input: byte string to be encrypted. :return: encrypted string, nonce, and HMAC validation. """ ciphering = Salsa20.new(self.key) validation = HMAC.new(self.hmac_key, msg = ciphering.encrypt(byte_input), digestmod = SHA256) return [ciphering.encrypt(byte_input), ciphering.nonce, validation.hexdigest()]
def generate_salsa20(key, nonce_or_iv): key = key nonce = nonce_or_iv cipher = Salsa20.new(key=key, nonce=nonce) def do_computation(msg: bytes): cipher.encrypt(msg) return do_computation
def pyCrypto(): import Cryptodome from Cryptodome.Cipher import AES, ChaCha20, DES, DES3, ARC2, ARC4, Blowfish, CAST, PKCS1_v1_5, PKCS1_OAEP, ChaCha20_Poly1305, Salsa20 from Cryptodome.PublicKey import ElGamal Cryptodome.Cipher.AES.new() # Noncompliant Cryptodome.Other.AES.new() # OK AES.new(key=key) # Noncompliant ChaCha20.new(key=key) # Noncompliant DES.new(key=key) # Noncompliant DES3.new(key=key) # Noncompliant ARC2.new(key=key) # Noncompliant ARC4.new(key=key) # Noncompliant Blowfish.new(key=key) # Noncompliant CAST.new(key=key) # Noncompliant PKCS1_v1_5.new(key=key) # Noncompliant PKCS1_OAEP.new(key=key) # Noncompliant ChaCha20_Poly1305.new(key=key) # Noncompliant Salsa20.new(key=key) # Noncompliant ElGamal.generate(key_size) # Noncompliant
def runTest(self): # Encrypt/Decrypt data and test output parameter key = b'4' * 32 nonce = b'5' * 8 cipher = Salsa20.new(key=key, nonce=nonce) pt = b'5' * 16 ct = cipher.encrypt(pt) output = bytearray(16) cipher = Salsa20.new(key=key, nonce=nonce) res = cipher.encrypt(pt, output=output) self.assertEqual(ct, output) self.assertEqual(res, None) cipher = Salsa20.new(key=key, nonce=nonce) res = cipher.decrypt(ct, output=output) self.assertEqual(pt, output) self.assertEqual(res, None) import sys if sys.version[:3] != '2.6': output = memoryview(bytearray(16)) cipher = Salsa20.new(key=key, nonce=nonce) cipher.encrypt(pt, output=output) self.assertEqual(ct, output) cipher = Salsa20.new(key=key, nonce=nonce) cipher.decrypt(ct, output=output) self.assertEqual(pt, output) cipher = Salsa20.new(key=key, nonce=nonce) self.assertRaises(TypeError, cipher.encrypt, pt, output=b'0'*16) cipher = Salsa20.new(key=key, nonce=nonce) self.assertRaises(TypeError, cipher.decrypt, ct, output=b'0'*16) shorter_output = bytearray(7) cipher = Salsa20.new(key=key, nonce=nonce) self.assertRaises(ValueError, cipher.encrypt, pt, output=shorter_output) cipher = Salsa20.new(key=key, nonce=nonce) self.assertRaises(ValueError, cipher.decrypt, ct, output=shorter_output)
def decrypt(self, file_path, password): private_key = self.get_private_key(password) if private_key is None: return {'status': False, 'msg': "Cannot get private key"} with open(file_path, 'rb') as fi: try: msg = json.loads(fi.read()) except ValueError: return {'status': False, 'msg': "File structure is damaged"} for key, value in msg.iteritems(): msg[key] = b64decode(value) secret_key = PKCS1_OAEP.new(private_key).decrypt(msg['secret_key']) try: # init cipher if msg['alg'] == ALG_OPTIONS[0]: cipher = AES.new(secret_key, AES.MODE_EAX, msg['nonce']) elif msg['alg'] == ALG_OPTIONS[1]: cipher = AES.new(secret_key, AES.MODE_OCB, msg['nonce']) elif msg['alg'] == ALG_OPTIONS[2]: cipher = AES.new(secret_key, AES.MODE_CFB, msg['iv']) elif msg['alg'] == ALG_OPTIONS[3]: cipher = AES.new(secret_key, AES.MODE_CTR, msg['nonce']) elif msg['alg'] == ALG_OPTIONS[4]: cipher = DES.new(secret_key, DES.MODE_OFB, iv=msg['iv']) elif msg['alg'] == ALG_OPTIONS[5]: cipher = ARC2.new(secret_key, ARC2.MODE_CFB) elif msg['alg'] == ALG_OPTIONS[6]: cipher = ARC4.new(secret_key) elif msg['alg'] == ALG_OPTIONS[7]: cipher = ChaCha20.new(key=secret_key, nonce=msg['nonce']) elif msg['alg'] == ALG_OPTIONS[8]: cipher = Salsa20.new(key=secret_key, nonce=msg['nonce']) else: return {'status': False, 'msg': "Cannot define the algorithm used to encrypt this file"} # decrypt and verify if msg['alg'] in ALG_OPTIONS[1:3]: decrypted_msg = cipher.decrypt_and_verify(msg['cipher_text'], msg['tag']) elif msg['alg'] in ALG_OPTIONS[3:]: decrypted_msg = cipher.decrypt(msg['cipher_text']) SHA256.new(decrypted_msg).hexdigest(), msg['tag'] if SHA256.new(decrypted_msg).hexdigest() != msg['tag']: raise ValueError else: return {'status': False, 'msg': "Cannot define the algorithm used to encrypt this file"} except ValueError, KeyError: return {'status': False, 'msg': "Decrypt failed, you are not the owner of this file"} dir_path, file_name = os.path.split(file_path) with open(dir_path + '/' + msg['file_name'], 'wb') as fo: fo.write(decrypted_msg) return {'status': True, 'msg': "Successfully decrypted file %s" % file_path}
def runTest(self): # Encrypt/Decrypt data and test output parameter key = b'4' * 32 nonce = b'5' * 8 cipher = Salsa20.new(key=key, nonce=nonce) pt = b'5' * 300 ct = cipher.encrypt(pt) output = bytearray(len(pt)) cipher = Salsa20.new(key=key, nonce=nonce) res = cipher.encrypt(pt, output=output) self.assertEqual(ct, output) self.assertEqual(res, None) cipher = Salsa20.new(key=key, nonce=nonce) res = cipher.decrypt(ct, output=output) self.assertEqual(pt, output) self.assertEqual(res, None) output = memoryview(bytearray(len(pt))) cipher = Salsa20.new(key=key, nonce=nonce) cipher.encrypt(pt, output=output) self.assertEqual(ct, output) cipher = Salsa20.new(key=key, nonce=nonce) cipher.decrypt(ct, output=output) self.assertEqual(pt, output) cipher = Salsa20.new(key=key, nonce=nonce) self.assertRaises(TypeError, cipher.encrypt, pt, output=b'0'*len(pt)) cipher = Salsa20.new(key=key, nonce=nonce) self.assertRaises(TypeError, cipher.decrypt, ct, output=b'0'*len(ct)) shorter_output = bytearray(len(pt) - 1) cipher = Salsa20.new(key=key, nonce=nonce) self.assertRaises(ValueError, cipher.encrypt, pt, output=shorter_output) cipher = Salsa20.new(key=key, nonce=nonce) self.assertRaises(ValueError, cipher.decrypt, ct, output=shorter_output)
def encrypt_file(self): to_encrypt = self.parent.textarea.get('1.0', 'end-1c') if State.generated_key_filename and State.generated_key: if State.encrypt_method == 'AES': cipher = AES.new(State.generated_key, AES.MODE_EAX) ciphertext, tag = cipher.encrypt_and_digest( to_encrypt.encode()) token = cipher.nonce + tag + ciphertext elif State.encrypt_method == 'Triple DES': cipher = DES3.new(State.generated_key, DES3.MODE_CFB) token = cipher.iv + cipher.encrypt(to_encrypt.encode()) elif State.encrypt_method == 'Salsa20': cipher = Salsa20.new(key=State.generated_key) token = cipher.nonce + cipher.encrypt(to_encrypt.encode()) else: return messagebox.showerror( title='Key', message= 'Something went wrong. Close the window and try again.') ans = filedialog.asksaveasfilename( parent=self.parent, defaultextension='.txt', filetypes=CONFIG['DEFAULT_FILETYPES'], initialfile=get_filename_from_path(State.filename)) if ans: State.filename = ans with open(State.filename, 'wb') as f: f.write(token) f.close() self.navbar.file_helper.update_title( get_filename_from_path(State.filename)) self.frame_encrypt.destroy() messagebox.showwarning( title='Success', message= 'File was successfully encrypted and saved. Do not lose your key.' ) State.is_modified = False State.generated_key_filename = False State.generated_key = False State.encrypt_method = CONFIG['DEFAULT_ENCRYPTION_METHOD'] else: messagebox.showerror( title='Key', message='You need to generate random key first.')
def decrypt(self, encrypted_input, validate, nonce): """ Decrypts given encrypted message and validates message with HMAC and nonce from encryption. :param encrypted_input: encrypted string to be decrypted. :param validate: HMAC validation byte string. :param nonce: nonce, additional security feature to prevent replay attacks. """ validation = HMAC.new(self.hmac_key, msg = encrypted_input, digestmod = SHA256) try: validation.hexverify(validate) except ValueError: client.disconnect(self) raise Exception("[FAIL]: Message is not authentic, failed HMAC validation!") pass ciphering = Salsa20.new(self.key, nonce = nonce) return ciphering.decrypt(encrypted_input)
def encrypt(self, byte_input): """ Takes byte input and returns encrypted input using a key and encryption nonce. :param byte_input: byte string to be encrypted. :return: encrypted string, nonce, and HMAC validation. """ if isinstance(byte_input, bytes): pass else: byte_input.encode(encoding="ascii", errors="replace") pass ciphering = Salsa20.new(self.key) validation = HMAC.new(self.hmac_key, msg=ciphering.encrypt(byte_input), digestmod=SHA256) return [ ciphering.encrypt(byte_input), ciphering.nonce, validation.hexdigest() ]
def encrypt(self, key: bytes, data: bytes, nonce: Optional[bytes] = None) -> bytes: """ Encrypts buffer using Salsa20 algorithm. :param key: Cryptographic key (16/32 bytes) :type key: bytes :param data: Buffer to be encrypted :type data: bytes :param nonce: Nonce value (8 bytes, defaults to `b"\\\\x00"*8` ) :type nonce: bytes, optional :return: Encrypted data :rtype: bytes """ if nonce is None: nonce = b"\x00" * 8 return Salsa20Cipher.new(key=key, nonce=nonce).encrypt(data)
def decrypt_file(self): if State.encrypt_method and State.filename and State.generated_key: with open(State.filename, 'rb') as f: text = f.read() try: if State.encrypt_method == 'AES': cipher = AES.new(State.generated_key, AES.MODE_EAX, text[:16]) decoded = cipher.decrypt_and_verify( text[32:], text[16:32]).decode() elif State.encrypt_method == 'Triple DES': cipher = DES3.new(State.generated_key, DES3.MODE_CFB) decoded = cipher.decrypt( text)[len(cipher.iv):].decode() elif State.encrypt_method == 'Salsa20': cipher = Salsa20.new(key=State.generated_key, nonce=text[:8]) decoded = cipher.decrypt(text[8:]).decode() else: return messagebox.showerror( title='Error', message='Choose algorithm to decode with') except Exception as e: print(e) return messagebox.showerror( title='Wrong key', message= 'File can not be decoded with this key. Try another one.' ) self.parent.textarea.delete('1.0', 'end-1c') self.parent.textarea.insert('1.0', decoded) self.parent.root.navbar.file_helper.text_modified() self.parent.textarea.see('1.0') self.parent.linenumberingarea.see('1.0') messagebox.showinfo(title='Success', message='File was decoded successfully.') else: messagebox.showerror(title='Error', message='Something went wrong. Try again.')
def get_cipher(self, protected_stream_key): key = hashlib.sha256(protected_stream_key).digest() return Salsa20.new( key=key, nonce=b'\xE8\x30\x09\x4B\x97\x20\x5D\x2A' )
def encrypt(data, number): data = base64.b64encode(data.encode('utf-8')) seckey = hashlib.sha256(str(number).encode('utf-8')).digest() cipher = Salsa20.new(key=seckey) msg = cipher.nonce + cipher.encrypt(data) return base64.b64encode(msg)
def test_default_nonce(self): cipher1 = Salsa20.new(bchr(1) * 16) cipher2 = Salsa20.new(bchr(1) * 16) self.assertEqual(len(cipher1.nonce), 8) self.assertNotEqual(cipher1.nonce, cipher2.nonce)
def encrypt(self, file_path, alg): if alg not in ALG_OPTIONS: return False with open(file_path, 'rb') as fi, open(file_path + ENCRYPT_EXTEND, 'wb') as fo: public_key = self.get_public_key() cipher_rsa = PKCS1_OAEP.new(public_key) plain_text = fi.read() msg = {'alg': alg} if alg == ALG_OPTIONS[0]: secret_key = Random.get_random_bytes(16) cipher = AES.new(secret_key, AES.MODE_EAX) msg.update({'nonce': cipher.nonce}) elif alg == ALG_OPTIONS[1]: secret_key = Random.get_random_bytes(16) cipher = AES.new(secret_key, AES.MODE_OCB) msg.update({'nonce': cipher.nonce}) elif alg == ALG_OPTIONS[2]: secret_key = Random.get_random_bytes(16) iv = Random.new().read(AES.block_size) cipher = AES.new(secret_key, AES.MODE_CFB, iv) msg.update({'iv': iv}) elif alg == ALG_OPTIONS[3]: secret_key = Random.get_random_bytes(16) cipher = AES.new(secret_key, AES.MODE_CTR) msg.update({'nonce': cipher.nonce}) elif alg == ALG_OPTIONS[4]: secret_key = Random.get_random_bytes(8) cipher = DES.new(secret_key, DES.MODE_OFB) msg.update({'iv': cipher.iv}) elif alg == ALG_OPTIONS[5]: secret_key = Random.get_random_bytes(16) cipher = ARC2.new(secret_key, ARC2.MODE_CFB) msg.update({'iv': cipher.iv}) elif alg == ALG_OPTIONS[6]: secret_key = Random.get_random_bytes(40) cipher = ARC4.new(secret_key) elif alg == ALG_OPTIONS[7]: secret_key = Random.get_random_bytes(32) cipher = ChaCha20.new(key=secret_key) msg.update({'nonce': cipher.nonce}) elif alg == ALG_OPTIONS[8]: secret_key = Random.get_random_bytes(32) cipher = Salsa20.new(key=secret_key) msg.update({'nonce': cipher.nonce}) else: return False if alg in ALG_OPTIONS[1:3]: cipher_text, tag = cipher.encrypt_and_digest(plain_text) elif alg in ALG_OPTIONS[3:]: cipher_text = cipher.encrypt(plain_text) tag = SHA256.new(plain_text).hexdigest() else: return False dir_path, file_name = os.path.split(file_path) msg.update({'secret_key': cipher_rsa.encrypt(secret_key), 'cipher_text': cipher_text, 'tag': tag, 'file_name': file_name}) for key, value in msg.iteritems(): msg[key] = b64encode(value).encode('utf-8') fo.write(json.dumps(msg)) return True
def encrypt(key, msg): cipher = Salsa20.new(key=key) return hexlify(cipher.nonce + cipher.encrypt(msg)).decode()
def Salsa20Encrypt(in_string): encryptionkey1 = get_passphrase(32) encryptionkey = str.encode(encryptionkey1) cipher = Salsa20.new(key=encryptionkey) msg = cipher.nonce + cipher.encrypt(in_string.encode('utf-8')) return [msg, encryptionkey1]
def decrypt(key, msg): msg = unhexlify(msg.encode()) nonce = msg[:8] c = msg[8:] cipher = Salsa20.new(key=key, nonce=nonce) return cipher.decrypt(c)
def Salsa20Decrypt(in_string, key): msg_nonce = in_string[:8] ciphertext = in_string[8:] cipher = Salsa20.new(key=key, nonce=msg_nonce) msg = cipher.decrypt(ciphertext) return msg