Có thể ký một tập tin bằng khóa ssh không?


36

Tôi sử dụng SSH (chính xác là OpenSSH 5.5p1 trên Linux). Tôi có một chìa khóa, trên đó tôi có một cụm mật khẩu. Tôi sử dụng điều này cho việc đăng nhập thông thường vào máy tính.

Tôi cũng có thể sử dụng nó để ký tập tin?

Theo tôi hiểu, khóa SSH là khóa RSA (hoặc DSA) và trong quá trình đăng nhập SSH, nó được sử dụng để ký các tin nhắn được gửi đến máy chủ. Vì vậy, trong nguyên tắc và trong thực tế, nó có thể được sử dụng để ký kết mọi thứ - thực sự, đó là mục đích duy nhất của nó.

Nhưng theo như tôi có thể thấy, không có cách nào để sử dụng khóa để ký một tệp tùy ý (như bạn làm với PGP, giả sử). Có cách nào để làm việc này không?


Không OpenSSH sử dụng Ed25519 làm giao thức dat ? Có vẻ chỉ là một vấn đề của các công cụ.
Pablo A

Câu trả lời:


24

Có thể không có cách nào để làm điều này với các công cụ OpenSSH.

Nhưng nó có thể được thực hiện khá dễ dàng với các công cụ OpenSSL. Trong thực tế, có ít nhất hai cách để làm điều đó. Trong các ví dụ dưới đây, ~/.ssh/id_rsalà khóa riêng của bạn.

Một cách là sử dụng dgst :

openssl dgst -sign ~/.ssh/id_rsa some-file

Khác là sử dụng pkeyutl :

openssl pkeyutl -sign -inkey ~/.ssh/id_rsa -in some-file

Cả hai đều viết một chữ ký nhị phân cho đầu ra tiêu chuẩn. dgst có một -hextùy chọn sẽ in một văn bản đại diện, với một số chi tiết về hình thức của chữ ký. pkeyutl có một -hexdumptùy chọn ít hữu ích hơn một chút. Cả hai sẽ chấp nhận cả khóa RSA và DSA. Tôi không biết định dạng của đầu ra là gì. Hai lệnh tạo ra các định dạng khác nhau. Tôi có ấn tượng rằng pkeyutl được coi là hiện đại hơn dgst .

Để xác minh những chữ ký đó:

openssl dgst -verify $PUBLIC_KEY_FILE -signature signature-file some-file

và:

openssl pkeyutl -verify -inkey $PUBLIC_KEY_FILE -sigfile signature-file -in some-file

Vấn đề ở đây là $PUBLIC_KEY_FILE. OpenSSL không thể đọc định dạng khóa chung của OpenSSH, vì vậy bạn không thể chỉ sử dụng id_rsa.pub. Bạn có một vài lựa chọn, không có lý tưởng.

Nếu bạn có phiên bản OpenSSH từ 5.6 trở lên, rõ ràng bạn có thể làm điều này:

ssh-keygen -e -f ~/.ssh/id_rsa.pub -m pem

Cái nào sẽ ghi khóa công khai vào đầu ra tiêu chuẩn ở định dạng PEM, mà OpenSSL có thể đọc được.

Nếu bạn có khóa riêng và đó là khóa RSA, thì bạn có thể trích xuất khóa chung từ nó (Tôi giả sử tệp khóa riêng được mã hóa PEM bao gồm một bản sao của khóa chung, vì không thể lấy được khóa chung từ chính khóa riêng) và sử dụng:

openssl rsa -in ~/.ssh/id_rsa -pubout

Tôi không biết nếu có DSA tương đương. Lưu ý rằng phương pháp này đòi hỏi một số sự hợp tác từ chủ sở hữu của khóa riêng, người sẽ phải trích xuất khóa công khai và gửi nó đến người xác minh.

Cuối cùng, bạn có thể sử dụng chương trình Python được viết bởi một chap có tên Lars để chuyển đổi khóa chung từ định dạng OpenSSH sang định dạng OpenSSL.


1
Tôi chỉ muốn lưu ý rằng, không thể lấy được khóa công khai từ khóa riêng mà chính nó là không đúng. Trong thực tế (nghĩa là, trong tất cả các hệ thống mật mã thực sự được sử dụng), khóa công khai dễ dàng được lấy từ khóa riêng trong hầu hết thời gian.
kirelagin

@kirelagin: Tôi không biết điều đó. Bạn có thể cho tôi biết, hoặc liên kết với tôi để biết thêm thông tin về cách có thể được thực hiện?
Tom Anderson

1
Tôi không chắc có bài đọc cụ thể nào về chủ đề này hay không. Hãy nghĩ về nó. Lấy bất kỳ hệ thống mật mã dựa trên nhật ký riêng biệt (ElGamal). Trong trường hợp này, khóa riêng là (kích thước nhóm, trình tạo, nguồn) và khóa chung là (kích thước nhóm, trình tạo, trình tạo ^ nguồn). Vì vậy, đăng nhập là khó khăn, nhưng sức mạnh là không, bạn chỉ cần tính toán nó.
kirelagin

Trong trường hợp RSA, việc đảo ngược này thực sự khó khăn, nhưng ở đây tình hình hơi khác. Khóa công khai là (n, d) và khóa riêng là (n, d ^ (- 1) mod phi (n)). Đảo ngược d cũng sẽ khó khăn nếu bạn không lưu trữ phi (n), nhưng đây là mẹo: hầu hết mọi người đều sử dụng e = 65537 (khi bạn tạo khóa có một tùy chọn để thay đổi mặc định này, nhưng tôi chưa bao giờ thấy bất cứ ai sử dụng nó bởi vì nó không có ý nghĩa thực tế nào), do đó, việc lấy khóa công khai từ khóa riêng là chuyện nhỏ.
kirelagin

Với các đường cong Elliptic, nó thực sự giống như với nhật ký và sức mạnh rời rạc, đảo ngược rất dễ dàng. Điều đó nói rằng, tôi không chắc chắn về các hệ thống mật mã khác, nhưng ba hệ thống đó là những hệ thống được sử dụng trong thực tế.
kirelagin

10

Câu trả lời của @ Tom đã giúp tôi bắt đầu, nhưng không hoạt động.

Các lệnh này sẽ làm việc với:

  • OpenSSL 1.0.1 14 tháng 3 năm 2012
  • OpenSSH_5.9p1

Sử dụng pkeyutl

# openssl pkeyutl -sign -inkey ~/.ssh/id_sample -in $1 > $1.sig
# ssh-keygen -e -f ~/.ssh/id_sample.pub -m PKCS8 > pub
# openssl pkeyutl -verify -pubin -inkey pub -in $1 -sigfile $1.sig
Signature Verified Successfully

Sử dụng dgst

# openssl dgst -sign ~/.ssh/id_sample $1 > $1.sig
# ssh-keygen -e -f ~/.ssh/id_sample.pub -m PKCS8 > pub
# openssl dgst -verify pub -signature $1.sig $1
Verified OK

Phiên bản pkeyutl chỉ có thể ký các tệp có kích thước nhỏ. Trong khi dgst có thể ký các tệp lớn tùy ý, vì nó cần thông báo trước khi ký kết quả.


Đối với tôi cũng có câu trả lời của Stephen.z. Đầu tiên tôi tiếp tục chơi với câu trả lời của Tom một lúc và cuối cùng thấy câu trả lời của Stephen.z hoạt động hoàn hảo với tôi. Cảm ơn Stephen.z!
Grzegorz Wierzowiecki

PS Ở đây tôi đã chia sẻ đoạn của tôi: gist.github.com/gwpl/2c7636f0b200cbfbe82cc9d4f6338585
Grzegorz Wierzowiecki

Bạn đã thử sử dụng pkeyutl để chỉ ký băm của tập tin?
Gaia

-3

Để xác minh những chữ ký - giải pháp dễ dàng hơn:

Cách dễ dàng hơn để đảm bảo một tài liệu đã ký giống nhau, là tạo lại tệp chữ ký số và sau đó sử dụng diff để kiểm tra xem hai tệp chữ ký có giống nhau không.


3
Bạn đang nghĩ về băm , không phải chữ ký . Tương tự, nhưng không giống nhau: hàm băm chỉ xác minh rằng tệp không thay đổi; một chữ ký cũng xác minh từ đâu nó đến.
Piskvor
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.