Защита закрытого ключа на диске с использованием симметричного шифрования в Java - PullRequest
0 голосов
/ 19 февраля 2011

У меня есть распределенное приложение, которое запрашивает команды с центрального сервера, и содержимое этих команд «подписывается» закрытым ключом с открытым ключом, развернутым вместе с приложением на каждом удаленном сайте. Каждая команда подписана с помощью закрытого ключа, и эта подпись проверяется перед выполнением команды.

Вот как я генерирую свои пары открытого и закрытого ключей в Java. (я понимаю, мы должны делать больше 1024)

KeyPairGenerator keyGen = KeyPairGenerator.getInstance("DSA", "SUN");
    SecureRandom random = SecureRandom.getInstance("SHA1PRNG", "SUN");
keyGen.initialize(1024, random);
KeyPair pair = keyGen.generateKeyPair();

Новое требование заключается в том, что в дополнение к отправке простых относительно безопасных команд мы теперь хотим отправлять команды, которые инструктируют наше программное обеспечение загружать и запускать установщик для обновления. Это может открыть большую дыру, если все сделано неправильно. Команда «выполнить обновление установщика» будет подписана как всегда и будет также включать в себя md5 исполняемого файла, который будет загружен и запущен. Таким образом, подпись в команде должна быть правильной (и будет включать md5), а затем вычисленное значение md5 для загруженного файла должно быть правильным, прежде чем произойдет выполнение. Это должно заботиться о большинстве векторов атаки, о которых я могу думать. Есть ли еще какие-то вопросы, которые меня должны волновать?

Итак, теперь я обращаю свое внимание на защиту закрытого ключа на сервере, где эти команды происходят. Если этот закрытый ключ получен, игра окончена. Как мне защитить этот ключ на диске?

Моя мысль состоит в том, чтобы использовать симметричное шифрование с парольной фразой для защиты этого закрытого ключа.

Мое текущее решение выглядит следующим образом:

char[] passphrase; // Actual passphrase
PrivateKey privateKeyObj; // Actual Private Key
byte[] privateKeyBytes = privateKeyObj.getEncoded();

byte[] salt = new byte[8];
new SecureRandom().nextBytes(salt);

SecretKeyFactory factory = SecretKeyFactory.getInstance("PBKDF2WithHmacSHA1");
KeySpec spec = new PBEKeySpec(passphrase, salt, 1024, 256);
SecretKey tmp = factory.generateSecret(spec);
SecretKey secret = new SecretKeySpec(tmp.getEncoded(), "AES");

Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
cipher.init(Cipher.ENCRYPT_MODE, secret);
AlgorithmParameters params = cipher.getParameters();
byte[] iv = params.getParameterSpec(IvParameterSpec.class).getIV();

byte[] ciphertext = cipher.doFinal(privateKeyBytes);

FileOutputStream outputFileStream = new FileOutputStream(outputFile);
outputFileStream.write(salt);
outputFileStream.write(iv);
outputFileStream.write(ciphertext);
outputFileStream.close();

(исключения исключены для ясности)

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

Однако я чувствую, что здесь чего-то не хватает. Как я должен также как-то включить некоторый тип MAC на ключ, чтобы я знал, что получаю правильное описание? Может быть, это так просто, как поместить 5 или 6 байтов известного текста перед закрытым ключом? Плохая парольная фраза прямо сейчас приводит к исключению плохого заполнения, но я читал, что это не всегда так, и некоторые плохие парольные фразы будут декодироваться и приводить к нежелательной. Я чувствую, что мне нужно остерегаться этого.

Может кто-нибудь сообщить мне, если я на правильном пути здесь, и предоставить некоторую обратную связь. Важно, чтобы я получил это как можно более безопасно ..

Ответы [ 2 ]

1 голос
/ 19 февраля 2011

Разумно указывать хеш или HMAC, учитывая, что вы хотите знать, не набрали ли вы свою фразу-пароль. В противном случае ваше решение выглядит разумным для меня.

Еще одна вещь, которую вы можете сделать, чтобы сохранить ее как можно надежнее: отключить ее. Поместите копии на пару USB-ключей, храните один в надежном месте, но под рукой, а резервную копию - в сейфе или у адвоката. Слышно, как получить секретный ключ, если он физически недоступен.

0 голосов
/ 20 ноября 2011

В некоторых ситуациях может не использоваться HMAC или известный префикс, чтобы злоумышленнику было труднее взломать.Обратите внимание, что если вы не включите HMAC, вы все равно получите исключения декодирования в некоторых ситуациях (вызванных неправильным заполнением), которых будет достаточно для распознавания неправильного пароля.

...