Sử dụng khóa riêng RSA để tạo khóa chung?


394

Tôi không thực sự hiểu điều này:

theo: http://www.madboa.com/geek/openssl/#key-rsa , Bạn có thể tạo khóa chung từ khóa riêng.

openssl genrsa -out mykey.pem 1024
openssl rsa -in mykey.pem -pubout > mykey.pub

Suy nghĩ ban đầu của tôi là chúng được tạo thành một cặp với nhau. Khóa riêng RSA có chứa tổng không? hoặc khóa công khai?


1
Cho mọi người sử dụng rsa và openssl và muốn mã hóa một tệp lớn như 5 Kbyte. xin lưu ý rằng khóa công khai phải có tỷ lệ hoặc lớn hơn với kích thước bạn muốn mã hóa nếu không bạn sẽ nhận được "tệp lớn để được mã hóa." Tôi tóm tắt rằng bạn tạo một khóa riêng khá lớn và nghiêm trọng và từ đó tạo ra các khóa riêng để bạn có nhiều dữ liệu để làm việc. Tôi đã nói với ai tôi biết trong openssl về lỗ hổng, và họ chỉ nên tự lặp đi lặp lại nếu không bạn sẽ mất nhiều thời gian để tìm hiểu lý do tại sao nó phàn nàn về kích thước.
Kent Hansen

10
Vấn đề mà Kent Hansen mô tả là do sử dụng RSA trực tiếp trên dữ liệu văn bản gốc, điều này không bao giờ được thực hiện trong mọi trường hợp vì lý do bảo mật. Thay vào đó, hãy sử dụng sơ đồ mã hóa lai được phân tích tốt, chẳng hạn như RSA-KEM ( tools.ietf.org/html/rfc5990#appcill-A ), với sơ đồ mã hóa đối xứng được xác thực như mã hóa-sau đó-HMAC được áp dụng cho dữ liệu.
Daira Hopwood

Điều này có thể giúp: jason4zhu.blogspot.jp/2014/10/ trên
Đánh giá


Câu trả lời của @ SteffenUllrich trong liên kết này giải thích tại sao: security.stackexchange.com/questions/172274/
Kẻ

Câu trả lời:


577
openssl genrsa -out mykey.pem 1024

sẽ thực sự sản xuất một cặp khóa công khai - riêng tư. Cặp được lưu trữ trong mykey.pemtập tin được tạo .

openssl rsa -in mykey.pem -pubout > mykey.pub

sẽ trích xuất khóa công khai và in ra. Đây là một liên kết đến một trang mô tả điều này tốt hơn.

EDIT: Kiểm tra phần ví dụ ở đây . Để chỉ xuất phần công khai của khóa riêng:

openssl rsa -in key.pem -pubout -out pubkey.pem

Để có được khóa công khai có thể sử dụng cho mục đích SSH, hãy sử dụng ssh-keygen :

ssh-keygen -y -f key.pem > key.pub

50
thật khó hiểu khi mọi người trong các hướng dẫn ở khắp mọi nơi đều nói rằng bằng cách sử dụng lệnh openssl genrsa, bạn sẽ tạo ra KHÓA RIÊNG TƯ, bởi vì họ quên rằng nó cũng đang tạo ra KHÓA CÔNG CỘNG
Jaime Hablutzel

15
@jaime bạn có thể thực sự đổ lỗi cho họ? Các tài liệu chính thức nói hoàn toàn không có gì về một khóa công khai. "MÔ TẢ: Lệnh genrsa tạo khóa riêng RSA." openssl.org/docs/apps/genrsa.html
Despertar

124
@jaime, Đó là vì nó không - genrsa chỉ tạo khóa riêng, khóa chung không được lưu trữ. Tuy nhiên nếu bạn có khóa riêng thì bạn có thể tính (lấy) khóa chung từ nó - đó là điều mà lệnh thứ 2 ở trên thực hiện. Nó tính toán, không trích xuất, khóa công khai.
steveayre

13
@steveayre Theo hiểu biết của tôi thì các khóa RSA chỉ đơn giản là hai số mũ ( edtrong tài liệu chung). Không ai là riêng tư hay công khai về mặt toán học , đó là những nhãn được gán tùy ý khi tạo. Họ có thể dễ dàng được chỉ định ngược lại. Tạo cái này từ cái kia là một vấn đề tương đương. Các .pemđịnh dạng chứa một bó toàn bộ thông tin, bao gồm cả số mũ, và vì vậy cả hai phím, phải không?
lynks

13
@steveayre hầu hết là sai. Các thành phần khóa RSA công khai (n, e) DO được tạo và được nhúng vào tệp khóa RSA riêng được tạo bằng openssl genrsalệnh. Một tệp khóa công khai riêng biệt không được tạo ở cùng một bước. Để trích xuất khóa chung từ tệp khóa riêng thành tệp khóa chung riêng, bạn sử dụng openssl rsa -in private.pem -pubout -out public.pemlệnh của mình . Khi bạn tạo khóa công khai theo cách này, nó sẽ được trích xuất từ ​​tệp khóa riêng, không được tính toán. Xem câu trả lời của tôi dưới đây để biết thêm chi tiết.
golem

273

Những người tìm kiếm khóa công khai SSH ...

Nếu bạn đang tìm cách trích xuất khóa chung để sử dụng với OpenSSH, bạn sẽ cần lấy khóa công khai khác đi một chút

$ ssh-keygen -y -f mykey.pem > mykey.pub

Định dạng khóa công khai này tương thích với OpenSSH. Nối khóa công khai vào remote:~/.ssh/authorized_keysvà bạn sẽ thấy ổn


tài liệu từ SSH-KEYGEN(1)

ssh-keygen -y [-f input_keyfile]  

-y Tùy chọn này sẽ đọc tệp định dạng OpenSSH riêng và in khóa công khai OpenSSH sang thiết bị xuất chuẩn.


3
Công việc này như một cái duyên vậy! Nó tạo ra một định dạng mà Github có! Github không lấy định dạng PEM. Câu trả lời openssl rsa -in key.pem -pubout -out pubkey.pemrõ ràng được đề xuất không được chấp nhận vì rõ ràng đầu ra của đó là khóa công khai định dạng pem. Vì vậy, tôi đã gặp lỗi này: "Khóa không hợp lệ. Nó phải bắt đầu bằng 'ssh-rsa' hoặc 'ssh-dss'. Kiểm tra xem bạn có sao chép một nửa khóa công khai không". Tuy nhiên, ssh-keygen -y [-f input_keyfile] tạo định dạng chính xác mà Github thực hiện.
Devy

71

Trong hầu hết các phần mềm tạo khóa riêng RSA, bao gồm cả openssl, khóa riêng được biểu diễn dưới dạng đối tượng RSAPrivatekey PKCS # 1 hoặc một số biến thể của chúng:

A.1.2 Cú pháp khóa riêng RSA

Khóa riêng RSA phải được thể hiện bằng
RSAPrivateKey loại ASN.1 :

  RSAPrivateKey ::= SEQUENCE {
      version           Version,
      modulus           INTEGER,  -- n
      publicExponent    INTEGER,  -- e
      privateExponent   INTEGER,  -- d
      prime1            INTEGER,  -- p
      prime2            INTEGER,  -- q
      exponent1         INTEGER,  -- d mod (p-1)
      exponent2         INTEGER,  -- d mod (q-1)
      coefficient       INTEGER,  -- (inverse of q) mod p
      otherPrimeInfos   OtherPrimeInfos OPTIONAL
  }

Như bạn có thể thấy, định dạng này có một số trường bao gồm mô đun và số mũ công khai và do đó là một siêu dữ liệu nghiêm ngặt của thông tin trong khóa công khai RSA .


Bạn có nghĩa là đã cung cấp một khóa riêng, nó khả thi về mặt toán học để tạo khóa chung? Không phải sức mạnh của RSA là sự thật rằng tính toán của nó không khả thi để tạo ra một khóa được cung cấp cho khóa kia?
Raam

30
@Raam: Không, điểm mạnh của RSA là không thể tạo khóa riêng từ công chúng. Tạo các hình thức công cộng tư nhân là tầm thường.
Tổng thống James K. Polk

@GregS, tại sao? Một khóa bao gồm một mô-đun và một số mũ. Nếu số mũ khác có thể được tính từ hai số này, RSA sẽ bị bẻ khóa dễ dàng. Vì vậy, khóa riêng OpenSSL chứa nhiều hơn số mũ và mô đun?
Calmarius

1
@Calmarius: Ai nói khóa bao gồm mô đun và số mũ? Đó sẽ là khóa riêng tối thiểu, nhưng thông thường khóa riêng bao gồm các thành phần khác như các thừa số nguyên tố. Đọc câu trả lời để biết chi tiết.
Tổng thống James K. Polk

1
@JamesKPolk Điều đó không hẳn đúng. Nếu số mũ công khai lớn (nghĩa là có cùng thuộc tính với số mũ riêng) thì khóa công khai có thể không thể tái tạo lại. Hầu hết các thư viện sẽ không hỗ trợ điều này nhưng hệ thống mật mã RSA chắc chắn không yêu cầu bạn phải xây dựng lại khóa chung từ khóa riêng.
Maarten Bodewes

34

Câu trả lời của tôi dưới đây hơi dài dòng, nhưng hy vọng nó cung cấp một số chi tiết còn thiếu trong các câu trả lời trước. Tôi sẽ bắt đầu với một số câu liên quan và cuối cùng trả lời câu hỏi ban đầu.

Để mã hóa thứ gì đó bằng thuật toán RSA, bạn cần cặp số mũ và mô đun (công khai) (n, e). Đó là khóa công khai của bạn. Để giải mã một cái gì đó bằng thuật toán RSA, bạn cần cặp số mũ (n, d) mô đun và giải mã (riêng tư). Đó là khóa riêng của bạn.

Để mã hóa thứ gì đó bằng khóa công khai RSA, bạn coi văn bản gốc của mình là một số và nâng nó lên sức mạnh của mô đun điện tử n:

ciphertext = ( plaintext^e ) mod n

Để giải mã một cái gì đó bằng khóa riêng RSA, bạn coi mật mã của mình là một số và nâng nó lên sức mạnh của d modulus n:

plaintext = ( ciphertext^d ) mod n

Để tạo khóa riêng (d, n) bằng openssl, bạn có thể sử dụng lệnh sau:

openssl genrsa -out private.pem 1024

Để tạo khóa công khai (e, n) từ khóa riêng bằng openssl, bạn có thể sử dụng lệnh sau:

openssl rsa -in private.pem -out public.pem -pubout

Để phân tích nội dung của khóa RSA private.pem được tạo bởi lệnh openssl ở trên, hãy chạy phần sau (đầu ra được cắt thành nhãn ở đây):

openssl rsa -in private.pem -text -noout | less

modulus         - n
privateExponent - d
publicExponent  - e
prime1          - p
prime2          - q
exponent1       - d mod (p-1)
exponent2       - d mod (q-1)
coefficient     - (q^-1) mod p

Không nên khóa riêng chỉ bao gồm (n, d) cặp? Tại sao có 6 thành phần phụ? Nó chứa e (số mũ công khai) để khóa RSA công khai có thể được tạo / trích xuất / lấy từ khóa RSA private.pem private. 5 thành phần còn lại có mặt để tăng tốc quá trình giải mã. Hóa ra, bằng cách tính toán trước và lưu trữ 5 giá trị đó, có thể tăng tốc độ giải mã RSA theo hệ số 4. Giải mã sẽ hoạt động mà không cần 5 thành phần đó, nhưng có thể được thực hiện nhanh hơn nếu bạn có sẵn chúng. Thuật toán tăng tốc dựa trên Định lý còn lại của Trung Quốc .

Có, khóa riêng private.pem RSA thực sự chứa tất cả 8 giá trị đó; không ai trong số họ được tạo ra khi bạn chạy lệnh trước đó. Hãy thử chạy các lệnh sau và so sánh đầu ra:

# Convert the key from PEM to DER (binary) format
openssl rsa -in private.pem -outform der -out private.der

# Print private.der private key contents as binary stream
xxd -p private.der

# Now compare the output of the above command with output 
# of the earlier openssl command that outputs private key
# components. If you stare at both outputs long enough
# you should be able to confirm that all components are
# indeed lurking somewhere in the binary stream
openssl rsa -in private.pem -text -noout | less

Cấu trúc này của khóa riêng RSA được PKCS # 1 v1.5 khuyên dùng làm đại diện thay thế ( thứ hai ). Tiêu chuẩn PKCS # 1 v2.0 không bao gồm số mũ e và d từ đại diện thay thế hoàn toàn. PKCS # 1 v2.1v2.2 đề xuất các thay đổi tiếp theo đối với biểu diễn thay thế, bằng cách tùy chọn bao gồm nhiều thành phần liên quan đến CRT hơn.

Để xem nội dung của khóa RSA công khai.pem chạy như sau (đầu ra bị cắt thành nhãn ở đây):

openssl rsa -in public.pem -text -pubin -noout

Modulus             - n
Exponent (public)   - e

Không có bất ngờ ở đây. Đó chỉ là cặp (n, e), như đã hứa.

Bây giờ cuối cùng đã trả lời câu hỏi ban đầu: Như đã trình bày ở trên khóa RSA riêng được tạo bằng openssl chứa các thành phần của cả khóa chung và khóa riêng và một số khóa khác. Khi bạn tạo / trích xuất / lấy khóa công khai từ khóa riêng, openssl sao chép hai trong số các thành phần đó (e, n) vào một tệp riêng trở thành khóa chung của bạn.


bạn đã viết "Để tạo khóa công khai (d, n) từ khóa riêng ...". Không phải là "(e, n)" sao? Cảm ơn bạn đã trả lời tuyệt vời, mặc dù!
elactic

Bạn đang so sánh (bên ngoài) 'cú pháp' trong v1.5 với ngữ nghĩa trong các phiên bản sau; kiểm tra 2.0 # 11.1.2 và 2.1 và 2.2 # A.1.2 và bạn sẽ thấy n, e, d vẫn hiện diện. (Như câu trả lời của James Polk đã được ghi nhận.)
dave_thndry_085

1
giải thích tuyệt vời. Cảm ơn
Francisco Albert

1
Có vẻ như số mũ công khai eluôn là 65537 0x010001. Đây có lẽ là một định nghĩa cho việc chọn số mũ công khai và đây có lẽ là lý do tại sao trong trang nam và hầu hết mọi nơi genrsađược giải thích là to generate the private key. Công chúng là một điều hiển nhiên.
gội đầu

Tôi có thể tính toán ra (n, e) chỉ từ (n, d)?
Flyq

21

Khóa công khai không được lưu trữ trong tệp PEM như một số người nghĩ. Cấu trúc DER sau đây có trong Tệp khóa riêng:

openssl rsa -text -in mykey.pem

RSAPrivateKey ::= SEQUENCE {
  version           Version,
  modulus           INTEGER,  -- n
  publicExponent    INTEGER,  -- e
  privateExponent   INTEGER,  -- d
  prime1            INTEGER,  -- p
  prime2            INTEGER,  -- q
  exponent1         INTEGER,  -- d mod (p-1)
  exponent2         INTEGER,  -- d mod (q-1)
  coefficient       INTEGER,  -- (inverse of q) mod p
  otherPrimeInfos   OtherPrimeInfos OPTIONAL
}

Vì vậy, có đủ dữ liệu để tính toán Public Key (mô đun và số mũ công khai), đó là những gì openssl rsa -in mykey.pem -puboutkhông


Tôi thấy khóa công khai không được lưu trữ ở đó, mặc dù có thể lấy được là khóa riêng, nhưng tôi cũng không thấy khóa riêng được lưu ở đó?! nhưng nếu tôi gửi tập tin pem tôi thấy nó nói khóa riêng và một số ascii.
barlop

2
Khóa riêng cũng được tạo ra, hãy nhìn vào trường privateExponent. Bạn có thể thấy các trường bằng cách sử dụng openssl rsa -text -in mykey.pem
Uxio

2
Khóa công khai thực sự được lưu trữ trong pem, vì pem cũng bao gồm e và d, đó là khóa chung. Không giống như các thuật toán nhật ký rời rạc, khóa công khai rsa không thể được tính từ chỉ khóa riêng (d, n). Nó chỉ ở đó bởi vì thông số rsa chỉ ra để lưu trữ nó với khóa riêng và thông tin khác.
Michael Chourdakis

1
Đúng, câu trả lời này là trong tất cả các mục đích và mục đích SAI . Cả số mũ công khai và mô đun đều nằm trong đó, vì vậy khóa công khai chắc chắn có mặt. Không cần số mũ công khai trong đó ngoài việc dễ dàng lấy khóa công khai cho nó mà không cần bất kỳ tính toán nào .
Maarten Bodewes

1
@MaartenBodewes: Câu trả lời là đúng. Những gì được trích dẫn được lấy từ RFC có liên quan như các giá trị được lưu trữ cho khóa RIÊNG TƯ. Hai trong số các giá trị cũng / chỉ được sử dụng cho mã hóa khóa chung không thay đổi rằng đây là dữ liệu khóa riêng. Tôi đã học được tất cả những thứ này trong hai ngày qua, không phải bằng cách đặt câu hỏi mà bằng cách tìm kiếm và đọc các tiêu chuẩn có liên quan. Bây giờ tôi hiểu tất cả về ASN.1, DER, PEM và RSA (có lẽ không phải TẤT CẢ về RSA).
AlastairG

8

Ở đây trong mã này trước tiên chúng tôi đang tạo khóa RSA là khóa riêng tư nhưng nó cũng có cặp khóa chung của nó để có được khóa công khai thực tế của bạn, chúng tôi chỉ cần làm điều này

openssl rsa -in mykey.pem -pubout > mykey.pub

hy vọng bạn có được nó để biết thêm thông tin kiểm tra này


6

Đầu tiên là một bản tóm tắt nhanh về việc tạo khóa RSA.

  1. Chọn ngẫu nhiên hai số nguyên tố có thể ngẫu nhiên có kích thước phù hợp (p và q).
  2. Nhân hai số nguyên tố với nhau để tạo ra mô đun (n).
  3. Chọn một số mũ công khai (e).
  4. Làm một số phép toán với các số nguyên tố và số mũ công khai để tạo ra số mũ riêng (d).

Khóa công khai bao gồm mô đun và số mũ công khai.

Một khóa riêng tối thiểu sẽ bao gồm mô đun và số mũ riêng. Không có cách chắc chắn khả thi về mặt tính toán nào để đi từ một mô đun đã biết và số mũ riêng đến số mũ công khai tương ứng.

Tuy nhiên:

  1. Các định dạng khóa riêng thực tế gần như luôn lưu trữ nhiều hơn n và d.
  2. e thường không được chọn ngẫu nhiên, một trong số ít các giá trị nổi tiếng được sử dụng. Nếu e là một trong những giá trị nổi tiếng và bạn biết d thì sẽ dễ dàng tìm ra e bằng cách dùng thử và lỗi.

Vì vậy, trong hầu hết các triển khai RSA thực tế, bạn có thể lấy khóa chung từ khóa riêng. Có thể xây dựng một hệ thống mật mã dựa trên RSA, nơi điều này là không thể, nhưng nó không phải là điều được thực hiện.


1
Use the following commands:

1. openssl req -x509 -nodes -days 365 -sha256 -newkey rsa:2048 -keyout mycert.pem -out mycert.pem

Loading 'screen' into random state - done
Generating a 2048 bit RSA private key
.............+++
..................................................................................................................................................................+++
writing new private key to 'mycert.pem'
-----
You are about to be asked to enter information that will be incorporated
into your certificate request.
What you are about to enter is what is called a Distinguished Name or a DN.
There are quite a few fields but you can leave some blank
For some fields there will be a default value,
If you enter '.', the field will be left blank.

2. If you check there will be a file created by the name : mycert.pem

3. openssl rsa -in mycert.pem -pubout > mykey.txt
writing RSA key

4. If you check the same file location a new public key : mykey.txt will be created.

1
Điều này thật ngốc nghếch; không cần phải nỗ lực nhiều hơn để tạo ra một chứng chỉ vô dụng khi tất cả những gì bạn muốn đó là một sự tuyệt vọng. Đối với một số Q khác mà bạn muốn có chứng chỉ thì đây có thể là một câu trả lời.
dave_thndry_085
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.