เป็นไปได้ไหมที่จะเซ็นชื่อไฟล์โดยใช้คีย์ ssh?


36

ฉันใช้ SSH (OpenSSH 5.5p1 บน Linux เพื่อความแม่นยำ) ฉันมีกุญแจซึ่งฉันมีข้อความรหัสผ่าน ฉันใช้สิ่งนี้ในการลงชื่อเข้าใช้คอมพิวเตอร์ตามปกติ

ฉันสามารถใช้มันเพื่อลงชื่อไฟล์ได้หรือไม่

ตามที่ฉันเข้าใจคีย์ SSH คือคีย์ RSA (หรือ DSA) และระหว่างกระบวนการล็อกอิน SSH จะใช้เพื่อลงชื่อข้อความที่ส่งไปยังเซิร์ฟเวอร์ ดังนั้นในหลักการและในทางปฏิบัติมันสามารถใช้เพื่อลงนามในสิ่งต่าง ๆ - นั่นคือจุดประสงค์เดียวของมัน

แต่เท่าที่ฉันเห็นไม่มีวิธีใช้คีย์เพื่อลงชื่อไฟล์โดยพลการ (เช่นเดียวกับที่คุณทำกับ PGP) มีวิธีการทำเช่นนี้?


OpenSSH ไม่ใช้Ed25519เป็นโปรโตคอลดาต้าหรือไม่ ดูเหมือนจะเป็นแค่เครื่องมือ
ปาโบล

คำตอบ:


24

อาจไม่มีวิธีในการทำเช่นนี้กับเครื่องมือ OpenSSH เพียงอย่างเดียว

แต่สามารถทำได้ค่อนข้างง่ายด้วยเครื่องมือ OpenSSL ในความเป็นจริงมีอย่างน้อยสองวิธีที่จะทำ ในตัวอย่างด้านล่าง~/.ssh/id_rsaเป็นรหัสส่วนตัวของคุณ

วิธีหนึ่งคือการใช้dgst :

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

อื่น ๆ ใช้pkeyutl :

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

ทั้งสองนี้เขียนลายเซ็นไบนารีไปยังเอาต์พุตมาตรฐาน dgstจะใช้-hexตัวเลือกที่จะพิมพ์การเป็นตัวแทนข้อความโดยมีรายละเอียดบางอย่างเกี่ยวกับรูปแบบของลายเซ็น pkeyutlใช้-hexdumpตัวเลือกซึ่งมีประโยชน์น้อยกว่าเล็กน้อย ทั้งสองจะยอมรับทั้งคีย์ RSA และ DSA ฉันไม่รู้ว่าฟอร์แมตของเอาต์พุตคืออะไร ทั้งสองคำสั่งสร้างรูปแบบที่แตกต่างกัน ฉันได้รับความประทับใจที่pkeyutlถือว่าทันสมัยมากขึ้นกว่าdgst

ในการตรวจสอบลายเซ็นเหล่านั้น:

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

และ:

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

$PUBLIC_KEY_FILEนี่คือปัญหา OpenSSL ไม่สามารถอ่านรูปแบบที่สำคัญ OpenSSH id_rsa.pubของประชาชนเพื่อให้คุณไม่สามารถเพียงแค่การใช้งาน คุณมีตัวเลือกน้อยไม่เหมาะ

หากคุณมี OpenSSH เวอร์ชัน 5.6 หรือใหม่กว่าคุณสามารถทำสิ่งนี้ได้อย่างชัดเจน:

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

ซึ่งจะเขียนพับลิกคีย์ไปยังเอาต์พุตมาตรฐานในรูปแบบ PEM ซึ่ง OpenSSL สามารถอ่านได้

หากคุณมีคีย์ส่วนตัวและเป็นคีย์ RSA คุณสามารถแยกรหัสสาธารณะได้ (ฉันถือว่าไฟล์คีย์ส่วนตัวที่เข้ารหัส PEM มีสำเนาของคีย์สาธารณะเนื่องจากไม่สามารถรับคีย์สาธารณะได้ จากไพรเวตคีย์เอง) และใช้สิ่งนั้น:

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

ฉันไม่รู้ว่ามี DSA ที่เทียบเท่าหรือไม่ โปรดทราบว่าวิธีการนี้ต้องใช้ความร่วมมือจากเจ้าของรหัสส่วนตัวซึ่งจะต้องแยกรหัสสาธารณะและส่งไปยังตัวตรวจสอบที่ต้องการ

สุดท้ายคุณสามารถใช้โปรแกรม Python ที่เขียนโดย chap ชื่อ Larsเพื่อแปลงพับลิกคีย์จาก OpenSSH เป็นรูปแบบ OpenSSL


1
ฉันแค่ต้องการที่จะทราบว่า "มันเป็นไปไม่ได้ที่จะได้รับกุญแจสาธารณะจากกุญแจส่วนตัวของตัวเอง" ไม่เป็นความจริง ในทางปฏิบัติ (นั่นคือใน cryptosystem ทั้งหมดที่ใช้จริง) พับลิกคีย์นั้นได้มาจากคีย์ส่วนตัวโดยส่วนใหญ่แล้ว
kirelagin

@kirelagin: ฉันไม่รู้ คุณสามารถบอกฉันหรือเชื่อมโยงฉันเพื่อข้อมูลเพิ่มเติมเกี่ยวกับวิธีการที่สามารถทำได้?
Tom Anderson

1
ฉันไม่แน่ใจว่ามีการอ่านเฉพาะในหัวข้อนี้หรือไม่ลองคิดดูสิ ใช้ระบบเข้ารหัสลับที่ไม่ต่อเนื่องใด ๆ (ElGamal) ในกรณีนี้คีย์ส่วนตัวคือ (ขนาดกลุ่มเครื่องกำเนิดไฟฟ้า) และกุญแจสาธารณะคือ (ขนาดกลุ่มเครื่องกำเนิดไฟฟ้าเครื่องกำเนิดไฟฟ้า ^ พลัง) ดังนั้นบันทึกจึงเป็นเรื่องยาก แต่พลังงานไม่ได้คุณแค่คำนวณ
kirelagin

ในกรณีของ RSA การผกผันนี้ยากจริง ๆ แต่ที่นี่สถานการณ์แตกต่างกันเล็กน้อย กุญแจสาธารณะคือ (n, d) และกุญแจส่วนตัวคือ (n, d ^ (- 1) mod phi (n)) Inverting d อาจเป็นเรื่องยากหากคุณไม่ได้เก็บ phi (n) แต่นี่คือเคล็ดลับ: เกือบทุกคนใช้ e = 65537 (เมื่อคุณสร้างรหัสมีตัวเลือกในการเปลี่ยนค่าเริ่มต้นนี้ แต่ฉันไม่เคยเห็น ใครก็ตามที่ใช้มันเพราะมันไม่ได้ใช้ประโยชน์ได้จริง) ดังนั้นการได้รับรหัสสาธารณะจากรหัสส่วนตัวนั้นไม่สำคัญ
kirelagin

ด้วยเส้นโค้งรูปไข่จริงๆแล้วมันเหมือนกับการล็อกและพลังงานแบบแยกกันการกลับด้านเป็นเรื่องง่าย ที่กล่าวว่าฉันไม่แน่ใจเกี่ยวกับ cryptosystems อื่น ๆ แต่ทั้งสามเป็นสิ่งที่ใช้ในทางปฏิบัติ
kirelagin

10

@ คำตอบของทอมช่วยให้ฉันเริ่มต้นได้ แต่ไม่ได้ผลนอกกรอบ

คำสั่งเหล่านี้จะทำงานกับ:

  • OpenSSL 1.0.1 14 มีนาคม 2012
  • OpenSSH_5.9p1

ใช้ 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

ใช้ 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

รุ่น pkeyutl สามารถลงชื่อไฟล์ขนาดเล็กได้เท่านั้น ในขณะที่ dgst สามารถลงนามไฟล์ขนาดใหญ่โดยพลการเพราะมันจะย่อยก่อนที่จะลงนามผล


สำหรับฉันแล้ว Stephen.z คำตอบก็ใช้ได้หมดแล้ว ก่อนอื่นฉันเล่นกับคำตอบของทอมอยู่พักหนึ่งและในที่สุดก็พบว่า Stephen.z ตอบเพื่อทำงานให้ฉันอย่างสมบูรณ์แบบ ขอบคุณ Stephen.z!
Grzegorz Wierzowiecki

ป.ล. ที่นี่ฉันได้แชร์ตัวอย่างของฉัน: gist.github.com/gwpl/2c7636f0b200cbfbe82cc9d4f6338585
Grzegorz Wierzowiecki

คุณลองใช้ pkeyutl เพื่อลงชื่อเฉพาะแฮชของไฟล์หรือไม่
Gaia

-3

วิธีตรวจสอบลายเซ็น - วิธีแก้ปัญหาที่ง่ายกว่า:

วิธีที่ง่ายกว่าในการตรวจสอบให้แน่ใจว่าเอกสารที่เซ็นชื่อนั้นเหมือนกันคือสร้างไฟล์ลายเซ็นดิจิทัลใหม่จากนั้นใช้ diff เพื่อตรวจสอบว่าไฟล์ลายเซ็นสองไฟล์เหมือนกันหรือไม่


3
คุณคิดว่าการแฮชไม่ได้ลายเซ็น คล้ายกัน แต่ไม่เหมือนกัน: แฮชจะตรวจสอบว่าไฟล์ไม่เปลี่ยนแปลง ลายเซ็นยังยืนยันว่ามันมาจากไหน
Piskvor
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.