Closed KeerthiNaathan closed 4 years ago
It sounds like you really want to use the PBKDF2 functions (password-based cryptography). That's what I use in this type of application. See https://www.pycryptodome.org/en/latest/src/protocol/kdf.html?highlight=password
When I pass in a key instead of a password, your modified code works as expected (attached essai.py). Of course, decryption with a different key or nonce does not throw an exception but simply returns garbage cleartext.
is there any way to solve this issue?
@KeerthiNaathan
Did you read my earlier message and the attachment (essai.py.txt)?
Use the PyCryptodome PBKDF2 functions (password-based cryptography) instead of what you are currently doing. PyCryptodome is behaving as expected.
If you agree with me, please close this issue. If you do not, please explain what I missed/misunderstood.
I used PBKDF2 Functions to Generate Harsh, Still the Issue is there.
def encrypt(self, mode, data, password):
# a customed based KDF
password_h = self.harsh_obj.generate(password, True)
return {
"password_org": password, # orginal password
"password_h": password_h, # password harshed with PBKDF2 (harsh mode = SHA3-256)
"encryption": self.AES_MODE[mode].encrypt(data, password_h), # Encrypted Data
"mode": mode # type of AES Mode
}
def decrypt(self, data, password):
password_h = self.harsh_obj.generate(password, True) # generating the harsh password
return self.AES_MODE[data['mode']].decrypt(data['encryption'], password_h)
if __name__ == '__main__':
e = AESclass()
e_data = e.encrypt('CTR', b'Soviet Union', 'Stalin')
print(e_data)
# orginal password
p_data = e.decrypt(e_data, 'Stalin')
print('orginal_output:', p_data)
# wrong password
p_data = e.decrypt(e_data, 'Russia1')
print('wrong_output:', p_data)
the self.harsh_obj using PBKDF2 Function. to generate the Harsh as u mentioned above.
the Output is i got is: {'password_org': 'Stalin', 'password_h': b'7511d40bb6fdb3e55a3a8082150796b6', 'encryption': {'encrypted_data': b'J3iLvK3tBo8JliDt', 'nonce': b'FePovVQ7rNI='}, 'mode': 'CTR'} orginal_output: b'Soviet Union' wrong_output: b'2\x13\xa3\xc5kT\xf2o\xd9\xf8*S'
As per the Documentation: https://www.pycryptodome.org/en/latest/src/cipher/classic.html#ctr-mode . If the nonce / password wrong it must raise ValueError , KeyError. instead it throws some garbage values.
Please attach (drag and drop) the source code file of your test program to a new message here. I'll give it a go as soon as I see it.
Agreed with your comment about ValueError in the documentation. Ditto for KeyError.
"harsh" >>> "hash" right? (=:
PasswordGenerator.py - Generate Hash using HashGenerator, and compression of file, and other stuff
AESModes.py - AES Modes and Main AES Class. Btw: Thanks for spelling mistake correction , i need to Change the Name from harsh to hash. 👍
If any doubt ask me. because there is no documentation. (sry for that)
File Attachments: AESModes.py.txt PasswordGenerator.py.txt
Got the same result as you:
Encrypt output with password 'Stalin' on b'Soviet Union' {'password_org': 'Stalin', 'password_h': b'a0f8d8030ca52073d1d1355ffd8ff220', 'encryption': {'encrypted_data': b'kauZBLxZjUWUqw03', 'nonce': b'vqUOpKmBDCs='}, 'mode': 'CTR'}
Decrypt output with password "Stalin": b'Soviet Union'
Decrypt output with password "Russia1": b'<\xa4\xaf\x03\x83\xa8\x10;\xcfmi('
Modified your code for whatever it is worth with a few annotations and did the respelling. AESModes.py.txt PasswordGenerator.py.txt
Bottom line (I should have said this before):
(1) It is not the intent in pycryptodrome (or its predecessor pycrypto) that just a wrong password-generated key can cause a ValueError or a KeyError. Those are lower-level errors usually caused by the ciphertext containing invalid pad characters or invalid counters. In short, the ciphertext is garbage or had been tampered with. Providing the wrong password and therefore making a valid but incorrect key may not be sufficient to generate an exception of some kind. See https://github.com/Legrandin/pycryptodome/blob/master/lib/Crypto/Cipher/AES.py ValueError circumstances:
(2) In commercial production, a banking system ATM PIN is used like a password. A common ATM function is Verify PIN. The customer's PIN is permanently stored in the database (encrypted or hashed or both in some form). The incoming encrypted PIN block from the external transaction originator (E.g. ATM) plus the database ciphertext are provided to the authorization system's secure cryptographic device along with the 2 keys: database key and the key shared with the transaction originator. The device decrypts both ciphertext blocks and returns simply "match" or "not matched" based on a comparison of the 2 cleartext blocks. In a way, pycryptodome user programs doing password based cryptography are like this cryptographic device.
I hope that this makes sense. I've been doing cryptography for a long time and might be making incorrect assumptions about your experience level.
I have a project called pycloaking under my github space which you are welcome to. This utility is used to disguise files for transporting data say on a thumb drive or attaching to an email. The key to cloak or uncloak is based on a password. The cloaked file appears to a casual browser as a graphic TIFF file.
Ok Thanks , I am Closing this Issue btw @texadactyl Thanks for your help and I will talk to you in Email. also i will also check your pycloaking also 👍
in AES Mode - CFB, OFB, CTR when I enter the password it is not raising the error, instead, it gives random data.
I check the document, examples and tried , it not raising errors
Source-code: `class CTR: def encrypt(self, data, password): cipher = AES.new(password, AES.MODE_CTR) e_data = cipher.encrypt(data) return { "encrypted_data": e_data, "nonce": cipher.nonce, }
` Results: {'encryption': {'encrypted_data': b'\xbc\xca~\xe0\x81\x85\xf9R\xc7\xfcA?', 'nonce': b'[\x1c\x82\xc8J\xc8dn'}, 'mode': 'CTR'} output: b'\xf8\x94\x15,0q\xf0\x1e\xb1A\x0c\x1a'