先前提過我想用便宜的自製 USB 實體金鑰配合 GPG 軟體實現「擁有特定硬體才能簽章、解密及登入」的高強度資安機制,實體 USB 金鑰具備有金鑰無法匯出複製、無法遠端破解、密碼及 PIN 碼雙重保護、錯誤次數上限鎖定銷毁等特性,安全性一般金鑰檔高出數倍。

不過,用 GPG 工具指令將金鑰存入 USB 實體金鑰的操作步驟繁瑣,對新手並不友善,未來有機會我想寫個 GUI 工具將複雜程序封裝起來,但在此之前我打算整理一篇完整筆記,以免下次又跟今天一樣爬文找半天。(註:以下程序也適合 Yubikey、Nitrokey Pro 等支援 OpenPGP 的產品)

產生金鑰

目的:產生一把 ECC 金鑰並新增認證用的子金鑰,以同時支援簽章、加密及身分認證(登入)三種用途。
這部分上回已經寫文章介紹過了,這回再補充產生身分認證子金鑰部分。

【新手常識】若不小心操作錯誤搞砸或被鎖死,可重置 GPG 實體金鑰(注意:存在裡面的金鑰資料會被清空)重新來過,跟手機一樣,搞壞就恢復原廠重來一次。重設步驟為 gpg --edit-cardadminfactory-reset

gpg/card> admin
Admin commands are allowed

gpg/card> factory-reset
gpg: OpenPGP card no. D276000124010200FFFE4E5232310000 detected

gpg: Note: This command destroys all keys stored on the card!

Continue? (y/N) y
Really do a factory reset? (enter "yes") yes

gpg/card> quit

先建立一把 ECC 金鑰:

X:\>gpg --full-generate-key
gpg (GnuPG) 2.4.3; Copyright (C) 2023 g10 Code GmbH
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.

Please select what kind of key you want:
   (1) RSA and RSA
   (2) DSA and Elgamal
   (3) DSA (sign only)
   (4) RSA (sign only)
   (9) ECC (sign and encrypt) *default*
  (10) ECC (sign only)
  (14) Existing key from card
Your selection?
Please select which elliptic curve you want:
   (1) Curve 25519 *default*
   (4) NIST P-384
   (6) Brainpool P-256
Your selection?
Please specify how long the key should be valid.
         0 = key does not expire
      <n>  = key expires in n days
      <n>w = key expires in n weeks
      <n>m = key expires in n months
      <n>y = key expires in n years
Key is valid for? (0)
Key does not expire at all
Is this correct? (y/N) y

GnuPG needs to construct a user ID to identify your key.

Real name: Jeffrey
Email address: jeffrey@darkthread.net
Comment: Gnuk Token
You selected this USER-ID:
    "Jeffrey (Gnuk Token) <jeffrey@darkthread.net>"

Change (N)ame, (C)omment, (E)mail or (O)kay/(Q)uit? o
### 這裡會彈出對話框要求設定金鑰密碼
We need to generate a lot of random bytes. It is a good idea to perform
some other action (type on the keyboard, move the mouse, utilize the
disks) during the prime generation; this gives the random number
generator a better chance to gain enough entropy.
We need to generate a lot of random bytes. It is a good idea to perform
some other action (type on the keyboard, move the mouse, utilize the
disks) during the prime generation; this gives the random number
generator a better chance to gain enough entropy.
gpg: revocation certificate stored as 'C:\\Users\\jeffrey\\AppData\\Roaming\\gnupg\\openpgp-revocs.d\\B7C9B8ED0F20DED189B920628203FE9C7EC51718.rev'
public and secret key created and signed.

pub   ed25519 2023-08-06 [SC]
      B7C9B8ED0F20DED189B920628203FE9C7EC51718
uid                      Jeffrey (Gnuk Token) <jeffrey@darkthread.net>
sub   cv25519 2023-08-06 [E]

再來要做一把子金鑰供身分認證(例如:SSH 登入),指令為 gpg --expert --edit-key <Real name or email or key id> (記得加 --expert 以顯示進階選項)

X:\>gpg --expert --edit-key Jeffrey
gpg (GnuPG) 2.4.3; Copyright (C) 2023 g10 Code GmbH
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.

gpg: checking the trustdb
gpg: marginals needed: 3  completes needed: 1  trust model: pgp
gpg: depth: 0  valid:   1  signed:   0  trust: 0-, 0q, 0n, 0m, 0f, 1u
Secret key is available.

sec  ed25519/8203FE9C7EC51718
     created: 2023-08-06  expires: never       usage: SC
     trust: ultimate      validity: ultimate
ssb  cv25519/063462189E625F9C
     created: 2023-08-06  expires: never       usage: E
[ultimate] (1). Jeffrey (Gnuk Token) <jeffrey@darkthread.net>

gpg> addkey
Please select what kind of key you want:
   (3) DSA (sign only)
   (4) RSA (sign only)
   (5) Elgamal (encrypt only)
   (6) RSA (encrypt only)
   (7) DSA (set your own capabilities)
   (8) RSA (set your own capabilities)
  (10) ECC (sign only)
  (11) ECC (set your own capabilities)
  (12) ECC (encrypt only)
  (13) Existing key
  (14) Existing key from card
### 請選 11 自訂用途  
Your selection? 11

Possible actions for this ECC key: Sign Authenticate
Current allowed actions: Sign

   (S) Toggle the sign capability
   (A) Toggle the authenticate capability
   (Q) Finished
### 選 A 加上認證功能
Your selection? a

Possible actions for this ECC key: Sign Authenticate
Current allowed actions: Sign Authenticate

   (S) Toggle the sign capability
   (A) Toggle the authenticate capability
   (Q) Finished
### 選 S 拿掉簽章功能
Your selection? s

Possible actions for this ECC key: Sign Authenticate
Current allowed actions: Authenticate

   (S) Toggle the sign capability
   (A) Toggle the authenticate capability
   (Q) Finished  
### 選 Q 完成   
Your selection? q
Please select which elliptic curve you want:
   (1) Curve 25519 *default*
   (2) Curve 448
   (3) NIST P-256
   (4) NIST P-384
   (5) NIST P-521
   (6) Brainpool P-256
   (7) Brainpool P-384
   (8) Brainpool P-512
   (9) secp256k1
### 使用預設 Curve 25519   
Your selection?
Please specify how long the key should be valid.
         0 = key does not expire
      <n>  = key expires in n days
      <n>w = key expires in n weeks
      <n>m = key expires in n months
      <n>y = key expires in n years
### 使用預設值,永不過期      
Key is valid for? (0)
Key does not expire at all
Is this correct? (y/N) y
Really create? (y/N) y
### 這裡會彈出對話框要求輸入金鑰密碼
We need to generate a lot of random bytes. It is a good idea to perform
some other action (type on the keyboard, move the mouse, utilize the
disks) during the prime generation; this gives the random number
generator a better chance to gain enough entropy.

sec  ed25519/8203FE9C7EC51718
     created: 2023-08-06  expires: never       usage: SC
     trust: ultimate      validity: ultimate
ssb  cv25519/063462189E625F9C
     created: 2023-08-06  expires: never       usage: E
ssb  ed25519/6437BCF8D3CC206B
     created: 2023-08-06  expires: never       usage: A
[ultimate] (1). Jeffrey (Gnuk Token) <jeffrey@darkthread.net>

gpg> q
Save changes? (y/N) y

做完之後在原有 sec/ssb 外會再多一個 ssb 項目,usage 為 A (Authentication)。

備份金鑰

稍後我們會的金鑰匯入實體金鑰並從個人電腦刪除,為防止實體金鑰壞掉檔案永遠解不開,強烈建議將金鑰匯出成檔案複製到離線媒體妥善保存。(若選擇存在行動碟的話要留意SSD、USB 行動碟擺久資料會消失間題),我個人建議可考慮多列一份紙本,多一個保存管道以備不時之需。檔案複製好請從本機刪除,降低被竊取風險。

匯出成文字格式檔案指令如下:

X:\Backup\GpgKeys>gpg --export-secret-key -a -o Jeffrey.seckey.asc Jeffrey
### 這裡會彈出對話框要求輸入金鑰密碼
X:\Backup\GpgKeys>gpg --export -a -o Jeffrey.pubkey.asc Jeffrey

.seckey.asc 為私鑰檔,請務必用最高保密等級管理;.pubkey.asc 則屬公開資訊,可隨意發送給溝通對象。

將金鑰存入實體金鑰

接下來我們要將三把金鑰(簽章、加密、身分認證)都寫入實體金鑰,並將其從個人電腦上移除,未來要簽章、解密或登入,都必須插入實體金鑰並輸入 PIN 碼(或再上按實體鈕動作)才能完成。

X:\Backup\GpgKeys>gpg --edit-key Jeffrey
gpg (GnuPG) 2.4.3; Copyright (C) 2023 g10 Code GmbH
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.

Secret key is available.

sec  ed25519/8203FE9C7EC51718
     created: 2023-08-06  expires: never       usage: SC
     trust: ultimate      validity: ultimate
ssb  cv25519/063462189E625F9C
     created: 2023-08-06  expires: never       usage: E
ssb  ed25519/6437BCF8D3CC206B
     created: 2023-08-06  expires: never       usage: A
[ultimate] (1). Jeffrey (Gnuk Token) <jeffrey@darkthread.net>

gpg> keytocard
Really move the primary key? (y/N) y
Please select where to store the key:
   (1) Signature key
   (3) Authentication key
Your selection? 1
### 輸入金鑰密碼及輸入兩次 Admin PIN 碼,Gnuk 預設 Admin PIN 為 12345678
sec  ed25519/8203FE9C7EC51718
     created: 2023-08-06  expires: never       usage: SC
     trust: ultimate      validity: ultimate
ssb  cv25519/063462189E625F9C
     created: 2023-08-06  expires: never       usage: E
ssb  ed25519/6437BCF8D3CC206B
     created: 2023-08-06  expires: never       usage: A
[ultimate] (1). Jeffrey (Gnuk Token) <jeffrey@darkthread.net>

Note: the local copy of the secret key will only be deleted with "save".
gpg> key 1

sec  ed25519/8203FE9C7EC51718
     created: 2023-08-06  expires: never       usage: SC
     trust: ultimate      validity: ultimate
ssb* cv25519/063462189E625F9C
     created: 2023-08-06  expires: never       usage: E
ssb  ed25519/6437BCF8D3CC206B
     created: 2023-08-06  expires: never       usage: A
[ultimate] (1). Jeffrey (Gnuk Token) <jeffrey@darkthread.net>
### 注意第二筆 ssb* 出現星號表選取中
gpg> keytocard
Please select where to store the key:
   (2) Encryption key
Your selection? 2
### 輸入金鑰密碼及輸入一次 Admin PIN 碼
sec  ed25519/8203FE9C7EC51718
     created: 2023-08-06  expires: never       usage: SC
     trust: ultimate      validity: ultimate
ssb* cv25519/063462189E625F9C
     created: 2023-08-06  expires: never       usage: E
ssb  ed25519/6437BCF8D3CC206B
     created: 2023-08-06  expires: never       usage: A
[ultimate] (1). Jeffrey (Gnuk Token) <jeffrey@darkthread.net>

Note: the local copy of the secret key will only be deleted with "save".
gpg> key 1

sec  ed25519/8203FE9C7EC51718
     created: 2023-08-06  expires: never       usage: SC
     trust: ultimate      validity: ultimate
ssb  cv25519/063462189E625F9C
     created: 2023-08-06  expires: never       usage: E
ssb  ed25519/6437BCF8D3CC206B
     created: 2023-08-06  expires: never       usage: A
[ultimate] (1). Jeffrey (Gnuk Token) <jeffrey@darkthread.net>

### 第二筆 ssb 星號取消
gpg> key 2

sec  ed25519/8203FE9C7EC51718
     created: 2023-08-06  expires: never       usage: SC
     trust: ultimate      validity: ultimate
ssb  cv25519/063462189E625F9C
     created: 2023-08-06  expires: never       usage: E
ssb* ed25519/6437BCF8D3CC206B
     created: 2023-08-06  expires: never       usage: A
[ultimate] (1). Jeffrey (Gnuk Token) <jeffrey@darkthread.net>

### 第三筆 ssb* 出現星號表選取中
gpg> keytocard
Please select where to store the key:
   (3) Authentication key
Your selection? 3
### 輸入金鑰密碼及輸入一次 Admin PIN 碼
sec  ed25519/8203FE9C7EC51718
     created: 2023-08-06  expires: never       usage: SC
     trust: ultimate      validity: ultimate
ssb  cv25519/063462189E625F9C
     created: 2023-08-06  expires: never       usage: E
ssb* ed25519/6437BCF8D3CC206B
     created: 2023-08-06  expires: never       usage: A
[ultimate] (1). Jeffrey (Gnuk Token) <jeffrey@darkthread.net>

Note: the local copy of the secret key will only be deleted with "save".

### 注意
### 如果此時若輸入 save,個人電腦上的金鑰就會被刪除
### 若要將金鑰複製到第二把第三把備份鑰匙,請輸入 quit 並確認不儲存
gpg> quit
Save changes? (y/N) n
Quit without saving? (y/N) y

### 若已做完所備份鑰匙,輸入 save 之訊息如下
gpg> quit
Save changes? (y/N) y

註:如果總共要打三把實體金鑰,前兩支做完先 quit,第三支做完再 save 刪掉電腦上的私鑰。

啟用實體按鈕確認

若實體金鑰上有確認鈕,可透過以下指令啟用:

X:\>gpg --edit-card

Reader ...........: Free Software Initiative of Jap Gnuk Token 0
Application ID ...: D276000124010200FFFE4E5232310000
Application type .: OpenPGP
Version ..........: 2.0
Manufacturer .....: unmanaged S/N range
Serial number ....: 4E523231
Name of cardholder: [not set]
Language prefs ...: [not set]
Salutation .......:
URL of public key : [not set]
Login data .......: [not set]
Signature PIN ....: forced
Key attributes ...: ed25519 cv25519 ed25519
Max. PIN lengths .: 127 127 127
PIN retry counter : 3 3 3
Signature counter : 0
KDF setting ......: off
UIF setting ......: Sign=off Decrypt=off Auth=off
Signature key ....: B7C9 B8ED 0F20 DED1 89B9  2062 8203 FE9C 7EC5 1718
      created ....: 2023-08-06 04:57:24
Encryption key....: 67C8 77F6 1380 3014 DCBF  46FE 0634 6218 9E62 5F9C
      created ....: 2023-08-06 04:57:24
Authentication key: DD2E C821 FD81 0043 DC0A  4B8C 6437 BCF8 D3CC 206B
      created ....: 2023-08-06 05:01:32
General key info..:
pub  ed25519/8203FE9C7EC51718 2023-08-06 Jeffrey (Gnuk Token) <jeffrey@darkthread.net>
sec>  ed25519/8203FE9C7EC51718  created: 2023-08-06  expires: never
                                card-no: FFFE 4E523231
ssb>  cv25519/063462189E625F9C  created: 2023-08-06  expires: never
                                card-no: FFFE 4E523231
ssb>  ed25519/6437BCF8D3CC206B  created: 2023-08-06  expires: never
                                card-no: FFFE 4E523231

gpg/card> admin
Admin commands are allowed

### 1 - sign 簽署時需按鈕
gpg/card> uif 1 on
### 2 - decrypt 解密時需按鈕
gpg/card> uif 2 on
### 3 - auth  登入時需按鈕
gpg/card> uif 3 on

gpg/card> q

修改 PIN 碼

實體金鑰上有二組 PIN 碼,一組為簽章、解密、登入時輸入,另一組 Admin PIN 在管理金鑰會用到。GPG 預設的 PIN 及 Admin PIN 分別為 123456 及 12345678,若要修改指令如下:

D:\>gpg --change-pin
gpg: OpenPGP card no. D276000124010200FFFE4E5239570000 detected

1 - change PIN
2 - unblock PIN
3 - change Admin PIN
4 - set the Reset Code
Q - quit

Your selection? 3
### 輸入舊 Admin PIN,新 Admin PIN 及再次輸入確認 (8 碼以上)
PIN changed.

1 - change PIN
2 - unblock PIN
3 - change Admin PIN
4 - set the Reset Code
Q - quit

Your selection? 1
### 輸入舊 PIN,新 PIN 及再次輸入確認 (6 碼以上)
PIN changed.

1 - change PIN
2 - unblock PIN
3 - change Admin PIN
4 - set the Reset Code
Q - quit

Your selection? q

注意:記得先修改 Admin PIN 再改 PIN,若先改 PIN 會進入 Adminless Mode,PIN 與 Admin PIN 相同,而 PIN 必須 8 碼以上。

後話

順便更新我的雞排實體金鑰 Side Project 進度。

找到完美的觸控開關裝法 - 從廢棄滑鼠拆下微動開關,剪掉中央腳,1, 3 腳跨接電路板末端兩側最靠外的接點,接腳距離與開關寬度剛好,外型也不會突兀,Perfect!

thumbnail

一口氣多做了兩把備份鑰匙,準備正式拿它來做日常加密,GO!


Comments

Be the first to post a comment

Post a comment