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