Puncte:1

Rezultatul verificării (EC-)Diffie-Hellman

drapel in

Am primit o cheie publică prin JSON.

De exemplu, am 4 chei: 2 chei publice și 2 chei private.

public A : co2D0pNxZJIeQ4RZlCRJYBDzNXSLluETdztid0M+HGzN1uGJ4JWZsenjWgRrmkLh3yqHQqzOBMl/wHVH97A6+g==

privat A : TXxii5Ka8LMvuc9arHu63qTmNKxGlgti+wpR3YhBGew=

public B : nUblC+OKdl94iBiWk0941wmYBiMt7C90CjOJPI2BPr8K7xGuC1XsR5DtwFCoM3Iew2BjBG+5SqrYwAPTJF7gdA==

privat B : sm6V7+hChvkFSeLNoR+5tItiX8gH5tT47xBkFaV6SDU=

Nu pot face un schimb ECDH de la a cheia publică A si a cheia privată B pe care îl primesc în JSON.

Cum pot verifica: (cheie publică A + cheie privată B) == (cheie publică B + cheie privată A) ?

Michael Fehr avatar
drapel gb
Cheile din fișierul JSON sunt chei codificate Base64 și, de obicei, pot fi importate cu specificațiile cheii.Apoi generați un secret partajat folosind [cheie publică A + cheie privată B] și [cheie publică B + cheie privată A] și dacă secretele sunt egale, ați verificat că au 2 perechi de chei de lucru. Vă rugăm să vă editați întrebarea și să adăugați ceva cod, deoarece Stackoverflow nu este un serviciu gratuit de scriere a codului, mulțumesc.
Maarten Bodewes avatar
drapel in
Rețineți că schimbul ECDH nu folosește „adăugarea”, ci folosește multiplicarea punctelor ca construcție matematică de bază.
fgrieu avatar
drapel ng
Sugestie: decodificați Base64, excludeți că conținutul este ASN.1, ghiciți provizoriu că este vorba de octeți bruti big-endian, concluzionați din dimensiunile că cheile publice probabil au X și Y concatenate, utilizați redundanța ridicată de acolo pentru (sperăm) să vă dați seama o curbă comună (poate una dintre [acestea](https://www.secg.org/sec2-v2.pdf#subsection.2.4)) și bifați $a\,B=b\,A$ așa cum este cerut. Alternativ, verificați dacă $a\,G=A$ și $b\,G=B$ (adică cheile publice și private se potrivesc), ceea ce ar dovedi $a\,B=b\,A$ fără calcule suplimentare. Această [referință](https://www.secg.org/sec1-v2.pdf#subsubsection.2.2.1) poate ajuta (YMMV).
Puncte:6
drapel in

De obicei, rezultatul calculului Diffie-Hellman (curba eliptică) se numește un secret principal. Această cheie principală este folosită în mod obișnuit ca material de introducere a cheii (IKM) pentru o funcție de derivare a cheii (KDF). Folosirea cheilor multiple KDF poate fi derivată din secretul principal. Ceea ce cauți se numește „conformație cheie”.

Există mai multe moduri de a confirma cheile simetrice:

  1. Una dintre aceste taste poate fi folosită ca intrare într-un protocol de răspuns la provocare. Un protocol de răspuns la provocare este o metodă simetrică pentru a valida faptul că o entitate are acces la cheia secretă corectă.

  2. O altă modalitate este de a folosi cheia ca intrare la un MAC pe un șir cunoscut de ambele părți. În acest fel, MAC arată că entitatea are acces la cheia corectă. De exemplu, TLS (1.3) folosește un MAC pe întreaga strângere de mână în mesajul final „Terminat” al strângerii de mână:

    Terminat: Un MAC (Cod de autentificare a mesajelor) în întregime strângere de mână. Acest mesaj oferă confirmarea cheii, leagă identitatea punctului final la cheile schimbate și, de asemenea, în modul PSK autentifică strângerea de mână. [Secțiunea 4.4.4]

  3. De asemenea, vă puteți imagina că o parte poate semna secretul rezultat și poate trimite semnătura celeilalte părți.

  4. În sfârșit, confirmarea că cheile rezultate și deci secrete sunt identice poate fi efectuată și implicit atunci când primul mesaj autentificat este trimis de la o parte către cealaltă parte. Totuși, acest lucru este în general evitat, deoarece înseamnă că nu puteți face distincția între transmisia de date și erorile de strângere de mână; Prin urmare, poate juca un iad vesel în implementarea protocolului.

Note:

  • Dacă confirmați o cheie, atunci se confirmă și validitatea secretului și a oricărei alte chei derivate (cu excepția erorilor de implementare).
  • Este posibil ca cheia publică (statică) a DH să fie de încredere prin alte mijloace, caz în care verificarea suplimentară a secretului rezultat poate să nu fie necesară pentru partea autentificată; numai părțile neautentificate sunt obligate să trimită o valoare de contestare-răspuns, MAC sau semnătură.
Puncte:0
drapel in

Deci, așa mi-am rezolvat problema:

Cheile mele în șiruri:

public A : co2D0pNxZJIeQ4RZlCRJYBDzNXSLluETdztid0M+HGzN1uGJ4JWZsenjWgRrmkLh3yqHQqzOBMl/wHVH97A6+g==

privat A : TXxii5Ka8LMvuc9arHu63qTmNKxGlgti+wpR3YhBGew=

public B : nUblC+OKdl94iBiWk0941wmYBiMt7C90CjOJPI2BPr8K7xGuC1XsR5DtwFCoM3Iew2BjBG+5SqrYwAPTJF7gdA==

privat B : sm6V7+hChvkFSeLNoR+5tItiX8gH5tT47xBkFaV6SDU=

Funcții pentru a obține cheia privată:

public static PrivateKey getPrivateKey(byte[] encodedPrivateKey) {
   BigInteger s = nou BigInteger(1,codedPrivateKey);
   ECNamedCurveParameterSpec ecCurve = ECNamedCurveTable.getParameterSpec("secp256r1");
   ECParameterSpec ecParameterSpec = ECNamedCurveSpec nou("secp256r1", ecCurve.getCurve(), ecCurve.getG(), ecCurve.getN(), ecCurve.getH(), ecCurve.getSeed());
   ECPrivateKeySpec privateKeySpec = ECPrivateKeySpec nou(e, ecParameterSpec);
   încerca {
       KeyFactory keyFactory = KeyFactory.getInstance("EC");
       return keyFactory.generatePrivate(privateKeySpec);
    } catch (NoSuchAlgorithmException | InvalidKeySpecException e) {
        e.printStackTrace();
        returnează nul;
   }
}

public static PublicKey rawToEncodedECPublicKey(String curveName, byte[] rawBytes) aruncă 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 = nou ECPoint(new BigInteger(1,x), new BigInteger(1,y));
   returnează kf.generatePublic(new ECPublicKeySpec(w, ecParameterSpecForCurve(curveName)));
}

public static java.security.spec.ECParameterSpec ecParameterSpecForCurve(String curveName) aruncă NoSuchAlgorithmException, InvalidParameterSpecException {
   AlgorithmParameters params = AlgorithmParameters.getInstance("EC");
   params.init(new ECGenParameterSpec(curveName));
   return params.getParameterSpec(ECParameterSpec.class);
}

Trebuie să creăm 2 perechi de chei prin chei publice/private în șir și să verificăm dacă ambele sunt egale:

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

încerca {
     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);

     // Secretul #1
     // PrivateKeyA + PublicKeyB = generateSecret
     KeyAgreement keyAgreement = KeyAgreement.getInstance("ECDH");
     keyAgreement.init(PrivateKeyA);
     keyAgreement.doPhase(PublicKeyB, true);
     byte[] generateSecret = keyAgreement.generateSecret();
     String base64_generateSecret = Base64.getEncoder().encodeToString(generateSecret);

     // Secretul #2
     // PrivateKeyB + PublicKeyA = generateSecret2
     KeyAgreement keyAgreement2 = KeyAgreement.getInstance("ECDH");
     keyAgreement.init(PrivateKeyB);
     keyAgreement.doPhase(PublicKeyA, true);
     byte[] generateSecret2 = keyAgreement.generateSecret();
     String base64_generateSecret2 = Base64.getEncoder().encodeToString(generateSecret);

     // compara 2 secrete
     // (cheie publică A + cheie privată B) == (cheie publică B + cheie privată A)
     if(base64_generateSecret.equals(base64_generateSecret2)){
          // Bine: Secretele sunt aceleași
          // continua..
     }
     altfel{
          // Nu este bine: Secretele sunt diferite
     }
}
captură{
     aruncă o nouă excepție IllegalArgumentException(e.getMessage(), e);
}

Cheile sunt egale, pot începe să criptez.

Maarten Bodewes avatar
drapel in
Întreaga idee a DH este că generați secrete în două locații. Nu puteți compara direct secretele folosind „equals” deoarece asta ar însemna că puteți copia valoarea dintr-o locație în alta. Dacă poți face asta, atunci nu ai nevoie de DH.

Postează un răspuns

Majoritatea oamenilor nu înțeleg că a pune multe întrebări deblochează învățarea și îmbunătățește legătura interpersonală. În studiile lui Alison, de exemplu, deși oamenii își puteau aminti cu exactitate câte întrebări au fost puse în conversațiile lor, ei nu au intuit legătura dintre întrebări și apreciere. În patru studii, în care participanții au fost implicați în conversații ei înșiși sau au citit transcrieri ale conversațiilor altora, oamenii au avut tendința să nu realizeze că întrebarea ar influența – sau ar fi influențat – nivelul de prietenie dintre conversatori.