简体   繁体   English

python中的文件加密在android中解密

[英]file encrypt in python decrypt in android

I have been trying to decrypt a file in android, encrypted from python, Here is python code i used in decrypting. 我一直在尝试解密从python加密的android中的文件,这是我在解密中使用的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()

and here is my android function trying to decrypt with 这是我的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();
    }

this gives while using AES/CBC/NoPadding java.io.IOException: data not block size aligned and when AES/CBC/PKCS5Padding is used, it gives java.io.IOException: last block incomplete in decryption 这在使用AES / CBC / NoPadding时给出了java.io.IOException: data not block size aligned并且当使用AES / CBC / PKCS5Padding时,它给出了java.io.IOException: last block incomplete in decryption

AES is a block cipher so the messages need to be padded to exactly the multiple of the block size, both at encryption and decryption. AES是一种分组密码,因此无论是在加密还是解密时,都需要将消息精确地填充为该分组大小的倍数。 Your encryption is fine. 您的加密很好。 It reads the filesize, writes to first 8 bytes of your file, then writes 16 bytes IV and finally the content of file chunk by chunk ensuring the padding. 它读取文件大小,写入文件的前8个字节,然后写入16个字节的IV,最后逐块写入文件内容,以确保填充。 However, your decryption does not follow the same pattern for decryption. 但是,您的解密不遵循相同的解密模式。 AES is a 128 bit block cipher so you don't have to worry much about specifying PKCS5Padding, just need to follow the same routine in reverse as your encryption. AES是一种128位块密码,因此您不必担心指定PKCS5Padding,只需要遵循与加密相反的例程即可。 There was a bug in your code related to iv too. 您的代码中也存在与iv相关的错误。

Try the following and it should work: 尝试以下方法,它应该可以工作:

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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