私はJavaでデータファイルを暗号化し、Pythonで解読しようとしています。Pythonのjava解読でAES/CBC/PKCS5Paddingの暗号化が正しく行われない
復号化されたデータファイルは、常にこの
my normal content^@^@^@^@^@
remainslikeいくつかのパディングバイトを得たI実際にPythonコードでUNPADアクション(FUNC decrypt_file())
を行うと、私はUNPADのアクションを削除する場合私はこれを持っています:
my normal content^@^@^@^@^@^P^P^P^P^P^P^P^P^P^P^P^P^P^P^P^P
だから、Javaの暗号化メソッドはTWICEを埋め尽くしたようです。
私はとても混乱しており、ここにはまっています。誰でも助けることができますか?どうもありがとう!
ここに私のコードです。あなただけのデフォルトモードを使用して試してみて、ENC/12月時にこの問題が発生した場合
(1)Javaのバージョン
import java.io.File;
import javax.crypto.Cipher;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
public class AESUtil {
private static final String key = "wesurexZ5!Hcurfit";
private static final String ivs = "zK2hzBvP%FRJ5%lD";
public static byte[] encrypt(byte[] strInBytes) throws Exception {
SecretKeySpec skeySpec = getKey(key);
Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
IvParameterSpec iv = new IvParameterSpec(ivs.getBytes("UTF-8"));
cipher.init(Cipher.ENCRYPT_MODE, skeySpec, iv);
return cipher.doFinal(strInBytes);
}
public static byte[] decrypt(byte[] strIn) throws Exception {
SecretKeySpec skeySpec = getKey(key);
Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
IvParameterSpec iv = new IvParameterSpec(ivs.getBytes("UTF-8"));
cipher.init(Cipher.DECRYPT_MODE, skeySpec, iv);
byte[] decrypted = cipher.doFinal(strIn);
return decrypted;
}
private static SecretKeySpec getKey(String strKey) throws Exception {
byte[] arrBTmp = strKey.getBytes();
byte[] arrB = new byte[16];
for (int i = 0; i < arrBTmp.length && i < arrB.length; i++) {
arrB[i] = arrBTmp[i];
}
SecretKeySpec skeySpec = new SecretKeySpec(arrB, "AES");
return skeySpec;
}
}
(2)Pythonのバージョン
#!/usr/bin/env python
# -*- coding: utf-8 -*-
import sys
reload(sys)
sys.setdefaultencoding("utf-8")
from Crypto.Cipher import AES
class AESTool(object):
def __init__(self, iv, key):
self.iv = iv.decode("utf8")
self.key = key
bs = AES.block_size
self.pad = lambda s: s + (bs - len(s) % bs) * chr(bs - len(s) % bs)
self.unpad = lambda s: s[0:-ord(s[-1])]
def encrypt(self, plain_text):
try:
encryptor = AES.new(self.key, AES.MODE_CBC, self.iv)
encrypted_text = encryptor.encrypt(self.pad(plain_text))
except Exception as ex:
raise Exception(ex.message)
return encrypted_text
def decrypt(self, decrypted_text):
try:
decryptor = AES.new(self.key, AES.MODE_CBC, self.iv)
plain_text = decryptor.decrypt(decrypted_text)
except Exception as ex:
raise Exception(ex.message)
return self.unpad(plain_text)
def encrypt_file(self, from_full_path, to_full_path, chunksize=64*1024):
encryptor = AES.new(self.key, AES.MODE_CBC, self.iv)
try:
with open(from_full_path, 'rb') as infile:
with open(to_full_path, 'wb') as outfile:
while True:
chunk = infile.read(chunksize)
if len(chunk) == 0:
break
if len(chunk) < chunksize:
outfile.write(encryptor.encrypt(self.pad(chunk)))
break
outfile.write(encryptor.encrypt(chunk))
except Exception as ex:
return -1
return 0
def decrypt_file(self, from_full_path, to_full_path, chunksize=64*1024):
decryptor = AES.new(self.key, AES.MODE_CBC, self.iv)
try:
with open(from_full_path, 'rb') as infile:
with open(to_full_path, 'wb') as outfile:
prev_chunk = None
while True:
chunk = infile.read(chunksize)
if len(chunk) == 0 and prev_chunk:
outfile.write(self.unpad(decryptor.decrypt(prev_chunk)))
break
if prev_chunk:
outfile.write(decryptor.decrypt(prev_chunk))
if len(chunk) < chunksize:
outfile.write(self.unpad(decryptor.decrypt(chunk)))
break
prev_chunk = chunk
except Exception as ex:
return -1
return 0
IVは、暗号化ごとにランダムで異なる必要があります。 – zaph
@zaph固定IVの再利用がセキュリティ上の問題を引き起こす可能性があることを知りました。しかし、どうすればこのような機能上の問題が生じるのでしょうか?私はそれを得ていない、あなたは私を埋めることができますか?どうもありがとうございました。 – RonnieTsang
このコメントはOPのためのものではなく、将来の読者のためのもので、問題の固定IVはセキュリティが貧弱であることを指摘しています。 – zaph