Điểm:1

Xác minh kết quả của (EC-)Diffie-Hellman

lá cờ in

Tôi đã nhận được khóa công khai bằng JSON.

Ví dụ: tôi có 4 khóa: 2 khóa chung và 2 khóa riêng.

công cộng A : co2D0pNxZJIeQ4RZlCRJYBDzNXSLluETdztid0M+HGzN1uGJ4JWZsenjWgRrmkLh3yqHQqzOBMl/wHVH97A6+g==

riêng tư A : TXxii5Ka8LMvuc9arHu63qTmNKxGlgti+wpR3YhBGew=

công khai B : nUblC+OKdl94iBiWk0941wmYBiMt7C90CjOJPI2BPr8K7xGuC1XsR5DtwFCoM3Iew2BjBG+5SqrYwAPTJF7gdA==

riêng tư B : sm6V7+hChvkFSeLNoR+5tItiX8gH5tT47xBkFaV6SDU=

tôi không thể làm một trao đổi ECDH từ một khóa công khai A và một khóa riêng B mà tôi nhận được trong JSON.

Làm thế nào tôi có thể xác minh: (khóa chung A + khóa riêng B) == (khóa chung B + khóa riêng A) ?

Michael Fehr avatar
lá cờ gb
Các khóa trong tệp JSON là các khóa được mã hóa Base64 và thường có thể được nhập bằng thông số kỹ thuật của khóa.Sau đó, tạo bí mật dùng chung bằng cách sử dụng [khóa chung A + khóa riêng B] và [khóa chung B + khóa riêng tư A] và nếu các bí mật bằng nhau thì bạn đã xác minh rằng có 2 cặp khóa đang hoạt động. Vui lòng chỉnh sửa câu hỏi của bạn và thêm một số mã vì Stackoverflow không phải là dịch vụ viết mã miễn phí, cảm ơn.
Maarten Bodewes avatar
lá cờ in
Lưu ý rằng trao đổi ECDH không sử dụng "phép cộng", nó sử dụng phép nhân điểm làm cấu trúc toán học cơ bản.
fgrieu avatar
lá cờ ng
Gợi ý: giải mã Base64, loại trừ nội dung là ASN.1, tạm thời đoán đó là byte thô big-endian, kết luận từ các kích thước mà các khóa chung có thể có X và Y được nối với nhau, sử dụng độ dự phòng cao ở đó để (hy vọng) tìm ra một đường cong chung (có thể là một trong số [những đường này](https://www.secg.org/sec2-v2.pdf#subsection.2.4)) và chọn $a\,B=b\,A$ khi được hỏi. Ngoài ra, hãy kiểm tra xem $a\,G=A$ và $b\,G=B$ (tức là khóa công khai và khóa riêng tư có khớp nhau hay không), điều này sẽ chứng minh $a\,B=b\,A$ mà không cần tính toán thêm. [Tham khảo](https://www.secg.org/sec1-v2.pdf#subsubsection.2.2.1) đó có thể hữu ích (YMMV).
Điểm:6
lá cờ in

Thông thường, kết quả của phép tính Diffie-Hellman (Đường cong Elliptic) được gọi là bí mật chính. Khóa chính này thường được sử dụng làm tài liệu tạo khóa đầu vào (IKM) cho Hàm dẫn xuất khóa (KDF). Sử dụng nhiều khóa KDF có thể được lấy từ bí mật chính. Những gì bạn đang tìm kiếm được gọi là "cấu hình chính".

Có nhiều cách khác nhau để xác nhận khóa đối xứng:

  1. Một trong những khóa này có thể được sử dụng làm đầu vào cho giao thức phản hồi thử thách. Giao thức phản hồi thách thức là một phương pháp đối xứng để xác thực rằng một thực thể có quyền truy cập vào khóa bí mật chính xác.

  2. Một cách khác là sử dụng khóa làm đầu vào cho MAC qua một chuỗi mà cả hai bên đều biết. Bằng cách đó, MAC cho thấy rằng thực thể có quyền truy cập vào khóa chính xác. Chẳng hạn, TLS (1.3) sử dụng MAC trên toàn bộ quá trình bắt tay trong thông báo "Đã hoàn tất" cuối cùng của quá trình bắt tay:

    Đã kết thúc: MAC (Mã xác thực thư) trên toàn bộ bắt tay. Tin nhăn nay cung cấp xác nhận chính, liên kết các danh tính của điểm cuối đối với các khóa được trao đổi và trong chế độ PSK cũng vậy xác thực cái bắt tay. [Mục 4.4.4]

  3. Bạn cũng có thể tưởng tượng rằng một bên có thể ký kết quả bí mật và gửi chữ ký cho bên kia.

  4. Cuối cùng, việc xác nhận rằng các khóa kết quả và do đó bí mật giống hệt nhau cũng có thể được thực hiện hoàn toàn khi thông báo xác thực đầu tiên được gửi từ bên này sang bên kia. Tuy nhiên, điều này thường được tránh, vì nó có nghĩa là bạn không thể phân biệt giữa lỗi truyền dữ liệu và lỗi bắt tay; do đó, nó có thể đóng vai trò địa ngục vui vẻ trong việc thực hiện giao thức.

Ghi chú:

  • Nếu bạn xác nhận một khóa thì tính hợp lệ của khóa bí mật và bất kỳ khóa dẫn xuất nào khác cũng được xác nhận (trừ các lỗi triển khai).
  • Có thể khóa công khai (tĩnh) của DH có thể được tin cậy bằng các phương tiện khác, trong trường hợp đó, bên được xác thực có thể không cần xác minh bổ sung bí mật kết quả; chỉ những bên không được xác thực mới được yêu cầu gửi giá trị phản hồi, MAC hoặc chữ ký.
Điểm:0
lá cờ in

Vì vậy, đây là cách tôi giải quyết vấn đề của mình:

Các khóa của tôi trong chuỗi:

công cộng A : co2D0pNxZJIeQ4RZlCRJYBDzNXSLluETdztid0M+HGzN1uGJ4JWZsenjWgRrmkLh3yqHQqzOBMl/wHVH97A6+g==

riêng tư A : TXxii5Ka8LMvuc9arHu63qTmNKxGlgti+wpR3YhBGew=

công khai B : nUblC+OKdl94iBiWk0941wmYBiMt7C90CjOJPI2BPr8K7xGuC1XsR5DtwFCoM3Iew2BjBG+5SqrYwAPTJF7gdA==

riêng tư B : sm6V7+hChvkFSeLNoR+5tItiX8gH5tT47xBkFaV6SDU=

Các chức năng lấy private key:

public static PrivateKey getPrivateKey(byte[] encodedPrivateKey) {
   BigInteger s = new 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 = new ECPrivateKeySpec(s, ecParameterSpec);
   cố gắng {
       KeyFactory keyFactory = KeyFactory.getInstance("EC");
       trả về keyFactory.generatePrivate(privateKeySpec);
    } bắt (NoSuchAlgorithmException | InvalidKeySpecException e) {
        e.printStackTrace();
        trả về giá trị rỗng;
   }
}

public static PublicKey rawToEncodedECPublicKey(String curveName, byte[] rawBytes) ném 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 mới(BigInteger mới(1,x), BigInteger mới(1,y));
   return kf.generatePublic(ECPublicKeySpec mới(w, ecParameterSpecForCurve(curveName)));
}

tĩnh công khai java.security.spec.ECParameterSpec ecParameterSpecForCurve(String curveName) ném NoSuchAlgorithmException, InvalidParameterSpecException {
   AlgorithmParameters params = AlgorithmParameters.getInstance("EC");
   params.init(ECGenParameterSpec mới(curveName));
   trả về params.getParameterSpec(ECParameterSpec.class);
}

Chúng ta cần tạo 2 cặp khóa thông qua khóa công khai/riêng tư trong chuỗi và kiểm tra xem cả hai có bằng nhau không:

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);

cố gắng {
     PublicKey PublicKeyA = rawToEncodedECPublicKey("secp256r1",cle_publique_a_decode);
     Khóa công khai PublicKeyB = rawToEncodedECPublicKey("secp256r1",cle_publique_b_decode);

     Khóa riêng PrivateKeyA = getPrivateKey(cle_privee_a_decode);
     Khóa riêng PrivateKeyB = getPrivateKey(cle_privee_b_decode);

     // Bí mật #1
     // PrivateKeyA + PublicKeyB = generateSecret
     KeyAgreement keyAgreement = KeyAgreement.getInstance("ECDH");
     keyAgreement.init(PrivateKeyA);
     keyAgreement.doPhase(PublicKeyB, true);
     byte[] generateSecret = keyAgreement.generateSecret();
     Chuỗi base64_generateSecret = Base64.getEncoder().encodeToString(generateSecret);

     // Bí mật #2
     // PrivateKeyB + PublicKeyA = generateSecret2
     KeyAgreement keyAgreement2 = KeyAgreement.getInstance("ECDH");
     keyAgreement.init(PrivateKeyB);
     keyAgreement.doPhase(PublicKeyA, true);
     byte[] generateSecret2 = keyAgreement.generateSecret();
     Chuỗi base64_generateSecret2 = Base64.getEncoder().encodeToString(generateSecret);

     //so sánh 2 bí mật
     // (khóa chung A + khóa riêng B) == (khóa chung B + khóa riêng A)
     if(base64_generateSecret.equals(base64_generateSecret2)){
          // Tốt: Bí mật giống nhau
          // tiếp tục..
     }
     khác{
          // Không tốt : Bí mật là khác nhau
     }
}
nắm lấy{
     ném IllegalArgumentException mới(e.getMessage(), e);
}

Các khóa bằng nhau, tôi có thể bắt đầu mã hóa.

Maarten Bodewes avatar
lá cờ in
Toàn bộ ý tưởng của DH là bạn tạo bí mật ở hai địa điểm. Bạn không thể so sánh trực tiếp các bí mật bằng cách sử dụng `bằng` vì điều đó có nghĩa là bạn có thể sao chép giá trị từ vị trí này sang vị trí khác. Nếu bạn làm được điều đó thì bạn không cần DH.

Đăng câu trả lời

Hầu hết mọi người không hiểu rằng việc đặt nhiều câu hỏi sẽ mở ra cơ hội học hỏi và cải thiện mối quan hệ giữa các cá nhân. Ví dụ, trong các nghiên cứu của Alison, mặc dù mọi người có thể nhớ chính xác có bao nhiêu câu hỏi đã được đặt ra trong các cuộc trò chuyện của họ, nhưng họ không trực giác nhận ra mối liên hệ giữa câu hỏi và sự yêu thích. Qua bốn nghiên cứu, trong đó những người tham gia tự tham gia vào các cuộc trò chuyện hoặc đọc bản ghi lại các cuộc trò chuyện của người khác, mọi người có xu hướng không nhận ra rằng việc đặt câu hỏi sẽ ảnh hưởng—hoặc đã ảnh hưởng—mức độ thân thiện giữa những người đối thoại.