def _salsa_encrypt(plaintext, dict_key): if(type(dict_key) == str): dict_key = dict_key.encode("utf8") assert(type(dict_key) == bytes) assert(type(plaintext) == bytes) encrypt_key = ripemd128(dict_key) s20 = Salsa20(key=encrypt_key,IV=b"\x00"*8,rounds=8) return s20.encryptBytes(plaintext)
def parse(self, xml): if xml == None: self.status['error'] = 3 return None xml_root = ET.fromstring(xml) salsa_buffer = bytearray() iv = bytes([0xE8, 0x30, 0x09, 0x4B, 0x97, 0x20, 0x5D, 0x2A]) key = hashlib.sha256( self.database.header['protected_stream_key']).digest() salsa = Salsa20(key, iv) salsa.setCounter(0) for xml_entry in xml_root.iter('Entry'): need_decryption = False entry = {} entry['uid'] = xml_entry[0].text data = {} for child in xml_entry: if child.tag == "String" and child[1].text != None: data[child[0].text] = child[1].text if len(child[1].attrib ) > 0 and child[1].attrib['Protected'] != None: # Salsa20 if self.database.header['inner_random_stream_id'] == 2: encoded = base64.b64decode(child[1].text) length = len(encoded) # Assure we have an enought buffer for the value while length > len(salsa_buffer): new_salsa = salsa.encryptBytes( bytes(bytearray(64))) salsa_buffer.extend(new_salsa) # xor the encoded value with result = bytearray() for a, b in zip(bytearray(encoded), bytearray(salsa_buffer[:length])): result.append(a ^ b) # Replace the existing value with the decoded one data[child[0].text] = result.decode('utf-8') del salsa_buffer[:length] entry['data'] = data self.entries.append(entry) return self.entries
def __init__(self, unprotect=True): self._salsa_buffer = bytearray() self.salsa = Salsa20(sha256(self.header.ProtectedStreamKey), KDB4_SALSA20_IV) self.in_buffer.seek(0) # self.tree = objectify.parse(self.in_buffer) # self.obj_root = self.tree.getroot() self.obj_root = ElementTree.fromstring(self.in_buffer.read()) if unprotect: self.unprotect()
def encrypt_key(dict_key, email): """ Generates a hexadecimal key for use with the official MDict program. dict_key and email should be of type bytes (representing ascii strings), and outfile should be a file open for writing in text mode. Returns a string of 32 hexadecimal digits. This should be placed in a file of its own, with the same name and location as the mdx file but the extension changed to '.key'. """ email_digest = ripemd128(email) dict_key_digest = ripemd128(dict_key) s20 = Salsa20(key=email_digest,IV=b"\x00"*8,rounds=8) output_key = s20.encryptBytes(dict_key_digest) return _hexdump(output_key)
def encrypt_key(dict_key, **kwargs): """ Generates a hexadecimal key for use with the official MDict program. Parameters: dict_key: a bytes object, representing the dictionary password. Keyword parameters: Exactly one of email and device_id should be specified. They should be unicode strings, representing either the user's email address, or the device ID of the machine on which the dictionary is to be opened. Return value: a string of 32 hexadecimal digits. This should be placed in a file of its own, with the same name and location as the mdx file but the extension changed to '.key'. Example usage: key = encrypt_key(b"password", email="*****@*****.**") key = encrypt_key(b"password", device_id="12345678-9012-3456-7890-1234") """ if (("email" not in kwargs and "device_id" not in kwargs) or ("email" in kwargs and "device_id" in kwargs)): raise ParameterError( "Expected exactly one of email and device_id as keyword argument") if "email" in kwargs: owner_info_digest = ripemd128(kwargs["email"].encode("ascii")) else: owner_info_digest = ripemd128(kwargs["device_id"].encode("ascii")) dict_key_digest = ripemd128(dict_key) s20 = Salsa20(key=owner_info_digest, IV=b"\x00" * 8, rounds=8) output_key = s20.encryptBytes(dict_key_digest) return _hexdump(output_key)
def _decrypt_regcode_by_email(reg_code, email): email_digest = ripemd128(email.decode().encode('utf-16-le')) s20 = Salsa20(key=email_digest, IV=b"\x00" * 8, rounds=8) encrypt_key = s20.encryptBytes(reg_code) return encrypt_key
def _decrypt_regcode_by_deviceid(reg_code, deviceid): deviceid_digest = ripemd128(deviceid) s20 = Salsa20(key=deviceid_digest, IV=b"\x00" * 8, rounds=8) encrypt_key = s20.encryptBytes(reg_code) return encrypt_key
def _salsa_decrypt(ciphertext, encrypt_key): s20 = Salsa20(key=encrypt_key, IV=b"\x00" * 8, rounds=8) return s20.encryptBytes(ciphertext)
def _salsa_decrypt(ciphertext, dict_key): assert (type(ciphertext) == bytes) assert (type(dict_key) == bytes) decrypt_key = ripemd128(dict_key) s20 = Salsa20(key=decrypt_key, IV=b"\x00" * 8, rounds=8) return s20.encryptBytes(ciphertext)