Anstataŭigis AES-CBC per AES-GCM

This commit is contained in:
1010 2024-03-22 13:49:00 +07:00
parent 2d1fc23514
commit 628ee166fc
1 changed files with 73 additions and 37 deletions

View File

@ -1,10 +1,9 @@
#!/usr/bin/env python3
import binascii, pyperclip, readline, gettext
from Crypto.Cipher import AES
from Crypto.Protocol.KDF import PBKDF2
from Crypto.Random import get_random_bytes
from Crypto.Util.Padding import pad
import hashlib, pyperclip, readline, gettext
from Cryptodome.Cipher import AES
from Cryptodome.Random import get_random_bytes
t = gettext.translation(
'sekreto',
@ -14,49 +13,78 @@ t = gettext.translation(
_ = t.gettext
IV_LENGTH = 12
KEY_LENGTH = 32
TAG_LENGTH = 16
SALT_LENGTH = 16
HASH_NAME = "SHA1"
ITERATION_COUNT = 65535
zwc = ["\u2060", "\u200B", "\u200D", "\u200E",
"\u200F", "\u200C", "\u2061", "\u180E",
"\u202A", "\u202C", "\u202D", "\u2062",
"\u2063", "\u2064", "\u2065", "\u2066"]
def encrypt(plaintext, password):
salt = get_random_bytes(16)
key = PBKDF2(password, salt, dkLen=16, count=10000)
iv = get_random_bytes(16)
cipher = AES.new(key, AES.MODE_CBC, iv)
ciphertext = cipher.encrypt(pad(plaintext.encode('utf-8'), 16))
encrypted_data = salt + iv + ciphertext
return binascii.hexlify(encrypted_data).decode('utf-8')
def decrypt(hex_ciphertext, password):
ciphertext = bytes.fromhex(hex_ciphertext)
salt = ciphertext[:16]
iv = ciphertext[16:32]
encrypted_data = ciphertext[32:]
key = PBKDF2(password, salt, dkLen=16, count=10000)
cipher = AES.new(key, AES.MODE_CBC, iv)
decrypted_data = cipher.decrypt(encrypted_data)
secret = decrypted_data.decode('utf-8').strip()
return secret
def hid2hex(hid_string):
mappings = {zwc[i]: hex(i)[2:].upper() for i in range(16)}
hex_string = "".join(mappings.get(char, "") for char in hid_string)
return hex_string
def hex2hid(hex_string):
mappings = {hex(i)[2:].upper(): zwc[i] for i in range(16)}
hid_string = "".join(mappings.get(char.upper(), "") for char in hex_string)
return hid_string
def wrap(text):
wrapped_text = "\uFEFF" + text + "\uFEFF"
return wrapped_text
def unwrap(text):
unwrapped_text = text.strip('\uFEFF')
return unwrapped_text
def get_secret_key(password, salt):
return hashlib.pbkdf2_hmac(
HASH_NAME, password.encode(), salt, ITERATION_COUNT, KEY_LENGTH
)
def encrypt(password, plain_message):
salt = get_random_bytes(SALT_LENGTH)
iv = get_random_bytes(IV_LENGTH)
secret = get_secret_key(password, salt)
cipher = AES.new(secret, AES.MODE_GCM, iv)
encrypted_message_byte, tag = cipher.encrypt_and_digest(plain_message.encode("utf-8"))
cipher_byte = salt + iv + encrypted_message_byte + tag
encoded_cipher_byte = cipher_byte.hex()
return encoded_cipher_byte
def decrypt(password, cipher_message):
decoded_cipher_byte = bytes.fromhex(cipher_message)
salt = decoded_cipher_byte[:SALT_LENGTH]
iv = decoded_cipher_byte[SALT_LENGTH : (SALT_LENGTH + IV_LENGTH)]
encrypted_message_byte = decoded_cipher_byte[(IV_LENGTH + SALT_LENGTH) : -TAG_LENGTH]
tag = decoded_cipher_byte[-TAG_LENGTH:]
secret = get_secret_key(password, salt)
cipher = AES.new(secret, AES.MODE_GCM, iv)
decrypted_message_byte = cipher.decrypt_and_verify(encrypted_message_byte, tag)
return decrypted_message_byte.decode("utf-8")
while True:
print()
@ -66,33 +94,41 @@ while True:
print()
choice = input("Sekreto:~$ ")
if choice == "1":
secret = input(_("Sekreta mesaĝo: "))
password = input(_("Pasvorto: "))
pub_msg = input(_("Publika teksto: "))
if len(pub_msg) < 2:
secret_msg = input(_("Sekreta mesaĝo: "))
secret_key = input(_("Pasvorto: "))
public_msg = input(_("Publika teksto: "))
if len(public_msg) < 2:
print(_("La longo de publika teksto devas esti almenaŭ du signoj!"))
continue
encrypt_msg = encrypt(secret, password)
encrypt_msg = encrypt(secret_key, secret_msg)
hiding = hex2hid(encrypt_msg)
wrapping = wrap(hiding)
result = pub_msg[:len(pub_msg) // 2] + wrapping + pub_msg[len(pub_msg) // 2:]
pyperclip.copy(result)
print(_("Mesaĝo kaŝita kaj kopiita!"))
result = public_msg[:len(public_msg) // 2] + wrapping + public_msg[len(public_msg) // 2:]
try:
pyperclip.copy(result)
print(_("Mesaĝo kaŝita kaj kopiita!"))
except pyperclip.PyperclipException:
print(_("Eraro okazis dum kopiado!"))
elif choice == "2":
result = input(_("Enigu tekston kun mesaĝo: "))
password = input(_("Pasvorto: "))
secret_key = input(_("Pasvorto: "))
extraction = unwrap(result)
revealing = hid2hex(extraction)
try:
secret = decrypt(revealing, password)
secret = decrypt(secret_key, revealing)
print(_("Sekreta mesaĝo: "), secret)
except:
print(_("Vi enigis malĝustan teksto aŭ pasvorton!"))
elif choice == "0":
quit()