【问题标题】:Decrypt encrypted binary file in java ( AES_CTR mode)在java中解密加密的二进制文件(AES_CTR模式)
【发布时间】:2018-10-20 20:14:47
【问题描述】:

我知道以前有人问过这个问题。我只需要一个方向来完成这些代码。如果有人能指出我的代码中的问题,那将非常有帮助

这是用于解密的Java代码

import javax.crypto.Cipher;
import javax.crypto.CipherOutputStream;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.File;
class Decode{
    public static void main(String []args){
    try{
        Decode.decrypt();
        System.out.println("Decrypted");
    }catch(Exception e){
        System.out.println(e);
    }
}
public static void decrypt() throws Exception {
    byte[] initialIV;
    final byte[] buf = new byte[128];
    final Cipher c = Cipher.getInstance("AES/CTR/NoPadding");

    final InputStream is = new FileInputStream("/home/neki/python/encVideo.mp4");



    byte[] buffer = new byte[16];
    is.read(buffer);


    c.init(Cipher.DECRYPT_MODE,new SecretKeySpec("1234567890123456".getBytes(), "AES"),new IvParameterSpec(buffer));

    final OutputStream os = new CipherOutputStream(new FileOutputStream("/home/neki/python/javaDecVideo.mp4"), c);
    while (true) {
        int n = is.read(buf);
        if (n == -1) break;
            os.write(buf, 0, n);
    }
    os.close(); is.close();
}
}
}

这是加密文件的python代码

import os, random, struct
from Crypto.Cipher import AES
from os import urandom
from Crypto.Util import Counter
def encrypt_file(key, in_filename, out_filename=None, chunksize=128):


if not out_filename:
    out_filename = in_filename + '.enc'

iv = '\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0'
encryptor = AES.new(key, AES.MODE_CTR, counter = lambda : 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)

        while True:
            chunk = infile.read(chunksize)
            if len(chunk) == 0:
                break

            outfile.write(encryptor.encrypt(chunk))
encrypt_file("1234567890123456".encode(),"/home/neki/python/Eduaid.mp4","/home/neki/python/encVideo.mp4")

我还在stackoverflow中找到了一些想法。但不能很好理解。

【问题讨论】:

    标签: java python pycrypto


    【解决方案1】:

    您配置此密码的方式非常不安全。 请勿使用此代码。

    通过设置:

    counter = lambda : iv
    

    在 Python 中初始化 AES 密码时,您已强制 AES-CTR 对每个块使用完全相同的计数器。这将密码从 AES-CTR 减少为简单的滚动 XOR。观察:

    >>> key = "abcd1234abcd1234"
    >>> iv = '\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0'
    >>> encryptor = AES.new(key, AES.MODE_CTR, counter = lambda : iv)
    >>> encryptor.encrypt("example block 01")
    '\xda\x7f\x00\xbdp\x1c\xe4\xf3=|\x88\xe2\xe5%\x80\xab'
    >>> encryptor.encrypt("example block 01")
    '\xda\x7f\x00\xbdp\x1c\xe4\xf3=|\x88\xe2\xe5%\x80\xab'
    >>> encryptor.encrypt("example block 02")
    '\xda\x7f\x00\xbdp\x1c\xe4\xf3=|\x88\xe2\xe5%\x80\xa8'
    

    注意:

    1. 重复加密同一块会产生相同的输出。

    2. 加密相似的块会产生相似的输出。 (技术上,a XOR b = E(a) XOR E(b)。)

    要解决此问题,您需要使用已导入的 Counter 类:

    encryptor = AES.new(key, AES.MODE_CTR, counter=Counter.new(128))
    

    正确配置 AES-CTR 后,您现有的 Java 代码应该能够解密它。

    但是,请注意,如果重复使用同一个密钥来加密多个文件,此模式仍然不安全。您必须为每个文件使用不同的密钥。

    【讨论】:

    • 感谢您的回复。我已将其更改为 """Counter.new(128)""" 。但它仍然无法在java中解密。 (仅供参考:但我可以在 python 中对其进行解密)
    • 我认为 java "new IvParameterSpec(buffer)" 和 python Counter.new(128) 都产生不同的值。想不通
    猜你喜欢
    • 2016-06-05
    • 1970-01-01
    • 2014-03-17
    • 1970-01-01
    • 2018-12-02
    • 1970-01-01
    • 1970-01-01
    • 2012-02-18
    • 1970-01-01
    相关资源
    最近更新 更多