我一直在尝试解密android中的文件,从python加密, 这是我用于解密的python代码。
import os, random, struct
from Crypto.Cipher import AES
import sys
import hashlib
print("trying")
def encrypt_file(key, in_filename, out_filename=None, chunksize=64*1024):
""" Encrypts a file using AES (CBC mode) with the
given key.
key:
The encryption key - a string that must be
either 16, 24 or 32 bytes long. Longer keys
are more secure.
in_filename:
Name of the input file
out_filename:
If None, '<in_filename>.enc' will be used.
chunksize:
Sets the size of the chunk which the function
uses to read and encrypt the file. Larger chunk
sizes can be faster for some files and machines.
chunksize must be divisible by 16.
"""
if not out_filename:
out_filename = in_filename + '.mjt'
iv = 16 * '\x00'
encryptor = AES.new(key, AES.MODE_CBC, iv)
filesize = os.path.getsize(in_filename)
with open(in_filename, 'rb') as infile:
with open(out_filename, 'wb') as outfile:
outfile.write(struct.pack('<Q', filesize))
# outfile.write(iv)
outfile.write(bytes(iv, 'UTF-8'))
while True:
chunk = infile.read(chunksize)
if len(chunk) == 0:
break
elif len(chunk) % 16 != 0:
chunk += b' ' * (16 - len(chunk) % 16)
outfile.write(encryptor.encrypt(chunk))
# outfile.write(bytes(encryptor.encrypt(chunk), 'UTF-8'))
def main():
filename1 = sys.argv[-2]
filename2 = sys.argv[-1]
key = '0123456789abcdef'
encrypt_file(key, filename1, filename2)
print("done")
if __name__ == '__main__':
main()
这是我的android函数试图用
解密private static byte[] ivBytes = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
public static void decrypt(String inputFile, String outputFile, String password) throws IOException, NoSuchAlgorithmException, NoSuchPaddingException, InvalidKeyException, InvalidAlgorithmParameterException {
FileInputStream fis = new FileInputStream(inputFile);
FileOutputStream fos = new FileOutputStream(outputFile);
IvParameterSpec iv = new IvParameterSpec(ivBytes);
SecretKeySpec sks = new SecretKeySpec(password.getBytes(), "AES");
Cipher cipher = Cipher.getInstance("AES/CBC/NoPadding");
cipher.init(Cipher.DECRYPT_MODE, sks, iv);
CipherInputStream cis = new CipherInputStream(fis, cipher);
int b;
byte[] d = new byte[1024];
while((b = cis.read(d)) != -1) {
fos.write(d, 0, b);
}
fos.flush();
fos.close();
cis.close();
}
这在使用AES / CBC / NoPadding时给出了
java.io.IOException: data not block size aligned
当使用AES / CBC / PKCS5Padding时,它给出了
java.io.IOException: last block incomplete in decryption
答案 0 :(得分:1)
AES是一种分组密码,因此需要在加密和解密时将消息填充到块大小的倍数。你的加密很好。它读取文件大小,写入文件的前8个字节,然后写入16个字节IV,最后写入块的内容,确保填充。但是,您的解密不会遵循相同的解密模式。 AES是128位分组密码,因此您不必担心指定PKCS5Padding,只需要像加密一样遵循相同的例程。您的代码中也存在与iv相关的错误。
尝试以下操作,它应该有效:
private static byte[] filesize = new byte[8];
private static byte[] ivBytes = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
public static void decrypt(String inputFile, String outputFile, String password) throws IOException, NoSuchAlgorithmException, NoSuchPaddingException, InvalidKeyException, InvalidAlgorithmParameterException {
FileInputStream fis = new FileInputStream(inputFile);
FileOutputStream fos = new FileOutputStream(outputFile);
fis.read(filesize, 0, 8);
System.out.println(new String(filesize));
fis.mark(9);
fis.read(ivBytes, 0, 16);
System.out.println(new String(ivBytes));
fis.mark(25);
IvParameterSpec iv = new IvParameterSpec(ivBytes);
SecretKeySpec sks = new SecretKeySpec(password.getBytes(), "AES");
Cipher cipher = Cipher.getInstance("AES/CBC/NoPadding");
cipher.init(Cipher.DECRYPT_MODE, sks, iv);
File file = new File(inputFile);
int byteLength = (int) file.length() - 24;
System.out.println(Integer.toString(byteLength));
byte[] bytes = new byte[byteLength];
byteLength = fis.read(bytes);
System.out.println(Integer.toString(byteLength));
System.out.println(new String(bytes));
InputStream bytesStream = new ByteArrayInputStream(bytes);
CipherInputStream cis = new CipherInputStream(bytesStream, cipher);
int b;
byte[] d = new byte[1024];
while((b = cis.read(d)) != -1) {
fos.write(d, 0, b);
}
fos.flush();
fos.close();
cis.close();
}