繁体   English   中英

Java AES加密(有效)和Python解密(无效)

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM