Как объединить закрытый ключ и открытый ключ для общего секрета в Java

Я читаю википедию о криптографии с открытым ключом с открытым ключом (http://en.wikipedia.org/wiki/Public-key_cryptography) и в нем говорится:

В схеме обмена ключами Диффи – Хеллмана каждая сторона генерирует пару открытого / закрытого ключей и распределяет открытый ключ ... После получения подлинной копии открытых ключей друг друга Алиса и Боб могут вычислить общий секрет в автономном режиме. Общий секрет может использоваться, например, как ключ для симметричного шифра.

Мне интересно, как этого добиться на Java? то есть, учитывая произвольный открытый ключ и произвольный частный ключ, как сгенерировать из него общий секрет?

Чтобы было понятнее:

У Алисы есть пара открытого и закрытого ключей key_pair_alice,

У Боба есть пара открытого и закрытого ключей key_pair_bob,

Если я правильно понимаю, должен существовать метод comb_keys (), чтобы:

combine_keys(key_pair_alice.private, key_pair_bob.public) == 
    combine_keys(key_pair_alice.public, key_pair_bob.private) 

У меня вопрос, как реализовать метод comb_keys () в Java.

Спасибо.


person Wudong    schedule 25.01.2012    source источник
comment
Возможный дубликат stackoverflow.com/ questions / 4219197 / how-to-create-a-pki-in-java   -  person nwaltham    schedule 25.01.2012
comment
Спасибо за вопрос и исследование позже - в основном, большинство людей думают в ограничениях RSA, где это классное свойство обычно невозможно, поэтому неверно истолковывают вопрос ...   -  person joshis    schedule 02.05.2014


Ответы (5)


После некоторого исследования я нашел решение, использующее криптографический пакет Java.

 public static void main(String[] args) {
KeyPairGenerator keyGen = KeyPairGenerator.getInstance("DH");
AlgorithmParameterGenerator paramGen = AlgorithmParameterGenerator
    .getInstance("DH");
paramGen.init(1024);

// Generate the parameters
AlgorithmParameters params = paramGen.generateParameters();
DHParameterSpec dhSpec = (DHParameterSpec) params
    .getParameterSpec(DHParameterSpec.class);

keyGen.initialize(dhSpec);

KeyPair alice_key = keyGen.generateKeyPair();
KeyPair bob_key = keyGen.generateKeyPair();

SecretKey secret_alice = combine(alice_key.getPrivate(),
    bob_key.getPublic());

SecretKey secret_bob = combine(bob_key.getPrivate(),
    alice_key.getPublic());

System.out.println(Arrays.toString(secret_alice.getEncoded()));
System.out.println(Arrays.toString(secret_bob.getEncoded()));
}

private static SecretKey combine(PrivateKey private1,
    PublicKey public1)  {
KeyAgreement ka = KeyAgreement.getInstance("DH");
ka.init(private1);
ka.doPhase(public1, true);
SecretKey secretKey = ka.generateSecret("DES");
return secretKey;
}

Системный вывод в конце показывает, что Алиса и Боб теперь разделяют один и тот же секрет.

person Wudong    schedule 25.01.2012
comment
Я тоже пытаюсь сделать то же самое, но я думаю, что этот код может быть не совсем правильным - похоже, что alice_key и bob_key инициализированы одной и той же парой ключей, поэтому оба объединяются с одним и тем же значением. - person Brad Tofel; 08.06.2013

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

person flyx    schedule 25.01.2012
comment
хм, я не уверен в этом. В статье говорится, что общий секрет вычисляется в автономном режиме обеими сторонами. Под офлайн, я полагаю, это означает, что дальнейший обмен между двумя сторонами не требуется? На рисунке ясно видно, что он объединяет оба ключа для генерации общего секрета. - person Wudong; 25.01.2012
comment
См. en.wikipedia.org/wiki/Diffie%E2%80%93Hellman_key_exchange: Расширенная диаграмма показывает, что сторонам необходимо договориться об общей краске. В этом случае ключ final действительно рассчитывается в автономном режиме. Если вы хотите реализовать этот алгоритм, посмотрите пример в статье. Вы можете использовать любой алгоритм, который соответствует схеме для вычисления общих ключей, поэтому не существует единственного способа реализовать это. - person flyx; 25.01.2012
comment
PS: Я также думаю, что упоминание Диффи-Хеллмана немного вводит в заблуждение в статье о криптографии с открытым ключом, потому что на самом деле это немного другая схема, в которой используется только закрытый ключ, а не открытый. Вы можете использовать его с общедоступными и закрытыми ключами, но я не вижу в этом смысла, потому что, когда вы работаете с общедоступными и закрытыми ключами, нет необходимости вычислять общий секрет. - person flyx; 25.01.2012

Открытый и закрытый ключи никогда не бывают произвольными, они генерируются вместе, то есть представляют собой пару ключей. Затем вы можете использовать закрытый ключ для расшифровки сообщений, зашифрованных открытым ключом, или подписывать сообщения закрытым ключом. Идея Диффи-Хеллмана состоит в том, чтобы зашифровать симметричный ключ с помощью открытого ключа коммуникационного партнера, чтобы его можно было безопасно передать. Партнер по коммуникации может расшифровать симметричный ключ своим закрытым ключом. Таким образом, оба партнера по обмену данными имеют общий симметричный ключ, который они могут использовать для симметричного шифрования.

С этим связан пакет java, javax.crypto, но у меня нет опыта с ним. Может быть, вам поможет API.

person joergl    schedule 25.01.2012

Предполагая, что я правильно понимаю, должен быть метод comb_keys ()

Конечно, есть способ. И это хорошо известный метод Диффи-Хеллмана. Существует множество Java-реализаций Диффи-Хеллмана. Например, посмотрите здесь. Ваш метод comb () описан как sharedKey

person Barmaley    schedule 25.01.2012

учитывая произвольный открытый ключ и произвольный закрытый ключ, как сгенерировать из него общий секрет?

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

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

  2. Он отправляет зашифрованный секрет стороне с закрытым ключом.

  3. Сторона с закрытым ключом расшифровывает зашифрованный секрет, и обе стороны разделяют секрет.

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

Мне интересно, как этого добиться на Java?

Существуют существующие реализации на Java. Если вы не можете использовать один из них, вы можете реализовать опубликованный алгоритм с нуля и использовать его для реализации общей секретной процедуры, как указано выше.

Вам, вероятно, нужен лучший источник информации, чем Википедия. На эту тему есть учебники ...

person Stephen C    schedule 25.01.2012