Как преобразовать String в SecretKey

Я хочу преобразовать String в secretKey

public void generateCode(String keyStr){ KeyGenerator kgen = KeyGenerator.getInstance("AES"); kgen.init(128); // 192 and 256 bits may not be available // Generate the secret key specs. secretKey skey=keyStr; //How can I make the casting here //SecretKey skey = kgen.generateKey(); byte[] raw = skey.getEncoded(); } 

Я пытаюсь использовать BASE64Decoder вместо secretKey, но сталкиваюсь с проблемой, которую я не могу указать длину ключа.

EDIT: я хочу вызвать эту функцию из другого места

  static public String encrypt(String message , String key , int keyLength) throws Exception { // Get the KeyGenerator KeyGenerator kgen = KeyGenerator.getInstance("AES"); kgen.init(keyLength); // 192 and 256 bits may not be available // Generate the secret key specs. SecretKey skey = key; //here is the error byte[] raw = skey.getEncoded(); SecretKeySpec skeySpec = new SecretKeySpec(raw, "AES"); // Instantiate the cipher Cipher cipher = Cipher.getInstance("AES"); cipher.init(Cipher.ENCRYPT_MODE, skeySpec); System.out.println("msg is" + message + "\n raw is" + raw); byte[] encrypted = cipher.doFinal(message.getBytes()); String cryptedValue = new String(encrypted); System.out.println("encrypted string: " + cryptedValue); return cryptedValue; } 

Если бы кто-нибудь мог помочь, я был бы очень благодарен.

Никакие проверки целостности по этим конкретным причинам

  1. Потребность не очевидна из варианта использования.
  2. Режим "AES/GCM/NoPadding" доступен только с Java 7 onward
  3. Это зависит от пользователя, если он хочет развернуть, например, HMAC и / или AESCMAC (рекомендуется).
  4. Это потребует дополнительного ключа как минимум, и двух полных проходов.

Если у вас есть реализация режима GCM с обеих сторон – например, с помощью Bouncy Castle на Java 6 – пожалуйста, ищите его, поскольку он намного безопаснее (пока «IV» действительно уникален). Это должно быть очень легко изменить реализацию.

Замечания по внедрению шифрования

  1. Эта реализация небезопасна при использовании в неограниченной роли клиент / сервер из-за атаки на оскорбительные атаки (в среднем они требуют 128 попыток на байт или ниже, независимо от алгоритма или размера ключа). Вам нужно будет использовать MAC, HMAC или Signature над зашифрованными данными и проверить его перед расшифровкой, чтобы развернуть его в режиме клиент / сервер.
  2. Decrypt вернет значение null, если дешифрование завершится с ошибкой. Это может указывать только на исключение заполнения, которое должно быть надлежащим образом обработано (предупреждаю ли я об отложенных атаках oracleа?)
  3. Недействительные ключи будут возвращены как InvalidArgumentException .
  4. Все другие исключения, связанные с безопасностью, «подметаются под таблицу», поскольку это означает, что среда выполнения Java недействительна. Например, поддержка "UTF-8" и "AES/CBC/PKCS5Padding" требуется для каждой реализации Java SE.

Некоторые другие примечания

  1. Пожалуйста, не пытайтесь сделать обратное и вставьте байты непосредственно во входную строку метода шифрования (например, используя new String(byte[]) ). Метод может терпеть неудачу!
  2. Оптимизирован для удобства чтения. Переходите к реализациям Base64 и CipherStream если вы предпочитаете скорость и лучший объем памяти.
  3. Вам нужен хотя бы Java 6 SE или совместимый для запуска этого кода.
  4. Шифрование / дешифрование может завершиться с ошибкой для ключей AES размером более 128 бит, поскольку вам могут понадобиться файлы политики для неограниченного шифрования (доступные от Oracle)
  5. Остерегайтесь правительственных правил при экспорте шифрования.
  6. Эта реализация использует шестнадцатеричные ключи вместо ключей base64, поскольку они достаточно малы, а hex проще просто отредактировать / проверить вручную.
  7. Используемые кодировки / декодирования hex и base64, извлеченные из JDK, не требовали каких-либо внешних библиотек.
  8. Uber прост в использовании, но, конечно, не очень объектно-ориентированный, не кэширование экземпляров объектов, используемых в шифровании / расшифровке. Рефакторинг по желанию.

ОК, вот какой код …

  public static String encrypt(final String plainMessage, final String symKeyHex) { final byte[] symKeyData = DatatypeConverter.parseHexBinary(symKeyHex); final byte[] encodedMessage = plainMessage.getBytes(Charset .forName("UTF-8")); try { final Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding"); final int blockSize = cipher.getBlockSize(); // create the key final SecretKeySpec symKey = new SecretKeySpec(symKeyData, "AES"); // generate random IV using block size (possibly create a method for // this) final byte[] ivData = new byte[blockSize]; final SecureRandom rnd = SecureRandom.getInstance("SHA1PRNG"); rnd.nextBytes(ivData); final IvParameterSpec iv = new IvParameterSpec(ivData); cipher.init(Cipher.ENCRYPT_MODE, symKey, iv); final byte[] encryptedMessage = cipher.doFinal(encodedMessage); // concatenate IV and encrypted message final byte[] ivAndEncryptedMessage = new byte[ivData.length + encryptedMessage.length]; System.arraycopy(ivData, 0, ivAndEncryptedMessage, 0, blockSize); System.arraycopy(encryptedMessage, 0, ivAndEncryptedMessage, blockSize, encryptedMessage.length); final String ivAndEncryptedMessageBase64 = DatatypeConverter .printBase64Binary(ivAndEncryptedMessage); return ivAndEncryptedMessageBase64; } catch (InvalidKeyException e) { throw new IllegalArgumentException( "key argument does not contain a valid AES key"); } catch (GeneralSecurityException e) { throw new IllegalStateException( "Unexpected exception during encryption", e); } } public static String decrypt(final String ivAndEncryptedMessageBase64, final String symKeyHex) { final byte[] symKeyData = DatatypeConverter.parseHexBinary(symKeyHex); final byte[] ivAndEncryptedMessage = DatatypeConverter .parseBase64Binary(ivAndEncryptedMessageBase64); try { final Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding"); final int blockSize = cipher.getBlockSize(); // create the key final SecretKeySpec symKey = new SecretKeySpec(symKeyData, "AES"); // retrieve random IV from start of the received message final byte[] ivData = new byte[blockSize]; System.arraycopy(ivAndEncryptedMessage, 0, ivData, 0, blockSize); final IvParameterSpec iv = new IvParameterSpec(ivData); // retrieve the encrypted message itself final byte[] encryptedMessage = new byte[ivAndEncryptedMessage.length - blockSize]; System.arraycopy(ivAndEncryptedMessage, blockSize, encryptedMessage, 0, encryptedMessage.length); cipher.init(Cipher.DECRYPT_MODE, symKey, iv); final byte[] encodedMessage = cipher.doFinal(encryptedMessage); // concatenate IV and encrypted message final String message = new String(encodedMessage, Charset.forName("UTF-8")); return message; } catch (InvalidKeyException e) { throw new IllegalArgumentException( "key argument does not contain a valid AES key"); } catch (BadPaddingException e) { // you'd better know about padding oracle attacks return null; } catch (GeneralSecurityException e) { throw new IllegalStateException( "Unexpected exception during decryption", e); } } 

Применение:

  String plain = "Zaphod's just zis guy, ya knöw?"; String encrypted = encrypt(plain, "000102030405060708090A0B0C0D0E0F"); System.out.println(encrypted); String decrypted = decrypt(encrypted, "000102030405060708090A0B0C0D0E0F"); if (decrypted != null && decrypted.equals(plain)) { System.out.println("Hey! " + decrypted); } else { System.out.println("Bummer!"); } 

Вот версия, использующая class Base64 Util вместо DatatypeConverter

 public static String encrypt(final String plainMessage, final String symKeyHex) { final byte[] symKeyData = Base64.decode(symKeyHex,Base64.DEFAULT); final byte[] encodedMessage = plainMessage.getBytes(Charset .forName("UTF-8")); try { final Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding"); final int blockSize = cipher.getBlockSize(); // create the key final SecretKeySpec symKey = new SecretKeySpec(symKeyData, "AES"); // generate random IV using block size (possibly create a method for // this) final byte[] ivData = new byte[blockSize]; final SecureRandom rnd = SecureRandom.getInstance("SHA1PRNG"); rnd.nextBytes(ivData); final IvParameterSpec iv = new IvParameterSpec(ivData); cipher.init(Cipher.ENCRYPT_MODE, symKey, iv); final byte[] encryptedMessage = cipher.doFinal(encodedMessage); // concatenate IV and encrypted message final byte[] ivAndEncryptedMessage = new byte[ivData.length + encryptedMessage.length]; System.arraycopy(ivData, 0, ivAndEncryptedMessage, 0, blockSize); System.arraycopy(encryptedMessage, 0, ivAndEncryptedMessage, blockSize, encryptedMessage.length); final String ivAndEncryptedMessageBase64 = Base64.encodeToString(ivAndEncryptedMessage,Base64.DEFAULT); return ivAndEncryptedMessageBase64; } catch (InvalidKeyException e) { throw new IllegalArgumentException( "key argument does not contain a valid AES key"); } catch (GeneralSecurityException e) { throw new IllegalStateException( "Unexpected exception during encryption", e); } } public static String decrypt(final String ivAndEncryptedMessageBase64, final String symKeyHex) { final byte[] symKeyData = Base64.decode((symKeyHex),Base64.DEFAULT); final byte[] ivAndEncryptedMessage = Base64.decode(ivAndEncryptedMessageBase64,Base64.DEFAULT); try { final Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding"); final int blockSize = cipher.getBlockSize(); // create the key final SecretKeySpec symKey = new SecretKeySpec(symKeyData, "AES"); // retrieve random IV from start of the received message final byte[] ivData = new byte[blockSize]; System.arraycopy(ivAndEncryptedMessage, 0, ivData, 0, blockSize); final IvParameterSpec iv = new IvParameterSpec(ivData); // retrieve the encrypted message itself final byte[] encryptedMessage = new byte[ivAndEncryptedMessage.length - blockSize]; System.arraycopy(ivAndEncryptedMessage, blockSize, encryptedMessage, 0, encryptedMessage.length); cipher.init(Cipher.DECRYPT_MODE, symKey, iv); final byte[] encodedMessage = cipher.doFinal(encryptedMessage); // concatenate IV and encrypted message final String message = new String(encodedMessage, Charset.forName("UTF-8")); return message; } catch (InvalidKeyException e) { throw new IllegalArgumentException( "key argument does not contain a valid AES key"); } catch (BadPaddingException e) { // you'd better know about padding oracle attacks return null; } catch (GeneralSecurityException e) { throw new IllegalStateException( "Unexpected exception during decryption", e); } } 

Просто напоминание для тех, кто получает исключение Padding. Убедитесь, что вы используете правильную длину ключа. Подсказка: посмотрите на сообщение Маартен: его шестнадцатеричный ровно 32;) Это не совпадение 🙂

  • Как использовать OpenSSL для шифрования / дешифрования файлов?
  • Использование SHA1 и RSA с java.security.Signature против MessageDigest и Cipher
  • Зашифрованы ли заголовки HTTPS?
  • Как выбрать режим шифрования AES (CBC ECB CTR OCB CFB)?
  • Любой исходный код cocoa для расшифровки шифрования AES?
  • Указанный ключ не является допустимым для этого алгоритма
  • Шифрование OpenSSL с использованием classов .NET
  • Как создать уникальный открытый и закрытый ключ через RSA
  • Почему неправильный пароль приводит к тому, что «Заполнение недопустима и не может быть удалено»?
  • Iphone - Как шифровать NSData с открытым ключом и расшифровывать с помощью закрытого ключа?
  • шифровать данные в SharedPreferences
  • Interesting Posts

    Сравнение использования памяти в браузере: встроенный onClick против использования JQuery .bind ()

    Соглашение об именах classов CSS

    Как передать переменное количество аргументов printf / sprintf

    Установите розничный диск Windows 7 Ultimate с ключом OEM для домашнего ПК Premium Premium

    Ручки против потоков против процессов

    Как определить, была ли перенаправлена ​​Console.In (stdin)?

    Пользовательский макет, который округляет углы его содержимого

    Ошибка MBR для установки Windows

    Элемент модели, переданный в словарь, имеет тип «mvc.Models.ModelA», но для этого словаря требуется элемент модели типа «mvc.Models.ModelB»

    Как отображать всплывающие подсказки в Tkinter?

    Является ли запись закрывающих тегов для элементов, которые не являются традиционно пустой плохой практикой?

    Как явным образом создаю экземпляр функции шаблона?

    Ядро Java swingWorker работает, но не получено или передано сообщение

    Что такое objc_setAssociatedObject () и в каких случаях его следует использовать?

    SQLite с поддержкой readline на Ubuntu

    Давайте будем гением компьютера.