วิธีใช้บรรทัดคำสั่ง gpg เพื่อตรวจสอบข้อความรหัสผ่านว่าถูกต้อง


90

ฉันพยายามสำรองข้อมูลโดยอัตโนมัติduplicityแต่เมื่อฉันทดสอบผลลัพธ์ฉันได้รับ

gpg: การถอดรหัสคีย์สาธารณะล้มเหลว: ข้อความรหัสผ่านไม่ถูกต้อง

ฉันต้องการตรวจสอบว่าข้อความรหัสผ่านที่ฉันใช้นั้นเป็นข้อความรหัสผ่านที่เชื่อมโยงกับคีย์ลับ gpg ที่เกี่ยวข้องหรือไม่ แต่ฉันไม่เห็นอยู่ดีในตัวเลือกบรรทัดคำสั่ง gpg ที่ระบุว่า "อย่าเข้ารหัสหรือถอดรหัสอะไรเลยเพียงแค่ยืนยัน ฉันใช้ข้อความรหัสผ่านที่ถูกต้อง "

สิ่งนี้ชี้ให้เห็นว่าบางทีฉันอาจจะเข้าใจผิด Gnu Privacy Guard (อีกครั้ง) (มันมีนิสัยชอบเหน็บแนมฉันจนฉันร้องไห้)

มันสมเหตุสมผลหรือไม่ที่จะขอให้ gpg ตรวจสอบข้อความรหัสผ่าน ถ้าเป็นเช่นนั้นอย่างไร?

คำตอบ:


115

ไม่มีวิธีการในตัวสำหรับการทำเช่นนี้ แต่ทำได้ง่ายพอที่จะสร้างการทดสอบที่ไม่แก้ไขอะไรเลยและให้คุณตรวจสอบข้อความรหัสผ่านของคุณได้

คุณไม่ได้ระบุดังนั้นฉันจะถือว่าคุณใช้ GnuPG เวอร์ชันน้อยกว่า v2 และอยู่บน Linux พร้อม Bash สำหรับตัวแปล commandline ของคุณ

ฉันจะให้คำสั่งที่นี่และด้านล่างฉันจะอธิบายว่าแต่ละส่วนทำอะไร - (หมายเหตุ: ต่อไปนี้ใช้สำหรับ GnuPG series เวอร์ชัน 1 ดูด้านล่างสำหรับ GnuPG series v2)

echo "1234" | gpg --no-use-agent -o /dev/null --local-user <KEYID> -as - && echo "The correct passphrase was entered for this key"

สิ่งที่ต้องทำอันดับแรกคือไพพ์ข้อความเพื่อลงชื่อเข้าใช้ GnuPG ด้วยecho "1234" |- เพราะเราไม่ต้องการเซ็นชื่ออะไรเลยนี่เป็นเพียงการทดสอบดังนั้นเราจะเซ็นข้อความที่ไร้ประโยชน์

ต่อไปเราบอก gpg ว่าอย่าใช้คีย์เอเจนต์กับ--no-use-agent; สิ่งนี้มีความสำคัญในภายหลังเนื่องจากขึ้นอยู่กับตัวแทนหลักของคุณอาจไม่ส่งคืน "0" ในความสำเร็จและนั่นคือทั้งหมดที่เราต้องการทำ - ยืนยันความสำเร็จของข้อความรหัสผ่านของคุณ

ต่อไปเราบอกให้ gpg ใส่ข้อมูลที่เซ็นชื่อลงใน/dev/nullไฟล์โดยตรงซึ่งหมายความว่าเราทิ้งและไม่เขียนผลลัพธ์ไปยังเทอร์มินัล - หมายเหตุ: หากคุณไม่ได้ใช้ Linux / Unix บางรุ่นไฟล์นี้อาจไม่มีอยู่ บน windows คุณอาจต้องอนุญาตให้มันเขียนข้อมูลที่เซ็นชื่อลงบนหน้าจอโดยเว้น-o /dev/nullส่วนนั้นไว้

--local-user 012345ต่อไปเราจะระบุที่สำคัญเราต้องการที่จะทำแบบทดสอบของเราด้วยโดยใช้ คุณสามารถใช้ KeyID เพื่อความเฉพาะเจาะจงสูงสุดหรือใช้ชื่อผู้ใช้ตามความต้องการของคุณ

ต่อไปเราจะระบุ-asซึ่งเปิดใช้งานโหมดเอาต์พุต ascii และตั้งค่าโหมดบริบทสำหรับการเซ็นชื่อ -หลังจากนั้นเพียงแค่บอก GnuPG echo "1234" |ที่จะได้รับข้อมูลที่จะลงนามจากมาตรฐานในซึ่งเป็นส่วนแรกของคำสั่งที่เราให้

และสุดท้ายเรามี&& echo "A message that indicates success"- "&&" หมายถึงหากคำสั่งก่อนหน้านี้สำเร็จให้พิมพ์ข้อความนี้ นี่เป็นเพียงการเพิ่มเพื่อความชัดเจนเนื่องจากความสำเร็จของคำสั่งข้างต้นจะถูกระบุโดยไม่มีเอาต์พุตเลย

ฉันหวังว่าจะชัดเจนพอที่คุณจะเข้าใจสิ่งที่เกิดขึ้นและคุณจะใช้มันในการทดสอบที่คุณต้องการทำอย่างไร หากส่วนใดไม่ชัดเจนหรือคุณไม่เข้าใจเรายินดีที่จะชี้แจง โชคดี!

[แก้ไข] - หากคุณใช้ GnuPG v2 คำสั่งด้านบนจะต้องได้รับการแก้ไขเล็กน้อยดังนี้:

echo "1234" | gpg2 --batch --passphrase-fd 1 -o /dev/null --local-user <KEYID> -as - && echo "The correct passphrase was entered for this key"

ด้วยเหตุนี้ GnuPG v2 จึงคาดว่าข้อความรหัสผ่านจะถูกดึงผ่านตัวแทนดังนั้นเราจึงไม่สามารถปิดการใช้งานเอเจนต์ด้วย--no-use-agentและมีเอฟเฟกต์ที่ต้องการได้ แต่เราจำเป็นต้องบอก GnuPG v2 ว่าเราต้องการที่จะใช้กระบวนการ "ชุด" และดึงข้อความรหัสผ่านจาก STDIN (มาตรฐาน) --passphrase-fd 1โดยใช้ตัวเลือก


11
สิ่งนี้ใช้ไม่ได้กับ gpg2 เนื่องจากต้องใช้เอเจนต์เสมอ นอกจากนี้ตัวแทน ncurses ยังสับสนกับอินพุต piped เลยเพิ่งใช้gpg --local-user <KEYID> -as. เพียงแค่นี้ให้ตัวแทนขอรหัสผ่านและบอกคุณว่าถูกต้องหรือไม่ (จากนั้นก็ไม่ทำอะไรเลย)
BubuIIC

1
คุณถูกต้อง BubullC ส่วนใหญ่; ด้วยการปรับเปลี่ยนเล็กน้อยสำหรับตัวเลือกที่ส่งผ่านคุณสามารถได้ผลลัพธ์ที่คล้ายกันโดยใช้ gpg2 ฉันแก้ไขคำตอบเพื่อรองรับความแตกต่างระหว่าง gpg และ gpg2
kylehuff

4
ลองใช้ GnuPG 2.1:gpg -o /dev/null --local-user <KEYID> -as <(echo 1234) && echo "The correct passphrase was entered for this key"
starfry

6
สำหรับฉันบน MacOS 10.12.6 ไม่มีการแจ้งข้อความรหัสผ่านรูปแบบต่างๆและส่งคืนข้อความแสดงความสำเร็จโดยไม่คำนึงถึง
Stan James

2
--passphrase-fd 1เหรอ? อ่านจาก stdout? สิ่งนี้ใช้ได้กับฉัน: gpg2 -aso - <(echo 1234); echo $?. ใช้echo RELOADAGENT | gpg-connect-agentเพื่อลืมข้อความรหัสผ่าน
x-yuri

20

นี่เป็นบรรทัดคำสั่งที่สั้นกว่าเพื่อตรวจสอบว่าข้อความรหัสผ่านใช้ได้หรือไม่:

gpg --export-secret-keys -a <KEYID> > /dev/null && echo OK

ไม่ถ้าคุณมีgpg-agentแอคทีฟ (ซึ่งคนส่วนใหญ่มี) และคุณเข้าสู่ระบบอย่างถูกต้องสิ่งนี้จะไม่ขอรหัสผ่าน
foki

6

สำหรับฉันวิธีง่ายๆในการตรวจสอบข้อความรหัสผ่านคือการใช้gpg --passwdชวเลข มันพยายามเปลี่ยนข้อความรหัสผ่านและขั้นตอนคือการยืนยันรหัสผ่านเก่าจากนั้นคุณสามารถคลิก 'ยกเลิก' บนข้อความรหัสผ่านใหม่และสิ่งนี้จะทำให้ข้อความรหัสผ่านยังคงอยู่

gpg --passwd <your-user-id>

นี่เป็นวิธีที่ตรงไปตรงมาที่สุดที่ได้ผลไม่ว่าคุณจะมีการgpg-agentใช้งานอยู่หรือไม่ก็ตาม
foki

2

คำเตือนอย่าใช้เสียงสะท้อนgpg -o /dev/nullตามที่แนะนำโดยคำตอบยอดนิยมที่นี่ ซึ่งจะทำให้ / dev / null มีสิทธิ์ที่ไม่ถูกต้องและทำให้/dev/nullไฟล์เสียหาย คุณสามารถตรวจสอบสิทธิ์ของไฟล์ / dev / null เมื่อรันคำสั่งนี้เพื่อพิสูจน์สิ่งนี้

คุณสามารถใช้สิ่งนี้:

echo "1234" | gpg -q --batch --status-fd 1 --sign --local-user $KEY_ID --passphrase-fd 0 > /dev/null

ฉันสร้างสคริปต์ทุบตีสำหรับสิ่งนี้ด้วย (อันนี้ใช้งานได้กับ Centos 8) สคริปต์นี้จะขอรหัสผ่านหากไม่ถูกต้องระบบจะขอให้ป้อนข้อความรหัสผ่านที่ถูกต้อง นอกจากนี้หากคุณป้อน KEY_ID ผิดหรือไม่มีอยู่เป็นอาร์กิวเมนต์ก็สามารถตรวจสอบความถูกต้องได้เช่นกัน:

#!/bin/bash
# usage ./gpgcron KEYID   | ./gpgcron 2B705B8B6FA943B1
script_path=$(dirname $(realpath -s $0))
script_name=$(basename -- "$0")
GPG_CACHE_BIN="/usr/libexec/gpg-preset-passphrase"
KEY_ID=$1
KEY_GRIP=$(gpg --with-keygrip --list-secret-keys $KEY_ID | grep -Pom1 '^ *Keygrip += +\K.*')
RETVAL=$?
if [[ $RETVAL -ne 0 || -z $KEY_ID ]]; then
    echo "Please provide correct KEY_ID. Example ./$script_name KEY_ID"
    exit 1
fi

export GPG_TTY=$(tty)

function set_gpg_cachepass {
    read -s -p "[$script_name | input]: Enter passphrase to cache into gpg-agent: " PASSPHRASE; echo
    $GPG_CACHE_BIN -c $KEY_GRIP <<< $PASSPHRASE
    RETVAL=$?
    echo "[$script_name | info ]: gpg-preset-passphrase return code: [$RETVAL]"
    if [ $RETVAL = 0 ]; then
        echo "[$script_name | info ]: A passphrase has been set and cached in gpg-agent"
        echo "[$script_name | info ]: Paraphrase set return code: [$RETVAL]"
        gpg_validatepass
    else
        echo "[$script_name | info ]: Unsuccessful error occured: [$RETVAL]"
        set_gpg_cachepass
    fi
}

function gpg_validatepass {
    echo "[$script_name | info ]: Validating passphrase cached in gpg-agent ..."
    echo "1234" | gpg -q --batch --status-fd 1 --sign --local-user $KEY_ID --passphrase-fd 0 > /dev/null
    RETVAL=$?
    if [ $RETVAL = 0 ]; then
        echo "[$script_name | info ]: OK, valid passphrase has been cached in gpg-agent"
    else
        echo "[$script_name | info ]: Warning, invalid passphrase or no passphrase is cached in gpg-agent"
        set_gpg_cachepass
    fi
}

RES=$(echo "KEYINFO --no-ask $KEY_GRIP Err Pmt Des" | gpg-connect-agent | awk '{ print $7 }')
if [ "$RES" == "1" ]; then
    echo "[$script_name | info ]: OK, passphrase is already cached in gpg agent for KEY_ID of [$KEY_ID]"
    gpg_validatepass
else
    echo "[$script_name | info ]: Warning, no passphrase is cached in gpg agent for KEY_ID of [$KEY_ID]"
    set_gpg_cachepass
fi

เอาต์พุตตัวอย่างหากไม่มีการแคชรหัสผ่านใน gpg-agent:

[root@earth gpg]# ./gpgcron 2B705B8B6FA943B2
[gpgcron | info ]: Warning, no passphrase is cached in gpg agent for KEY_ID of [2B705B8B6FA943B2]
[gpgcron | input]: Enter passphrase to cache into gpg-agent:

ตัวอย่างผลลัพธ์หากป้อนข้อความรหัสผ่านไม่ถูกต้อง (จะถามต่อไป):

[root@earth gpg]# ./gpgcron 2B705B8B6FA943B2
[gpgcron | info ]: OK, passphrase is already cached in gpg agent for KEY_ID of [2B705B8B6FA943B2]
[gpgcron | info ]: Validating passphrase cached in gpg-agent ...
gpg: signing failed: Bad passphrase
gpg: signing failed: Bad passphrase
[gpgcron | info ]: Warning, invalid passphrase or no passphrase is cached in gpg-agent
[gpgcron | input]: Enter passphrase to cache into gpg-agent:

เอาต์พุตตัวอย่างหากป้อนข้อความรหัสผ่านที่ถูกต้อง:

[gpgcron | input]: Enter passphrase to cache into gpg-agent:
[gpgcron | info ]: gpg-preset-passphrase return code: [0]
[gpgcron | info ]: A passphrase has been set and cached in gpg-agent
[gpgcron | info ]: Paraphrase set return code: [0]
[gpgcron | info ]: Validating passphrase cached in gpg-agent ...
[gpgcron | info ]: OK, valid passphrase has been cached in gpg-agent

เมื่อแคชข้อความรหัสผ่านที่ถูกต้องในครั้งต่อไปที่คุณเรียกใช้สคริปต์นี้จะไม่ขอให้คุณป้อนข้อความรหัสผ่าน ดังนั้นสคริปต์นี้ให้คำตอบสำหรับคำถามของคุณ "เพียงยืนยันว่าฉันใช้ข้อความรหัสผ่านที่ถูกต้อง"

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