首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >AES 128如何在python中使用部分密钥进行暴力破解

AES 128如何在python中使用部分密钥进行暴力破解
EN

Stack Overflow用户
提问于 2020-10-11 16:42:39
回答 1查看 1.9K关注 0票数 0

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

EN

回答 1

Stack Overflow用户

发布于 2020-10-12 05:23:07

很抱歉,我的答案中的源代码是用Java编写的,但是到目前为止,我从来没有用python编写过一行代码。由于您向我们展示了几乎没有自己编写的代码,我假设您需要一个路径来找到一种在python中实现它的方法。

一些基础知识- AES 128加密具有128位或16字节长的密钥,用于加密和稍后解密。你告诉我们你已经知道96位= 12个字节,所以只剩下4个字节可以猜测了。每个字节的“容量”为(整数) 256,因此最多需要测试256 * 256 * 256 * 256个组合= 4,294,967,296个组合。假设密钥是随机的,你需要其中的一半来尝试找到真正的密钥,因此在现实中有2,147,483,648个组合--今天的家用计算机在一个小时或更短的时间内就能做到这一点。

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

代码注释良好,不是针对速度进行优化,而是针对可读性进行优化。最后,您会得到类似下面这样的输出(因为我在CBC模式下对AES使用了一个随机密钥和初始化向量,所以您的输出会有所不同),在线编译器可以在这里找到:https://repl.it/@javacrypto/JavaAesCbc128BruteForce

代码语言:javascript
运行
复制
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

代码:

代码语言:javascript
运行
复制
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();
    }
}
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/64302122

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档