2013-08-09 50 views
15

Tôi đang sử dụng thư viện c của OpenSSL để tạo ra cặp khóa elip Diffie-Hellman (ECDH), theo mẫu mã đầu tiên here. Nó đã che đậy việc trao đổi thực tế của khóa công khai với dòng này:Làm cách nào để truy cập vào khóa công khai, khóa riêng và các tham số nguyên trong cấu trúc EVP_PKEY của OpenSSL?

peerkey = get_peerkey(pkey); 

Các pkey biến và giá trị trả về đều là kiểu EVP *. pkey chứa khóa công cộng, khóa cá nhân và thông số được tạo trước đó và giá trị trả lại chỉ chứa khóa công khai của đồng nghiệp. Vì vậy, điều này làm tăng ba câu hỏi:

  1. Làm thế nào sẽ get_peerkey() thực sự chỉ trích các khóa công khai từ pkey để gửi đến các đồng đẳng?
  2. Mã sẽ trích xuất khóa cá nhân và thông số từ pKey để lưu trữ chúng để sử dụng sau này sau khi trao đổi khóa như thế nào?
  3. Làm cách nào để get_peerkey() tạo cấu trúc EVP_PKEY mới từ khóa công khai thô của đồng nghiệp?

Tôi đã nhìn thấy các chức năng OpenSSL EVP_PKEY_print_public(), EVP_PKEY_print_private(), và EVP_PKEY_print_params() nhưng đây là để tạo ra con người có thể đọc được. Và tôi đã không tìm thấy bất kỳ tương đương nào để chuyển đổi khóa công khai có thể đọc được thành một cấu trúc EVP_PKEY.

Trả lời

32

Để trả lời câu hỏi của riêng tôi, có một đường dẫn khác cho khóa cá nhân và khóa công cộng.

Để serialize khóa công khai:

  1. Vượt qua EVP_PKEY để EVP_PKEY_get1_EC_KEY() để có được một EC_KEY.
  2. Chuyển EC_KEY sang EC_KEY_get0_public_key() để nhận EC_POINT.
  3. Vượt EC_POINT sang EC_POINT_point2oct() để nhận octet, chỉ là dấu chưa ký *.

Để deserialize khóa công khai:

  1. Vượt qua octet để EC_POINT_oct2point() để có được một EC_POINT.
  2. Vượt EC_POINT sang EC_KEY_set_public_key() để nhận EC_KEY.
  3. Chuyển EC_KEY tới EVP_PKEY_set1_EC_KEY để nhận EVP_KEY.

Để serialize khóa riêng:

  1. Vượt qua EVP_PKEY để EVP_PKEY_get1_EC_KEY() để có được một EC_KEY.
  2. Chuyển EC_KEY sang EC_KEY_get0_private_key() để nhận BIGNUM.
  3. Chuyển BIGNUM sang BN_bn2mpi() để nhận mpi, là định dạng được viết thành char chưa ký *.

Để deserialize khóa riêng:

  1. Vượt qua Bộ KH & ĐT để BN_mpi2bn() để có được một bignum.
  2. Chuyển BIGNUM tới EC_KEY_set_private_key() để nhận EC_KEY.
  3. Chuyển EC_KEY tới EVP_PKEY_set1_EC_KEY để nhận EVP_KEY.

Cũng có thể chuyển đổi BIGNUM thành hex, thập phân hoặc "bin", mặc dù tôi nghĩ rằng mpi sử dụng số byte ít nhất.

+2

Cảm ơn bạn đã cung cấp câu trả lời tiếp theo! – samoz

+0

Deserialize chìa khóa công cộng có thể đã làm việc 4 năm và 5 tháng trước, nhưng nó có vẻ khá phức tạp ngày hôm nay !!! : p EVP_PKEY_get1_EC_KEY được cho là tạo EC_POINT từ octet nhưng nó nhận được EC_POINT * từ đầu vào! Tôi đã cố gắng để làm cho nó bằng EC_POINT_new nhưng sau đó không thể tạo khóa bí mật với việc tạo ra EVP_KEY! – madz