RHE 7 не соблюдая java безопасное случайное семя - PullRequest
0 голосов
/ 30 апреля 2018

У меня проблемы на руках. Я создал сервис AES для шифрования / дешифрования конфиденциальной информации. Ключ AES генерируется случайным образом с использованием Java SecureRandom. У меня есть защищенный файл, в котором хранится начальное число, и после вызова службы начальное число заполняется в класс Secure Random.

Чтобы убедиться, что это работает, у меня есть следующая логика:

private boolean secureRandom(final String seed) {
  SecureRandom sr1 = new SecureRandom(seed.getBytes(UTF8_CHARSET));
  SecureRandom sr2 = new SecureRandom(seed.getBytes(UTF8_CHARSET));
  //Two secure random with the same seed should generate the same results
  boolean secureRandomWorks = sr1.nextLong() == sr2.nextLong();
  if (!secureRandomWorks) {
    System.err.println("Secure random not supported. Defaulting to old key");
  }
  return secureRandomWorks;
}

Идея в том, что я должен иметь возможность создавать два безопасных случайных объекта с одинаковым начальным числом, и они оба должны возвращать одно и то же значение при вызове nextLong()

Когда я развертываю свое приложение на машине с Windows, это работает нормально, но когда я развертываю его на машине с RHEL 7, я получаю ошибку.

У меня сложилось впечатление, что до тех пор, пока начальное число одинаково, оба экземпляра всегда будут давать один и тот же результат. Это похоже на случай с Windows, но не тогда, когда я тестировал его на RHEL 7, похоже, что это не так.

Я создал этот простой тест для проверки:

SecureRandom sr1 = new SecureRandom("encryptionKey".getBytes("UTF-8"));
SecureRandom sr2 = new SecureRandom("encryptionKey".getBytes("UTF-8"));

for (int i = 0; i < 1000; i++) {
  System.out.println(sr1.nextLong() == sr2.nextLong());
}

И в windows каждый вывод был верным, в то время как в RHEL 7 это было ложно.

Есть какие-нибудь идеи по поводу того, что может заставить RHEL 7 игнорировать семя?

Ответы [ 2 ]

0 голосов
/ 01 мая 2018

Оказывается, что RHEL 7 (и машины Linux в целом) использует другой алгоритм по умолчанию, чем windows. Linux использует NativePRNG, в то время как Windows использует SHA1PRNG.

Linux использует встроенный /dev/random или /dev/urandom с использованием NativePRNG.

Имея это в виду, я смог изменить способ инициализации объекта SecureRandom

private static final String ALGORITHM = "SHA1PRNG";
private static final String PROVIDER = "SUN";

private SecureRandom getSecureRandom(String seed) throws NoSuchAlgorithmException, NoSuchProviderException {
  SecureRandom sr = SecureRandom.getInstance(ALGORITHM, PROVIDER);
  sr.setSeed(seed.getBytes(UTF8_CHARSET));
  return sr;
}

Из документации getInstance не заполняет объект, поэтому он делает так, как мне нужно.

Возвращенный объект SecureRandom не был заполнен. Чтобы посеять возвращенный объект, вызовите метод setSeed. Если setSeed не вызывается, первый вызов nextBytes заставит объект SecureRandom заполняться сам. Этот самосев не произойдет, если setSeed был ранее называется.

Теперь он вынужден использовать то, что мне нужно, и у меня не должно быть проблем с RHEL 7.

0 голосов
/ 01 мая 2018

Я не нашел ни одной документации, запрещающей поведение, которое вы наблюдаете на RHEL 7.

JavaDoc для java.util.Random явно заявляет

Если два экземпляра Random создаются с одним и тем же начальным числом, и для каждого выполняется одинаковая последовательность вызовов методов, они будут генерировать и возвращать идентичные последовательности чисел

JavaDoc для java.security.SecureRandom не содержит аналогичного утверждения.

Напротив, упоминается (в документации по методу setSeed())

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

...