Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/342.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
AES 128如何在python中使用部分密钥强制执行_Python_Encryption_Cryptography_Key_Aes - Fatal编程技术网

AES 128如何在python中使用部分密钥强制执行

AES 128如何在python中使用部分密钥强制执行,python,encryption,cryptography,key,aes,Python,Encryption,Cryptography,Key,Aes,我是python初学者,所以我需要帮助 我有加密文件和部分密钥文件,部分密钥文件的128位中有96位,所以我需要猜测 其余的密钥和解密文件,提示的第一个字是“hello”中的加密 我的问题是: 如何猜出其余的关键点? 如何检查该键是否正确以及花费了多少时间?很抱歉,我的答案中的源代码是用Java编写的,但到目前为止,我从未用python编写过一行代码。正如您向我们展示的几乎没有自我编写的代码一样,我认为您需要一条路径来找到在python中实现它的方法 AES 128加密有一个128位或16字节长

我是python初学者,所以我需要帮助 我有加密文件和部分密钥文件,部分密钥文件的128位中有96位,所以我需要猜测 其余的密钥和解密文件,提示的第一个字是“hello”中的加密 我的问题是: 如何猜出其余的关键点?
如何检查该键是否正确以及花费了多少时间?

很抱歉,我的答案中的源代码是用Java编写的,但到目前为止,我从未用python编写过一行代码。正如您向我们展示的几乎没有自我编写的代码一样,我认为您需要一条路径来找到在python中实现它的方法

AES 128加密有一个128位或16字节长的密钥,用于加密和以后的解密。您告诉我们,您已经知道96位=12字节,因此“只剩下”4个字节可供猜测。每个字节的“容量”为(整数)256,因此您最多必须测试256*256*256*256组合=4294967296组合。假设钥匙是随机的,你需要一半的钥匙才能找到真正的钥匙,所以在真正的钥匙中有2147483648种组合——今天的家用电脑在一小时或更短的时间内就能做到这一点

下面是我的代码,我用代码设置了一个在线编译器——在这段代码中,我“限制”了对最后2个字节的搜索(因此它假设 16字节)因为在线编译器会以“运行时间过长”运行时错误中止程序

这段代码有很好的注释,不是为了速度而优化的,而是为了可读性。最后你会得到这样一个输出(因为我使用的是随机键和 CBC模式下AES的初始化向量(您的输出将不同),在线编译器可在以下位置获得:

代码:

import javax.crypto.BadPaddingException;
导入javax.crypto.Cipher;
导入javax.crypto.IllegalBlockSizeException;
导入javax.crypto.NoSuchPaddingException;
导入javax.crypto.spec.IvParameterSpec;
导入javax.crypto.spec.SecretKeySpec;
导入java.nio.ByteBuffer;
导入java.nio.charset.StandardCharset;
导入java.security.invalidalgorithParameterException;
导入java.security.InvalidKeyException;
导入java.security.NoSuchAlgorithmException;
导入java.security.SecureRandom;
公共班机{
公共静态void main(字符串[]args)引发异常{
System.out.println(“AES CBC字符串加密-暴力解密”);
String plaintext=“您好,这只是纯文本”;
//这个明文开头是已知的
字符串plaintextKnown=“hello”;
byte[]plaintextKnownByte=plaintextKnown.getBytes(StandardCharsets.UTF_8);
//密钥的已知字节数
int numberKeyBytes=14;//14字节=112位已知位
//随机键&iv
SecureRandom=新的SecureRandom();
字节[]键=新字节[16];//16字节=128位键长
随机。下个字节(键);
字节[]iv=新字节[16];
随机。下一字节(iv);
System.out.println(“键长度:+key.length+”数据:+bytesToHex(键));
//设置cbc
SecretKeySpec keySpec=新的SecretKeySpec(键,“AES”);
IvParameterSpec IvParameterSpec=新的IvParameterSpec(iv);
Cipher Cipher=Cipher.getInstance(“AES/CBC/PKCS5Padding”);
cipher.init(cipher.ENCRYPT_模式,keySpec,ivParameterSpec);
//获取明文
字节[]明文字节=明文.getBytes(StandardCharsets.UTF_8);
byte[]ciphertextByte=cipher.doFinal(明文字节);
byte[]keygussed=新字节[16];
System.arraycopy(key,0,keyGuessed,0,numberKeyBytes);//复制前14个字节=112位
System.out.println(“keyGuess长度:+keyGuessed.length+”数据:+bytesToHex(keyGuessed));
对于(int a=0;a<256;a++){
对于(int b=0;b<256;b++){
用于(int c=0;c<256;c++){
对于(int d=0;d<256;d++){
猜键[15]=(字节)d;
//System.out.println(“keyGuess长度:+keyGuessed.length+”数据:+bytesToHex(keyGuessed));
解密AESCBC128(猜密、iv、密文字节、明文字节);
}
猜键[14]=(字节)c;
}
猜键[13]=(字节)b;
}
猜键[12]=(字节)a;
}
}
私有静态布尔解密AESCBC128(字节[]密钥,字节[]iv,字节[]密文,字节[]明文ByTeknown)引发NoSuchPaddingException,NoSuchAlgorithmException,InvalidAlgorithmParameterException,InvalidKeyException{
SecretKeySpec keySpecDecode=新的SecretKeySpec(键,“AES”);
IvParameterSpec ivParameterSpecDecode=新的IvParameterSpec(iv);
Cipher cipherDecrypt=Cipher.getInstance(“AES/CBC/PKCS5Padding”);
cipherDecrypt.init(Cipher.DECRYPT_模式,keySpecDecode,ivParameterSpecDecode);
byte[]decryptedtext=新字节[0];
试一试{
decryptedtext=cipherDecrypt.doFinal(密文);
}捕获(非法块大小异常e){
e、 printStackTrace();
}捕获(BadPaddingException e){
//e、 printStackTrace();
返回false;
}
//部分数组比较
boolean find=ByteBuffer.wrap(decryptedtext,0,5).equals(ByteBuffer.wrap(plaintextbyteKnown,0,5));
如果(found==false){return false;}
System.out.println(“***键已找到***”);
System.out.println(“键长度:+key.length+”数据:+bytesToHex(键));
System.out.println(“纯文本:+新字符串(解密文本));
系统出口(0);
返回true;
}
私有静态字符串bytesToHex(字节[]字节){
StringBuffer结果=新的StringBuffer();
for(byte b:bytes)result.append(Integer.toString((b&0xff)+0x100,16).子字符串(1));
返回result.toString();
}
}
不是p
AES CBC String Encryption - brute force decryption
key      length: 16 data: 0cb878f9da009be3ef487f54aa8c3230
keyGuess length: 16 data: 0cb878f9da009be3ef487f54aa8c0000
*** key found ***
key      length: 16 data: 0cb878f9da009be3ef487f54aa8c3230
plaintext: hello this is just plaintext
import javax.crypto.BadPaddingException;
import javax.crypto.Cipher;
import javax.crypto.IllegalBlockSizeException;
import javax.crypto.NoSuchPaddingException;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
import java.nio.ByteBuffer;
import java.nio.charset.StandardCharsets;
import java.security.InvalidAlgorithmParameterException;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.security.SecureRandom;

public class Main {
    public static void main(String[] args) throws Exception {
        System.out.println("AES CBC String Encryption - brute force decryption");

        String plaintext = "hello this is just plaintext";
        // this plaintext beginning is known
        String plaintextKnown = "hello";
        byte[] plaintextKnownByte = plaintextKnown.getBytes(StandardCharsets.UTF_8);
        // number of known bytes of the key
        int numberKeyBytes = 14; // 14 bytes = 112 bit known bits
        // random key & iv
        SecureRandom random = new SecureRandom();
        byte[] key = new byte[16]; // 16 byte = 128 bit keylength
        random.nextBytes(key);
        byte[] iv = new byte[16];
        random.nextBytes(iv);
        System.out.println("key      length: " + key.length + " data: " + bytesToHex(key));
        // setup cbc
        SecretKeySpec keySpec = new SecretKeySpec(key, "AES");
        IvParameterSpec ivParameterSpec = new IvParameterSpec(iv);
        Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
        cipher.init(Cipher.ENCRYPT_MODE, keySpec, ivParameterSpec);
        // get plaintext
        byte[] plaintextByte = plaintext.getBytes(StandardCharsets.UTF_8);
        byte[] ciphertextByte = cipher.doFinal(plaintextByte);

        byte[] keyGuessed = new byte[16];
        System.arraycopy(key, 0, keyGuessed, 0, numberKeyBytes ); // copy first 14 bytes = 112 bit
        System.out.println("keyGuess length: " + keyGuessed.length + " data: " + bytesToHex(keyGuessed));
        for (int a = 0; a < 256; a++) {
            for (int b = 0; b < 256; b++) {
                for (int c = 0; c < 256; c++) {
                    for (int d = 0; d < 256; d++) {
                        keyGuessed[15] = (byte) d;
                        //System.out.println("keyGuess length: " + keyGuessed.length + " data: " + bytesToHex(keyGuessed));
                        decryptAesCbc128(keyGuessed, iv, ciphertextByte, plaintextKnownByte);
                    }
                    keyGuessed[14] = (byte) c;
                }
                keyGuessed[13] = (byte) b;
            }
            keyGuessed[12] = (byte) a;
        }
    }

    private static boolean decryptAesCbc128(byte[] key, byte[] iv, byte[] ciphertext, byte[] plaintextbyteKnown) throws NoSuchPaddingException, NoSuchAlgorithmException, InvalidAlgorithmParameterException, InvalidKeyException {
        SecretKeySpec keySpecDecode = new SecretKeySpec(key, "AES");
        IvParameterSpec ivParameterSpecDecode = new IvParameterSpec(iv);
        Cipher cipherDecrypt = Cipher.getInstance("AES/CBC/PKCS5Padding");
        cipherDecrypt.init(Cipher.DECRYPT_MODE, keySpecDecode, ivParameterSpecDecode);
        byte[] decryptedtext = new byte[0];
        try {
            decryptedtext = cipherDecrypt.doFinal(ciphertext);
        } catch (IllegalBlockSizeException e) {
            e.printStackTrace();
        } catch (BadPaddingException e) {
            //e.printStackTrace();
            return false;
        }
        // partial array comparison
        boolean found = ByteBuffer.wrap(decryptedtext, 0, 5).equals(ByteBuffer.wrap(plaintextbyteKnown, 0, 5));
        if (found == false) {return false;}
        System.out.println("*** key found ***");
        System.out.println("key      length: " + key.length + " data: " + bytesToHex(key));
        System.out.println("plaintext: " + new String(decryptedtext));
        System.exit(0);
        return true;
    }

    private static String bytesToHex(byte[] bytes) {
        StringBuffer result = new StringBuffer();
        for (byte b : bytes) result.append(Integer.toString((b & 0xff) + 0x100, 16).substring(1));
        return result.toString();
    }
}