我是python的初学者,所以我需要帮助我有加密文件和部分密钥文件,部分密钥文件有96位的128位,所以我需要猜测其余的密钥和解密文件,提示是第一个词是"hello“在加密我的问题:如何猜测其余的密钥?如何检查密钥是否是正确的密钥,花了多少时间?
发布于 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
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();
}
}
https://stackoverflow.com/questions/64302122
复制相似问题