Java AES и использование моего собственного ключа
Я хочу зашифровать строку с помощью AES с моим собственным ключом. Но у меня возникли проблемы с длиной бита ключа. Вы можете просмотреть мой код и посмотреть, что мне нужно исправить/изменить.
public static void main(String[] args) throws Exception {
String username = "bob@google.org";
String password = "Password1";
String secretID = "BlahBlahBlah";
String SALT2 = "deliciously salty";
// Get the Key
byte[] key = (SALT2 + username + password).getBytes();
System.out.println((SALT2 + username + password).getBytes().length);
// Need to pad key for AES
// TODO: Best way?
// Generate the secret key specs.
SecretKeySpec secretKeySpec = new SecretKeySpec(key, "AES");
// Instantiate the cipher
Cipher cipher = Cipher.getInstance("AES");
cipher.init(Cipher.ENCRYPT_MODE, secretKeySpec);
byte[] encrypted = cipher.doFinal((secrectID).getBytes());
System.out.println("encrypted string: " + asHex(encrypted));
cipher.init(Cipher.DECRYPT_MODE, secretKeySpec);
byte[] original = cipher.doFinal(encrypted);
String originalString = new String(original);
System.out.println("Original string: " + originalString + "nOriginal string (Hex): " + asHex(original));
}
сейчас я получаю исключение "недопустимая длина ключа AES: 86 байт". Мне нужно положить мой ключ? Как мне это сделать?
также мне нужно установить что-нибудь для ECB или CBC?
спасибо
5 ответов:
вы должны использовать SHA-1 для создания хэша из вашего ключа и обрезать результат до 128 бит (16 байт).
дополнительно не генерировать массивы байтов из строк через getBytes () Он использует кодировку платформы по умолчанию. Таким образом, пароль "blaöä" приводит к различным массивам байтов на разных платформах.
byte[] key = (SALT2 + username + password).getBytes("UTF-8"); MessageDigest sha = MessageDigest.getInstance("SHA-1"); key = sha.digest(key); key = Arrays.copyOf(key, 16); // use only first 128 bit SecretKeySpec secretKeySpec = new SecretKeySpec(key, "AES");
изменить: Если вам нужно 256 бит в качестве размеров ключей, вам нужно загрузить " политику юрисдикции неограниченной силы Java Cryptography Extension (JCE Файлы"Oracle download link, используйте SHA-256 в качестве хэша и удалите массивы.копией линии. "ECB" - это режим шифрования по умолчанию, а" PKCS5Padding " - дополнение по умолчанию. Вы можете использовать различные режимы шифрования и режимы заполнения через шифр.getInstance строка в следующем формате: "шифр / режим / заполнение"
для AES с использованием CTS и PKCS5Padding строка: "AES / CTS / PKCS5Padding"
вы должны использовать KeyGenerator для создания ключа,
длина ключа AES составляет 128, 192 и 256 бит в зависимости от шифра, который вы хотите использовать.
взгляните на учебник здесь
вот код для шифрования на основе пароля, это пароль вводится через System.in вы можете изменить это, чтобы использовать сохраненный пароль, если хотите.
PBEKeySpec pbeKeySpec; PBEParameterSpec pbeParamSpec; SecretKeyFactory keyFac; // Salt byte[] salt = { (byte)0xc7, (byte)0x73, (byte)0x21, (byte)0x8c, (byte)0x7e, (byte)0xc8, (byte)0xee, (byte)0x99 }; // Iteration count int count = 20; // Create PBE parameter set pbeParamSpec = new PBEParameterSpec(salt, count); // Prompt user for encryption password. // Collect user password as char array (using the // "readPassword" method from above), and convert // it into a SecretKey object, using a PBE key // factory. System.out.print("Enter encryption password: "); System.out.flush(); pbeKeySpec = new PBEKeySpec(readPassword(System.in)); keyFac = SecretKeyFactory.getInstance("PBEWithMD5AndDES"); SecretKey pbeKey = keyFac.generateSecret(pbeKeySpec); // Create PBE Cipher Cipher pbeCipher = Cipher.getInstance("PBEWithMD5AndDES"); // Initialize PBE Cipher with key and parameters pbeCipher.init(Cipher.ENCRYPT_MODE, pbeKey, pbeParamSpec); // Our cleartext byte[] cleartext = "This is another example".getBytes(); // Encrypt the cleartext byte[] ciphertext = pbeCipher.doFinal(cleartext);
import java.security.Key; import javax.crypto.Cipher; import javax.crypto.spec.SecretKeySpec; import sun.misc.*; import java.io.BufferedReader; import java.io.FileReader; public class AESFile { private static String algorithm = "AES"; private static byte[] keyValue=new byte[] {'0','2','3','4','5','6','7','8','9','1','2','3','4','5','6','7'};// your key // Performs Encryption public static String encrypt(String plainText) throws Exception { Key key = generateKey(); Cipher chiper = Cipher.getInstance(algorithm); chiper.init(Cipher.ENCRYPT_MODE, key); byte[] encVal = chiper.doFinal(plainText.getBytes()); String encryptedValue = new BASE64Encoder().encode(encVal); return encryptedValue; } // Performs decryption public static String decrypt(String encryptedText) throws Exception { // generate key Key key = generateKey(); Cipher chiper = Cipher.getInstance(algorithm); chiper.init(Cipher.DECRYPT_MODE, key); byte[] decordedValue = new BASE64Decoder().decodeBuffer(encryptedText); byte[] decValue = chiper.doFinal(decordedValue); String decryptedValue = new String(decValue); return decryptedValue; } //generateKey() is used to generate a secret key for AES algorithm private static Key generateKey() throws Exception { Key key = new SecretKeySpec(keyValue, algorithm); return key; } // performs encryption & decryption public static void main(String[] args) throws Exception { FileReader file = new FileReader("C://myprograms//plaintext.txt"); BufferedReader reader = new BufferedReader(file); String text = ""; String line = reader.readLine(); while(line!= null) { text += line; line = reader.readLine(); } reader.close(); System.out.println(text); String plainText = text; String encryptedText = AESFile.encrypt(plainText); String decryptedText = AESFile.decrypt(encryptedText); System.out.println("Plain Text : " + plainText); System.out.println("Encrypted Text : " + encryptedText); System.out.println("Decrypted Text : " + decryptedText); } }
Это будет работать.
public class CryptoUtils { private final String TRANSFORMATION = "AES"; private final String encodekey = "1234543444555666"; public String encrypt(String inputFile) throws CryptoException { return doEncrypt(encodekey, inputFile); } public String decrypt(String input) throws CryptoException { // return doCrypto(Cipher.DECRYPT_MODE, key, inputFile); return doDecrypt(encodekey,input); } private String doEncrypt(String encodekey, String inputStr) throws CryptoException { try { Cipher cipher = Cipher.getInstance(TRANSFORMATION); byte[] key = encodekey.getBytes("UTF-8"); MessageDigest sha = MessageDigest.getInstance("SHA-1"); key = sha.digest(key); key = Arrays.copyOf(key, 16); // use only first 128 bit SecretKeySpec secretKeySpec = new SecretKeySpec(key, "AES"); cipher.init(Cipher.ENCRYPT_MODE, secretKeySpec); byte[] inputBytes = inputStr.getBytes(); byte[] outputBytes = cipher.doFinal(inputBytes); return Base64Utils.encodeToString(outputBytes); } catch (NoSuchPaddingException | NoSuchAlgorithmException | InvalidKeyException | BadPaddingException | IllegalBlockSizeException | IOException ex) { throw new CryptoException("Error encrypting/decrypting file", ex); } } public String doDecrypt(String encodekey,String encrptedStr) { try { Cipher dcipher = Cipher.getInstance(TRANSFORMATION); dcipher = Cipher.getInstance("AES"); byte[] key = encodekey.getBytes("UTF-8"); MessageDigest sha = MessageDigest.getInstance("SHA-1"); key = sha.digest(key); key = Arrays.copyOf(key, 16); // use only first 128 bit SecretKeySpec secretKeySpec = new SecretKeySpec(key, "AES"); dcipher.init(Cipher.DECRYPT_MODE, secretKeySpec); // decode with base64 to get bytes byte[] dec = Base64Utils.decode(encrptedStr.getBytes()); byte[] utf8 = dcipher.doFinal(dec); // create new string based on the specified charset return new String(utf8, "UTF8"); } catch (Exception e) { e.printStackTrace(); } return null; } }