Создать KeyPair с RandomSecure
Можно ли в любом случае генерировать всегда один и тот же закрытый ключ? Я устал инициализировать KeyPairGenerator с объектом RandomSecure, который использует тот же seed
:
private PrivateKey getPrivateKey(String seed) {
try {
SecureRandom sr = new SecureRandom(seed.getBytes());
KeyPairGenerator keyGen = KeyPairGenerator.getInstance("RSA");
keyGen.initialize(1024, sr);
KeyPair keyPair = keyGen.generateKeyPair();
return keyPair.getPrivate();
} catch (NoSuchAlgorithmException e) {
System.out.println("Failed to generate key pair!");
}
return null;
}
Я вызываю вышеуказанную функцию и проверяю, совпадают ли закрытые ключи:
String seed = "xyzabc123";
PrivateKey key1 = getPrivateKey(seed);
PrivateKey key2 = getPrivateKey(seed);
boolean same = key1.equals(key2); // false
Они разные, у меня вопрос, есть ли способ генерировать всегда один и тот же закрытый ключ?
2 ответа
Реализация Java SecureRandom зависит от доступных поставщиков, поэтому она может быть разной в разных ОС или для разных реализаций.
В Linux реализация по умолчанию - NativePRNG, которая игнорирует ваш начальный AFAIK.
Что вы могли бы сделать, это сериализовать вашу безопасную случайную последовательность перед вызовом генерации и десериализовать ее, чтобы сбросить ее для следующего поколения.
Я делал это в прошлом, и помните, что это работает по крайней мере для некоторой реализации Java.
String seed = "xyzabc123";
SecureRandom sr = new SecureRandom(seed.getBytes());
ByteArrayOutputStream bos = new ByteArrayOutputStream();
ObjectOutput out = new ObjectOutputStream(bos);
out.writeObject(sr);
byte[] superseed = bos.toByteArray();
PrivateKey key1 = getPrivateKey(superseed);
PrivateKey key2 = getPrivateKey(superseed);
private PrivateKey getPrivateKey(byte[] superseed) {
ByteArrayInputStream bis = new ByteArrayInputStream(superseed);
ObjectInput in = new ObjectInputStream(bis);
SecureRandom sr = (SecureRandom)in.readObject();
...
Я не думаю, что этот код будет генерировать то же самое private-key
на каждый запрос. Причиной этого является именно этот кусок кода
SecureRandom sr = new SecureRandom(seed.getBytes());
каждый раз, когда вы звоните getPrivateKey(String)
метод. в каждый раз SecureRandom
Класс сгенерирует новое случайное число.
keyGen.initialize(1024, sr); //each time secure random number will be different.
KeyPair keyPair = keyGen.generateKeyPair();
а также keyGen.initialize()
метод инициализируется разными ключами все время, поэтому каждый раз keyGen.generateKeyPair();
метод будет генерировать другой private-key
,
Если вы попытаетесь изменить или передать то же самое SecureRandom
объект в initialize()
Способ, тогда только это может быть достигнуто.