Может ли Java версии 1.8 генерировать то же значение SecureRandom, что и Java версии 1.6? - PullRequest
0 голосов
/ 07 мая 2018

Я столкнулся с проблемой в системе аутентификации системы. Наши серверы используют версию 1.6, в то время как клиенты используют версию 1.8, в процессе аутентификации мы генерируем ключ по "SHA1PRNG" с SecureRandom, в то время как следующий код: т.е.:

KeyGenerator keygen = KeyGenerator.getInstance("Blowfish"); 
SecureRandom foo = SecureRandom.getInstance("SHA1PRNG");
foo.setSeed("baa".getBytes());
keygen.init(foo);

Проблема в том, что мы обнаружили, что ключ, сгенерированный на клиентах, отличается от ключа на сервере. Мы устали распечатывать все шаги и обнаружили, что проблема вызвана SecureRandom, т. Е. После foo.setSeed("baa".getBytes());, если мы вызываем foo.nextBytes(), это даст разные значения.

Поэтому нам хотелось бы знать, есть ли способ заставить обе стороны генерировать одинаковое значение? (Учитывая, что версия Java как на клиенте, так и на сервере не может быть изменена.) Или какой-либо независимый от платформы метод SecureRandom в Java?

Справочная информация: SERVER и CLIENT работают в Unix. У меня есть рабочий стол под управлением Java 1.8, и я проверил следующее:

  1. Рабочий стол Java 1.8 может шифровать и дешифровать ключ, сгенерированный в CLIENT (Java 1.8)

  2. CLIENT (Java 1.8) не может зашифровать или расшифровать ключ, сгенерированный в SERVER (Java 1.6), и наоборот.

  3. КЛИЕНТ установил Java 1.6 (только для тестирования), не может зашифровать или расшифровать ключ, сгенерированный в SERVER (Java 1.6). Мы предполагаем, что это потому, что /dev/random или /dev/urandom были перезаписаны в версию Java 1.8. Поэтому даже версия Java одинакова, у них разное поведение.

Ответы [ 2 ]

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

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

Вы не пишете то, что используете в качестве ввода для отклонения ключа, но если это пароль, вы можете использовать спецификацию ключа PBE (шифрование на основе пароля) - что-то вроде этого:

SecretKeyFactory factory = SecretKeyFactory.getInstance("PBKDF2WithHmacSHA256");
KeySpec spec = new PBEKeySpec(password, salt, 65536, 256);
SecretKey tmp = factory.generateSecret(spec);
SecretKey secret = new SecretKeySpec(tmp.getEncoded(), "Blowfish");
0 голосов
/ 07 мая 2018

С документация для SecureRandom:

Кроме того, SecureRandom должен выдавать недетерминированный вывод. Поэтому любой семенной материал, переданный объекту SecureRandom, должен быть непредсказуемо, и все SecureRandom выходные последовательности должны быть криптографически стойкий, как описано в RFC 1750: случайность Рекомендации по безопасности .

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

Чтобы создать предсказуемую последовательность случайности, используйте Random:

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

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

Экземпляр Random должен быть разделен между вызовами подпрограммы, в противном случае каждый раз будет генерироваться один и тот же номер:

public static void main(final String[] args) {
    IntStream.range(1, 10)
            .map(i -> new Random(42).nextInt())
            .forEach(System.out::println);
}

Выход:

-1170105035
-1170105035
-1170105035
-1170105035
-1170105035
-1170105035
-1170105035
-1170105035
-1170105035

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

...