Рейтинг:1

Проверка результата (EC-) Диффи-Хеллмана

флаг in

Я получил открытый ключ в формате JSON.

Например, у меня есть 4 ключа: 2 открытых ключа и 2 закрытых ключа.

общедоступный A: co2D0pNxZJIeQ4RZlCRJYBDzNXSLluETdztid0M+HGzN1uGJ4JWZsenjWgRrmkLh3yqHQqzOBMl/wHVH97A6+g==

частный A: TXxii5Ka8LMvuc9arHu63qTmNKxGlgti+wpR3YhBGew=

общедоступный B: nUblC+OKdl94iBiWk0941wmYBiMt7C90CjOJPI2BPr8K7xGuC1XsR5DtwFCoM3Iew2BjBG+5SqrYwAPTJF7gdA==

частный B : sm6V7+hChvkFSeLNoR+5tItiX8gH5tT47xBkFaV6SDU=

я не могу сделать обмен ECDH из открытый ключ А и закрытый ключ Б который я получаю в JSON.

Как я могу проверить: (открытый ключ A + закрытый ключ B) == (открытый ключ B + закрытый ключ A) ?

Michael Fehr avatar
флаг gb
Ключи в файле JSON представляют собой ключи в кодировке Base64 и обычно могут быть импортированы со спецификацией ключа.Затем сгенерируйте общий секрет, используя [открытый ключ A + закрытый ключ B] и [открытый ключ B + закрытый ключ A], и если секреты равны, вы подтвердили, что у вас есть 2 пары рабочих ключей. Пожалуйста, отредактируйте свой вопрос и добавьте немного кода, поскольку Stackoverflow не является бесплатной службой написания кода, спасибо.
Maarten Bodewes avatar
флаг in
Обратите внимание, что обмен ECDH не использует «сложение», он использует умножение точек в качестве базовой математической конструкции.
fgrieu avatar
флаг ng
Подсказка: декодируйте Base64, исключите, что содержимое является ASN.1, предварительно предположите, что это необработанные байты с обратным порядком байтов, сделайте вывод из размеров, что открытые ключи, вероятно, имеют конкатенацию X и Y, используйте высокую избыточность там, чтобы (надеюсь) выяснить общая кривая (возможно, одна из [этих](https://www.secg.org/sec2-v2.pdf#subsection.2.4)), и проверьте $a\,B=b\,A$, как было задано. В качестве альтернативы проверьте, совпадают ли $a\,G=A$ и $b\,G=B$ (то есть совпадают открытый и закрытый ключи), что докажет, что $a\,B=b\,A$ без дальнейших вычислений. Эта [ссылка] (https://www.secg.org/sec1-v2.pdf#subsubsection.2.2.1) может помочь (YMMV).
Рейтинг:6
флаг in

Обычно результат расчета Диффи-Хеллмана (эллиптическая кривая) называется главным секретом. Этот мастер-ключ обычно используется в качестве входного ключевого материала (IKM) для функции создания ключей (KDF). Используя KDF, можно получить несколько ключей из главного секрета. То, что вы ищете, называется "ключевой конформацией".

Существуют различные способы подтверждения симметричных ключей:

  1. Один из этих ключей можно использовать в качестве входных данных для протокола ответа на запрос. Протокол запроса-ответа — это симметричный метод проверки того, что объект имеет доступ к правильному секретному ключу.

  2. Другой способ — использовать ключ в качестве входных данных для MAC по строке, известной обеим сторонам. Таким образом, MAC показывает, что объект имеет доступ к правильному ключу. Например, TLS (1.3) использует MAC для всего рукопожатия в последнем сообщении «Завершено» рукопожатия:

    Законченный: MAC (код аутентификации сообщения) по всему рукопожатие. Это сообщение предоставляет подтверждение ключа, связывает удостоверение конечной точки по обменным ключам, а также в режиме PSK подтверждает подлинность рукопожатия. [Раздел 4.4.4]

  3. Вы также можете представить, что одна сторона может подписать полученный секрет и отправить подпись другой стороне.

  4. Наконец, подтверждение того, что результирующие ключи и, следовательно, секрет идентичны, также может быть выполнено неявно, когда первое аутентифицированное сообщение отправляется от одной стороны к другой стороне. Однако этого обычно избегают, поскольку это означает, что вы не можете отличить ошибки передачи данных от ошибок установления связи; поэтому он может разыграть веселый ад в реализации протокола.

Примечания:

  • Если вы подтвердите один ключ, то также будет подтверждена действительность секрета и любого другого производного ключа (за исключением ошибок реализации).
  • Может случиться так, что (статическому) открытому ключу DH можно доверять другими способами, и в этом случае для аутентифицированной стороны может не потребоваться дополнительная проверка полученного секрета; только стороны, не прошедшие проверку подлинности, должны отправить запрос-ответ, MAC или значение подписи.
Рейтинг:0
флаг in

Итак, как я решил свою проблему:

Мои ключи в строках:

общедоступный A: co2D0pNxZJIeQ4RZlCRJYBDzNXSLluETdztid0M+HGzN1uGJ4JWZsenjWgRrmkLh3yqHQqzOBMl/wHVH97A6+g==

частный A: TXxii5Ka8LMvuc9arHu63qTmNKxGlgti+wpR3YhBGew=

общедоступный B: nUblC+OKdl94iBiWk0941wmYBiMt7C90CjOJPI2BPr8K7xGuC1XsR5DtwFCoM3Iew2BjBG+5SqrYwAPTJF7gdA==

частный B : sm6V7+hChvkFSeLNoR+5tItiX8gH5tT47xBkFaV6SDU=

Функции для получения закрытого ключа:

открытый статический PrivateKey getPrivateKey (byte [] encodedPrivateKey) {
   BigInteger s = новый BigInteger(1,encodedPrivateKey);
   ECNamedCurveParameterSpec ecCurve = ECNamedCurveTable.getParameterSpec("secp256r1");
   ECParameterSpec ecParameterSpec = new ECNamedCurveSpec("secp256r1", ecCurve.getCurve(), ecCurve.getG(), ecCurve.getN(), ecCurve.getH(), ecCurve.getSeed());
   ECPrivateKeySpec privateKeySpec = новый ECPrivateKeySpec(s, ecParameterSpec);
   пытаться {
       KeyFactory keyFactory = KeyFactory.getInstance("EC");
       вернуть keyFactory.generatePrivate(privateKeySpec);
    } поймать (NoSuchAlgorithmException | InvalidKeySpecException e) {
        e.printStackTrace();
        вернуть ноль;
   }
}

public static PublicKey rawToEncodedECPublicKey(String curveName, byte[] rawBytes) выдает NoSuchAlgorithmException, InvalidKeySpecException, InvalidParameterSpecException {
   KeyFactory kf = KeyFactory.getInstance("EC");
   byte[] x = Arrays.copyOfRange(rawBytes, 0, rawBytes.length/2);
   byte[] y = Arrays.copyOfRange(rawBytes, rawBytes.length/2, rawBytes.length);
   ECPoint w = новый ECPoint (новый BigInteger (1, x), новый BigInteger (1, y));
   return kf.generatePublic(новый ECPublicKeySpec(w, ecParameterSpecForCurve(curveName)));
}

public static java.security.spec.ECParameterSpec ecParameterSpecForCurve (String curveName) выдает NoSuchAlgorithmException, InvalidParameterSpecException {
   Параметры алгоритма params = Параметры алгоритма.getInstance("EC");
   params.init (новый ECGenParameterSpec (curveName));
   вернуть params.getParameterSpec (ECParameterSpec.class);
}

Нам нужно создать 2 пары ключей через ключи public/private в строке и проверить, равны ли они:

byte [] cle_publique_a_decode = Base64.getDecoder().decode(cle_publique_a);
byte [] cle_privee_a_decode = Base64.getDecoder().decode(cle_privee_a);
byte [] cle_publique_b_decode = Base64.getDecoder().decode(cle_publique_b);
byte [] cle_privee_b_decode = Base64.getDecoder().decode(cle_privee_b);

пытаться {
     PublicKey PublicKeyA = rawToEncodedECPublicKey("secp256r1",cle_publique_a_decode);
     PublicKey PublicKeyB = rawToEncodedECPublicKey("secp256r1",cle_publique_b_decode);

     PrivateKey PrivateKeyA = getPrivateKey(cle_privee_a_decode);
     PrivateKey PrivateKeyB = getPrivateKey(cle_privee_b_decode);

     // Секрет №1
     // PrivateKeyA + PublicKeyB = generateSecret
     KeyAgreement keyAgreement = KeyAgreement.getInstance("ECDH");
     keyAgreement.init(PrivateKeyA);
     keyAgreement.doPhase(PublicKeyB, true);
     byte[] generateSecret = keyAgreement.generateSecret();
     Строка base64_generateSecret = Base64.getEncoder().encodeToString(generateSecret);

     // Секрет №2
     // PrivateKeyB + PublicKeyA = generateSecret2
     KeyAgreement keyAgreement2 = KeyAgreement.getInstance("ECDH");
     keyAgreement.init(PrivateKeyB);
     keyAgreement.doPhase(PublicKeyA, true);
     byte[] generateSecret2 = keyAgreement.generateSecret();
     Строка base64_generateSecret2 = Base64.getEncoder().encodeToString(generateSecret);

     // сравним 2 секрета
     // (открытый ключ A + закрытый ключ B) == (открытый ключ B + закрытый ключ A)
     если (base64_generateSecret.equals (base64_generateSecret2)) {
          // Хорошо: секреты те же
          // Продолжить..
     }
     еще{
          // Плохо: секреты разные
     }
}
ловить{
     бросить новое исключение IllegalArgumentException (e.getMessage (), e);
}

Ключи равны, могу приступить к шифрованию.

Maarten Bodewes avatar
флаг in
Вся идея DH заключается в том, что вы генерируете секреты в двух местах. Вы не можете напрямую сравнивать секреты, используя `equals`, поскольку это означало бы, что вы можете копировать значение из одного места в другое. Если вы можете это сделать, то вам не нужен DH.

Ответить или комментировать

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