AES加密方式每次返回不同的加密文本
AES Encryption Method Returning Different Encrypted Text Each Time
我一直在研究一个纯粹的概念验证代码,该代码源自 Diffie Hellman 密钥对交换,通过对这些密钥进行 SHA-256 加密,然后将其用作 AES-256 文本加密的密钥。我写它只是为了个人使用。我知道素数和秘密需要更长的时间..
我唯一有问题的代码是 AES-256 加密。它似乎可以工作,因为它显示了加密文本并且能够对其进行解密,但是经过仔细检查,每次您 运行 程序时加密文本都会更改?我觉得这很奇怪,因为该程序能够加密给定的纯文本,生成加密文本,然后使用给定的密钥对其进行解密。但是,每次程序 运行 使用相同的明文和相同的密钥时,此加密文本都会更改。
请看下面的代码...
from __future__ import print_function
import hashlib
from Crypto.Cipher import AES
from Crypto import Random
from base64 import b64encode, b64decode
# Variables
sharedPrime = 3721728827 # p
sharedBase = 2097383831 # g
p1Secret = 927391 # a
p2Secret = 193749 # b
# Begin
print( "\n--------------------------------------------\n" )
print( "Publicly Shared Variables:")
print( " Publicly Shared Prime (p): " , sharedPrime )
print( " Publicly Shared Base (g): " , sharedBase )
print( "\nPrivate Variables:")
print( " Private key a (a): " , p1Secret )
print( " Private key b (b): " , p2Secret )
print( "\n--------------------------------------------\n" )
# Person1 Sends Person2 A = g^a mod p
A = (sharedBase**p1Secret) % sharedPrime
print("Public Keys Sent Over Public Chanel: ")
print(" A = g^b mod p")
print(" Person1 Sends Over Public Chanel: " , A )
# Person2 Sends Person1 B = g^b mod p
B = (sharedBase ** p2Secret) % sharedPrime
print(" B = g^a mod p")
print(" Person2 Sends Over Public Chanel: ", B )
print( "\n--------------------------------------------\n" )
print( "Privately Calculated Shared Secret: " )
# P1 Computes Shared Secret: s = B^a mod p
p1SharedSecret = (B ** p1Secret) % sharedPrime
print( " s = B^a mod p")
print( " Person1 Shared Secret: ", p1SharedSecret )
# P2 Computes Shared Secret: s = A^b mod p
p2SharedSecret = (A**p2Secret) % sharedPrime
print( " s = A^b mod p")
print( " Person2 Shared Secret: ", p2SharedSecret )
print( "\n--------------------------------------------\n" )
# Converts DH secret to SHA256
print( "Converting shared key to SHA-256 key")
secretbyte = str(p1SharedSecret).encode()
print( " Shared secret to bytes: ", secretbyte)
shaV = hashlib.sha256(secretbyte).hexdigest()
print( " SHA-256 key: ", shaV)
key32 = shaV[0:32]
print( " SHA-256 key to AES-256 32bit secret key: ", key32)
print( "\n--------------------------------------------\n" )
#Begin AES-256 encryption
print( "Using SHA-256 32bit key for AES-256 encryption")
class AESCipher(object):
def __init__(self, key):
self.block_size = AES.block_size
self.key = hashlib.sha256(secretbyte).digest()
def encrypt(self, plain_text):
plain_text = self.__pad(plain_text)
iv = Random.new().read(self.block_size)
cipher = AES.new(self.key, AES.MODE_CBC, iv)
encrypted_text = cipher.encrypt(plain_text.encode())
return b64encode(iv + encrypted_text).decode("utf-8")
def decrypt(self, encrypted_text):
encrypted_text = b64decode(encrypted_text)
iv = encrypted_text[:self.block_size]
cipher = AES.new(self.key, AES.MODE_CBC, iv)
plain_text = cipher.decrypt(encrypted_text[self.block_size:]).decode("utf-8")
return self.__unpad(plain_text)
def __pad(self, plain_text):
number_of_bytes_to_pad = self.block_size - len(plain_text) % self.block_size
ascii_string = chr(number_of_bytes_to_pad)
padding_str = number_of_bytes_to_pad * ascii_string
padded_plain_text = plain_text + padding_str
return padded_plain_text
@staticmethod
def __unpad(plain_text):
last_character = plain_text[len(plain_text) - 1:]
return plain_text[:-ord(last_character)]
#Accept user input for encryption
message = input("Please enter message you want to be encrypted: ")
encMessage = AESCipher(key32)
encrypted = encMessage.encrypt(message)
print("Your encrypted message is: \n", encrypted)
print("Person 2 will now decrypt this message using the shared public key")
decrypted = encMessage.decrypt(encrypted)
print("Your decrypted message is: \n", decrypted)
该代码生成 72538667a2065257993b531746b9d92527cfe3caecc1457c4842e6a6caffe472
的 SHA-256 密钥,然后我将其 运行 分类为 32 个字符以生成 72538667a2065257993b531746b9d925
的 AES-256 密钥。然后我输入的任何明文都将被成功编码和解码,但是即使输入相同的密钥和明文,加密文本每次都会更改。我做错了什么吗?
只要你的密文每次都能解密成功,就不用担心密文不同
您的代码使用 CBC 链接模式,这很常见,每次加密时都会生成不同的初始化向量,以避免相同的明文在加密后看起来相同(这会部分破坏加密点,因为攻击者现在知道是否是同一个明文)。
图片来源:Block cipher mode of operation - Wikipedia(public 域)
我一直在研究一个纯粹的概念验证代码,该代码源自 Diffie Hellman 密钥对交换,通过对这些密钥进行 SHA-256 加密,然后将其用作 AES-256 文本加密的密钥。我写它只是为了个人使用。我知道素数和秘密需要更长的时间..
我唯一有问题的代码是 AES-256 加密。它似乎可以工作,因为它显示了加密文本并且能够对其进行解密,但是经过仔细检查,每次您 运行 程序时加密文本都会更改?我觉得这很奇怪,因为该程序能够加密给定的纯文本,生成加密文本,然后使用给定的密钥对其进行解密。但是,每次程序 运行 使用相同的明文和相同的密钥时,此加密文本都会更改。
请看下面的代码...
from __future__ import print_function
import hashlib
from Crypto.Cipher import AES
from Crypto import Random
from base64 import b64encode, b64decode
# Variables
sharedPrime = 3721728827 # p
sharedBase = 2097383831 # g
p1Secret = 927391 # a
p2Secret = 193749 # b
# Begin
print( "\n--------------------------------------------\n" )
print( "Publicly Shared Variables:")
print( " Publicly Shared Prime (p): " , sharedPrime )
print( " Publicly Shared Base (g): " , sharedBase )
print( "\nPrivate Variables:")
print( " Private key a (a): " , p1Secret )
print( " Private key b (b): " , p2Secret )
print( "\n--------------------------------------------\n" )
# Person1 Sends Person2 A = g^a mod p
A = (sharedBase**p1Secret) % sharedPrime
print("Public Keys Sent Over Public Chanel: ")
print(" A = g^b mod p")
print(" Person1 Sends Over Public Chanel: " , A )
# Person2 Sends Person1 B = g^b mod p
B = (sharedBase ** p2Secret) % sharedPrime
print(" B = g^a mod p")
print(" Person2 Sends Over Public Chanel: ", B )
print( "\n--------------------------------------------\n" )
print( "Privately Calculated Shared Secret: " )
# P1 Computes Shared Secret: s = B^a mod p
p1SharedSecret = (B ** p1Secret) % sharedPrime
print( " s = B^a mod p")
print( " Person1 Shared Secret: ", p1SharedSecret )
# P2 Computes Shared Secret: s = A^b mod p
p2SharedSecret = (A**p2Secret) % sharedPrime
print( " s = A^b mod p")
print( " Person2 Shared Secret: ", p2SharedSecret )
print( "\n--------------------------------------------\n" )
# Converts DH secret to SHA256
print( "Converting shared key to SHA-256 key")
secretbyte = str(p1SharedSecret).encode()
print( " Shared secret to bytes: ", secretbyte)
shaV = hashlib.sha256(secretbyte).hexdigest()
print( " SHA-256 key: ", shaV)
key32 = shaV[0:32]
print( " SHA-256 key to AES-256 32bit secret key: ", key32)
print( "\n--------------------------------------------\n" )
#Begin AES-256 encryption
print( "Using SHA-256 32bit key for AES-256 encryption")
class AESCipher(object):
def __init__(self, key):
self.block_size = AES.block_size
self.key = hashlib.sha256(secretbyte).digest()
def encrypt(self, plain_text):
plain_text = self.__pad(plain_text)
iv = Random.new().read(self.block_size)
cipher = AES.new(self.key, AES.MODE_CBC, iv)
encrypted_text = cipher.encrypt(plain_text.encode())
return b64encode(iv + encrypted_text).decode("utf-8")
def decrypt(self, encrypted_text):
encrypted_text = b64decode(encrypted_text)
iv = encrypted_text[:self.block_size]
cipher = AES.new(self.key, AES.MODE_CBC, iv)
plain_text = cipher.decrypt(encrypted_text[self.block_size:]).decode("utf-8")
return self.__unpad(plain_text)
def __pad(self, plain_text):
number_of_bytes_to_pad = self.block_size - len(plain_text) % self.block_size
ascii_string = chr(number_of_bytes_to_pad)
padding_str = number_of_bytes_to_pad * ascii_string
padded_plain_text = plain_text + padding_str
return padded_plain_text
@staticmethod
def __unpad(plain_text):
last_character = plain_text[len(plain_text) - 1:]
return plain_text[:-ord(last_character)]
#Accept user input for encryption
message = input("Please enter message you want to be encrypted: ")
encMessage = AESCipher(key32)
encrypted = encMessage.encrypt(message)
print("Your encrypted message is: \n", encrypted)
print("Person 2 will now decrypt this message using the shared public key")
decrypted = encMessage.decrypt(encrypted)
print("Your decrypted message is: \n", decrypted)
该代码生成 72538667a2065257993b531746b9d92527cfe3caecc1457c4842e6a6caffe472
的 SHA-256 密钥,然后我将其 运行 分类为 32 个字符以生成 72538667a2065257993b531746b9d925
的 AES-256 密钥。然后我输入的任何明文都将被成功编码和解码,但是即使输入相同的密钥和明文,加密文本每次都会更改。我做错了什么吗?
只要你的密文每次都能解密成功,就不用担心密文不同
您的代码使用 CBC 链接模式,这很常见,每次加密时都会生成不同的初始化向量,以避免相同的明文在加密后看起来相同(这会部分破坏加密点,因为攻击者现在知道是否是同一个明文)。
图片来源:Block cipher mode of operation - Wikipedia(public 域)