Расшифровка Java CBC работает, но CTR не работает
Я установил программу для класса, который я беру на крипто. Я буду следовать этому с моим кодом и другим разделом для моих различий переменных. Моя цель - расшифровать текст для нашей домашней работы. Я не хочу, чтобы кто-то расшифровывал это для меня, но хотел бы получить некоторую помощь относительно того, что вызывает это в моем коде. Когда я расшифровываю CBC, я получаю правильный вывод без проблем, хотя в нем есть некоторые дополнительные символы (это может быть проблема с заполнением? Я не уверен)
Затем, когда я использую CTR с правильными изменениями, он возвращает кучу мусора. Любая помощь будет принята с благодарностью. Спасибо,
CBC:
CBC key: 140b41b22a29beb4061bda66b6747e14
CBC Ciphertext 1:
4ca00ff4c898d61e1edbf1800618fb2828a226d160dad07883d04e008a7897ee2e4b7465d5290d0c0e6c6822236e1daafb94ffe0c5da05d9476be028ad7c1d81
CTR:
CTR key: 36f18357be4dbd77f050515c73fcf9f2
CTR Ciphertext 1:
69dda8455c7dd4254bf353b773304eec0ec7702330098ce7f7520d1cbbb20fc388d1b0adb5054dbd7370849dbf0b88d393f252e764f1f5f7ad97ef79d59ce29f5f51eeca32eabedd9afa9329
Переменные CBC
String algorithm = "AES";
String mode = "CBC";
String padding = "PKCS5Padding";
byte[] ciphertextBytes = StringToByte("4ca00ff4c898d61e1edbf1800618fb2828a226d160dad07883d04e008a7897ee2e4b7465d5290d0c0e6c6822236e1daafb94ffe0c5da05d9476be028ad7c1d81");
byte[] keyBytes = StringToByte("140b41b22a29beb4061bda66b6747e14");
Переменные CTR
String algorithm = "AES";
String mode = "CTR";
String padding = "NoPadding";
byte[] ciphertextBytes = StringToByte("770b80259ec33beb2561358a9f2dc617e46218c0a53cbeca695ae45faa8952aa0e311bde9d4e01726d3184c34451");
byte[] keyBytes = StringToByte("36f18357be4dbd77f050515c73fcf9f2");
Расшифровать Main
import javax.crypto.Cipher;
import javax.crypto.SecretKey;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
import java.security.SecureRandom;
import static java.lang.Character.digit;
public class CryptoClass {
public static void main(String[] args) throws Exception {
byte[] decryptByte = Decrypt();
String hexString = ByteToHex(decryptByte);
StringBuilder decryptedString = HexToString(hexString);
System.out.println(decryptedString);
}
public static byte[] Decrypt() throws Exception {
//
String algorithm = "AES";
String mode = "CTR";
String padding = "NoPadding";
byte[] ciphertextBytes = StringToByte("770b80259ec33beb2561358a9f2dc617e46218c0a53cbeca695ae45faa8952aa0e311bde9d4e01726d3184c34451");
byte[] keyBytes = StringToByte("36f18357be4dbd77f050515c73fcf9f2");
IvParameterSpec ivParamSpec = null;
int ivSize = 16;
byte[] iv = new byte[ivSize];
SecureRandom secureRandom = SecureRandom.getInstance("SHA1PRNG");
secureRandom.nextBytes(iv);
ivParamSpec = new IvParameterSpec(iv);
SecretKey aesKey = new SecretKeySpec(keyBytes, "AES");
Cipher cipher = Cipher.getInstance(algorithm + "/" + mode + "/" + padding, "JsafeJCE");
cipher.init(Cipher.DECRYPT_MODE, aesKey, ivParamSpec);
byte[] result = cipher.doFinal(ciphertextBytes);
return result;
}
//convert ByteArray to Hex String
public static String ByteToHex(byte[] byteArray) {
StringBuilder sb = new StringBuilder();
for (byte b : byteArray)
{
sb.append(String.format("%02X", b));
}
return sb.toString();
}
//convert String to ByteArray
private static byte[] StringToByte(String input) {
int length = input.length();
byte[] output = new byte[length / 2];
for (int i = 0; i < length; i += 2) {
output[i / 2] = (byte) ((digit(input.charAt(i), 16) << 4) | digit(input.charAt(i+1), 16));
}
return output;
}
//changes a hex string into plain text
public static StringBuilder HexToString(String hex) throws Exception {
StringBuilder output = new StringBuilder();
for (int i = 0; i < hex.length(); i+=2) {
String str = hex.substring(i, i+2);
output.append((char)Integer.parseInt(str, 16));
}
return output;
}
}
* Изменить метод для решения - вместо случайного IV я вытащил IV из первых 16 бит зашифрованного текста. В задании указывалось, что это так, и по какой-то причине я замаскировал его, когда просматривал в первый раз.
public static byte[] Decrypt() throws Exception {
String algorithm = "AES";
String mode = "CTR";
String padding = "NoPadding";
byte[] ciphertextBytes = StringToByte("0ec7702330098ce7f7520d1cbbb20fc388d1b0adb5054dbd7370849dbf0b88d393f252e764f1f5f7ad97ef79d59ce29f5f51eeca32eabedd9afa9329");
byte[] keyBytes = StringToByte("36f18357be4dbd77f050515c73fcf9f2");
//int ivSize = 16;
//byte[] iv = new byte[ivSize];
//SecureRandom secureRandom = SecureRandom.getInstance("SHA1PRNG");
//secureRandom.nextBytes(iv);
byte[] ivParamSpecTMP = StringToByte("69dda8455c7dd4254bf353b773304eec");
IvParameterSpec ivParameterSpec = new IvParameterSpec(ivParamSpecTMP);
SecretKey aesKey = new SecretKeySpec(keyBytes, "AES");
Cipher cipher = Cipher.getInstance(algorithm + "/" + mode + "/" + padding, "JsafeJCE");
cipher.init(Cipher.DECRYPT_MODE, aesKey, ivParameterSpec);
byte[] result = cipher.doFinal(ciphertextBytes);
return result;
1 ответ
Хитрость заключается в том, что вы должны отправить IV (в виде простого текста) получателю. Если вы случайно сгенерируете IV перед расшифровкой, вы получите мусор по определению. Случайные IV должны генерироваться только перед шифрованием.
улица