[英]Java AES Encryption (working) and Python Decryption (not working)
我正在尝试用Java加密消息并用Python解密消息。 不幸的是,我只是从python开始,却无法使解密工作。
那是我的Java代码:
KeyGenerator keygen = KeyGenerator.getInstance("AES");
SecureRandom sr = SecureRandom.getInstance("SHA1PRNG");
byte[] iv = sr.generateSeed(16);
IvParameterSpec ivSpec = new IvParameterSpec(iv);
SecretKey aesKey = keygen.generateKey();
//save byte array in text file to recreate key later
byte[] encodedKey = aesKey.getEncoded();
new File("myPath\\AESKey.txt");
FileOutputStream fos = new FileOutputStream("myPath\\AESKey.txt");
//save AesKey in first 16 bytes and Initial Vector in next 16 bytes
fos.write(encodedKey);
fos.write(iv);
fos.close();
String secretText = "Hello cryptography";
Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
cipher.init(Cipher.ENCRYPT_MODE, aesKey, ivSpec);
byte[] encrypted = cipher.doFinal(secretText.getBytes());
BASE64Encoder myEncoder = new BASE64Encoder();
String encodedSecretText = myEncoder.encode(encrypted);
new File("myPath\\encodedSecretText.txt");
FileOutputStream fos2 = new FileOutputStream("myPath\\encodedSecretText.txt");
fos2.write(encodedSecretText.getBytes());
fos2.close();
我可以使用Java解密消息,但不能使用python解密消息。 我希望有人能告诉我该怎么做。我从另一个答案中复制了带有填充的零件,并认为这就是问题所在。
我收到消息:ord()期望的长度为1的字符串,但找到了int。
蟒蛇:
from Crypto import Random
from Crypto.Cipher import AES
import base64
BS = 16
pad = lambda s: s + (BS - len(s) % BS) * chr(BS - len(s) % BS)
unpad = lambda s : s[0:-ord(s[-1])]
#read bytes of aesKey
file = open("myPath/AESKey.txt","rb")
aesKey = file.read(16)
iv = file.read(16)
file.close()
sec = open("myPath/encodedSecretText.txt")
for line in sec:
encodedSecretText = line.rstrip()
sec.close()
class AESCipher:
def __init__( self, key ):
self.key = key
def encrypt( self, raw ):
raw = pad(raw)
iv = Random.new().read( AES.block_size )
cipher = AES.new( self.key, AES.MODE_CBC, iv )
return base64.b64encode( iv + cipher.encrypt( raw ) )
def decrypt( self, enc ):
enc = base64.b64decode(enc)
cipher = AES.new(self.key, AES.MODE_CBC, iv )
return unpad(cipher.decrypt( enc[16:] ))
aes = AESCipher(aesKey)
print(aes.decrypt(encodedSecretText))
感谢您的任何提示。
您正在用整数调用ord
。 这显然是非法的。 ord
的全部要点是为它提供一个Unicode字符(作为字符串),并且还给了您代码点的数字值。
那么,为什么有电话号码? 好吧,我不确定您期望拥有什么,但是让我们看看您实际拥有什么。 如果s[-1]
是整数,则s
是某种整数序列。 s
是调用cipher.decrypt()
的结果。 如该函数的文档所述 ,它返回一个字节字符串。 这不是特定的类型,只是类型的描述-您可以通过一些基本的调试来找出实际的返回值,例如:
cipher = AES.new(self.key, AES.MODE_CBC, iv )
plaintext = cipher.decrypt(enc[16:])
print(type(plaintext), repr(plaintext))
return unpad(plaintext)
但是我要猜测这是一个bytes
对象,(从http://docs.python.org/3/library/functions.html#bytes引用)…
是一个不可变的整数序列,范围为0 <= x <256。
因此, s[-1]
是[0, 256)
范围内的整数。 因此,错误。
那么,您应该怎么做呢? 好吧,为什么您要致电ord
? 你有一个字节。 大概您想要的是一个字节。 所以……只是什么都不要打。
同时,您的代码中至少还有一个其他严重错误:
for line in sec:
encodedSecretText = line.rstrip()
sec.close()
如所粘贴,这将引发IndentationError
。 而且,如果同时缩进第二行和第三行,则从关闭的文件中读取时会出现错误。 因此,大概您只想缩进第二个。 在这种情况下,您要做的是遍历所有行,将尾随的空白删除,然后对它们不执行任何操作。 在循环结束时, encodedSecretText
保留了编码文本的最后一行,而所有其他行早已被遗忘并且无法恢复。
如果您想将所有文本读入行列表中,则将需要以下内容:
encodedSecretText = []
for line in sec:
encodedSecretText.append(line.rstrip())
或者,如果您想将其读入一个大字符串中,并且删除了换行符,则可以执行上述操作,然后执行encodedSecretText = b''.join(encodedSecretText)
,或者只是跳过整个循环并执行encodedSecretText = sec.read().replace(b'\\n', b'')
。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.