文件加密在python解密在android中

时间:2015-07-07 17:49:41

标签: java android python python-3.x encryption

我一直在尝试解密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

1 个答案:

答案 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();
}