2017-01-17 5 views
0

Благодарим вас за то, что вы нашли время, чтобы помочь мне в этом!(AES Encryption) Недостатки кода, с чем мне следует быть осторожным? [Предоставлено кодом] [Java]

Сообщения редактировали МЕНЬШЕ ИНФОРМАЦИЮ СМОТРИТЕ Отредактированную ЧАСТЬ

Ну я проводить наши исследования по этому вопросу, и я закончил с рабочим куском коды ..

Но Шифрование это не место для ошибок, и я хотел спросить, действительно ли мой код безопасен! Это очень важно для меня, потому что я хочу, чтобы реализовать его в программу, чтобы мой код ...

import java.nio.file.Files; 
import java.nio.file.Paths; 

import java.util.Base64; 

import javax.crypto.*; 
import javax.crypto.spec.SecretKeySpec; 
import java.security.SecureRandom; 


public class EncryptFile{ 
    private static final String FILE_IN = "./EncryptFile.java"; 
    private static final String FILE_ENCR = "./EncryptFile_encr.java"; 
    private static final String FILE_DECR = "./EncryptFile_decr.java"; 
    public static void main(String []args){ 
     try 
     { 
      Encryption("passwordisnottheactual", Files.readAllBytes(Paths.get(FILE_IN))); 
      Decryption("passwordisnottheactual"); 

     }catch(Exception e){ 
      System.out.println(e.getMessage()); 
     } 
    } 
    private static void Encryption(String Key, byte[] byteArray) throws Exception 
    { 
     // Decode the base64 encoded Key 
     byte[] decodedKey = Base64.getDecoder().decode(Key); 
     // Rebuild the key using SecretKeySpec 
     SecretKey secretKey = new SecretKeySpec(decodedKey, 0, decodedKey.length, "AES"); 

     // Cipher gets AES Algorithm instance 
     Cipher AesCipher = Cipher.getInstance("AES"); 

     //Initialize AesCipher with Encryption Mode, Our Key and A ?SecureRandom? 
     AesCipher.init(Cipher.ENCRYPT_MODE, secretKey, new SecureRandom()); 
     byte[] byteCipherText = AesCipher.doFinal(byteArray); 

     //Write Bytes To File 
     Files.write(Paths.get(FILE_ENCR), byteCipherText); 


    } 
    private static void Decryption(String Key) throws Exception 
    { 
     //Ddecode the base64 encoded string 
     byte[] decodedKey = Base64.getDecoder().decode(Key); 
     //Rebuild key using SecretKeySpec 
     SecretKey secretKey = new SecretKeySpec(decodedKey, 0, decodedKey.length, "AES"); 

     //Read All The Bytes From The File 
     byte[] cipherText = Files.readAllBytes(Paths.get(FILE_ENCR)); 

     //Cipher gets AES Algorithm Instance 
     Cipher AesCipher = Cipher.getInstance("AES"); 

     //Initialize it in Decrypt mode, with our Key, and a ?SecureRandom? 
     AesCipher.init(Cipher.DECRYPT_MODE, secretKey, new SecureRandom()); 

     byte[] bytePlainText = AesCipher.doFinal(cipherText); 
     Files.write(Paths.get(FILE_DECR), bytePlainText); 
    } 
} 

EDIT

Возможный дубликат Простой Java AES шифрования/дешифрования пример - JFPicard

Ну это может быть, но эти ответы Используйте IVParameterSpec, и я хотел бы знать, если эта строка кода на самом деле безопасно или если это плохая практика:

AesCipher.init(Cipher.DECRYPT_MODE, secretKey, new SecureRandom()); 

потому что я использую new SecureRandom() каждый раз, , и я не видел, чтобы кто использовать объект SecureRandom как это.

+3

Лучше попробуйте http://codereview.stackexchange.com/, так как SO, вероятно, не рассмотрит ваш код. –

+0

Возможный дубликат [Простой пример AES для шифрования/расшифровки Java] (http://stackoverflow.com/questions/15554296/simple-java-aes-encrypt-decrypt-example) – JFPicard

ответ

2
  1. Ключ шифрования
    • При вводе пароля проходит в виде строки, но Encryption функции Base64 декодирует его, что это ошибка кодирования.
    • При использовании пароля ключ шифрования должен быть выведен из него с помощью функции PBKDF2 (aka Rfc2898DeriveBytes).
    • При использовании деривации ключей для дешифрования должны быть доступны счет соли и итераций, часто они предоставляются в префиксе для зашифрованных данных.
  2. режим шифрования
    • Нет Режим шифрования не поставляется.
    • Используйте режим CBC со случайным IV.
    • Просто префикс зашифрованных данных с IV для использования при расшифровке.
  3. Набивки
    • AES представляет собой блочный шифр, и как таковые требует размера входных данных, чтобы быть кратным размером блока.
    • Укажите дополнение PKCS # 7 (né PKCS # 5), оно добавит дополнение к шифрованию и удалит его при расшифровке.
    • При расшифровке не возвращаются ошибки «заполнения», они могут обеспечить атаку «Padding Oracle».
  4. Явная
    • Укажите все параметры шифрования и размеры.
    • Не полагайтесь на значения по умолчанию для реализации.
  5. аутентификации Шифрование
    • Рассмотрим, если есть необходимость знать, если данные правильно расшифрованы.
  6. Versioning
    • Добавить индикатор версии, так что если изменения необходимы позже есть путь совместимости.

Или рассмотреть вопрос об использовании RNCryptor, который обрабатывает все это и многое другое.

Update: (спасибо Энди за комментарий)
Если режим GCM доступен и взаимодействия на разных платформах и библиотек не является проблемой GCM, возможно, лучший режим шифрования. GCM имеет встроенную аутентификацию и дополнение, что делает его более надежным и более безопасным решением.

+0

Я бы порекомендовал 'AES/GCM' над' CBC '- CBC обеспечивает конфиденциальность, но не гарантирует целостность, а накладные расходы на тег аутентификации GCM незначительны (на чипах AES-NI он довольно эффективен). – Andy

+0

Я согласен с тем, что режим GCM лучше в нескольких отношениях - за исключением доступности на разных платформах и библиотеках, которые не хватает. – zaph

+0

Действительно любопытно - вы рассматриваете возможности HW или платформы с ограниченным пространством здесь? Я не могу придумать ничего за последние 4 года, которое запускает Java, но не может обрабатывать GCM. OP использует NIO2, поэтому по крайней мере Java 7. Я согласен с вашей оценкой доступности GCM, но не думал, что это ограничивающий фактор здесь. – Andy

 Смежные вопросы

  • Нет связанных вопросов^_^