这是作业。我们的教授用CBC模式的AES-256加密了一条消息(密钥是256位)。然后他给了我他使用的IV(我的代码中randomized
),加密的消息和密钥的后半部分(keySuffix
),密钥是十六进制的,IV也是。我们必须使用暴力破解并解密该消息。消息是长度为8的块,由1和0组成,中间有空格(cryptogram
)。我所做的就是摆脱空间,将密码转换为byteArray
(你可以在代码中看到我是如何做到的)。关于密钥,我只做getBytes()
,在IV上我使用DatatypeConverter.parseHexBinary()
否则它会抛出关于错误的IV长度的错误。当我收到消息时,我使用new String(myByteArray)
将其作为字符串返回。然后我检查该消息是否包含所有正常字符(而不是一些'灌木丛')。
重点是我没有结果。我不知道这里可能出现了什么问题,我的猜测是有些转换不是以它们应该的方式完成的。我一直在用unicodes等尝试一些东西,但是蛮力需要很长时间才能完成,这样的测试很麻烦。有人能指出我正确的方向,比如如何进行转换。为密钥的另一端生成所有可能的字符串工作正常。
顺便说一句。 PKCS5Padding发出错误。
public class Main {
private String randomized = "21232d0960a7b522d3e25141e54ecee6";
private String keySuffix = "1dad418a";
private String cryptogram = "00110001 01111000 01111101 01111100 01100001 11011110 10010010 01011011";
private byte[] cryptogramBytes;
private String pattern = "[a-zA-Z1-9\\s]*";
private IvParameterSpec ivSpec = null;
private Cipher cipher = null;
public static void main(String... args){
char[] elements = { 'a', 'b', 'c', 'd', 'e', 'f', '1', '2', '3', '4', '5', '6', '7', '8', '9', '0' };
char[] buff = new char[8];
Main main = new Main ();
byte[] convertedRandomized = DatatypeConverter.parseHexBinary(main.randomized);
main.ivSpec = new IvParameterSpec(convertedRandomized);
main.cryptogram = main.cryptogram.replaceAll("\\s", "");
BigInteger bigint = new BigInteger(main.cryptogram, 2);
main.cryptogramBytes = bigint.toByteArray();
main.cipher = Cipher.getInstance("AES/CBC/NoPadding");
main.permGen(elements, 0, 8, buff);
}
public void permGen(char[] s, int i, int k, char[] buff){
if (i < k) {
for (int j = 0; j < s.length; j++) {
buff[i] = s[j];
permGen(s, i + 1, k, buff);
}
} else {
String result = decrypt(String.valueOf(buff) + keySuffix);
if (result.matches(pattern))
System.out.println("Key is: " + String.valueOf(buff) + keySuffix);
}
}
public String decrypt(String key){
SecretKeySpec skeySpec = new SecretKeySpec(key.getBytes(), "AES");
cipher.init(Cipher.DECRYPT_MODE, skeySpec, ivSpec);
return new String(cipher.doFinal(cryptogramBytes));
}
}