更新日誌
2020/10/20
從 iOS 換到 Android 後,發現 Password Store 這款 app 需要 OpenKeychain 來負責處理加解密的功能。但 OpenKeychain 居然沒有提供用指紋來加解密的功能?
看了 issue 發現從 2015 就提出來了,但到現在都沒有做出來… 找了一陣子發現好像真的沒有什麼好的解決方法,目前就改用 keepass 替代了,keepass 在 Linux 上有 KeePassXC,Android 上有 Keepass2Android Password Safe 的客戶端。

使用 pass (zx2c4) 自架密碼管理平台

如果對於線上的密碼管理服務仍然不太放心,不訪也可以嘗試 pass 這套密碼管理工具,pass 是受 Unix 哲學啟發的密碼管理器,它使用 GnuPG 對密碼進行加密和解密。

pass 的密碼會儲存在檔案中,並透過目錄組織。他的優點是即使在 CLI 也可以使用,對於常使用 CLI 處理事情的人或許會更方便管理,除此之外因為是一個一個的檔案,所以它也可以使用 git 來進行版本控制。在安全性的方面,也可以再串接 Yubikey、Nitrokey 等裝置可以進一步提昇安全性。

先備知識

PGP

PGP (Pretty Good Privacy) 是由 Philip R. Zimmermann 開發的一個程式,用來提供資料加密與認證。

OpenPGP

根據美國出口管理法案中的定義,加密系統使用大於 40 位的金鑰將被認為是軍需品,因此 PGP 也受此限制而面對官司問題。後來 Zimmermann 透過將 PGP 的原始碼出版成書規避掉出口問題,並且又將 PGP 訂定了一套標準叫做 OpenPGP。

GnuPG

GnuPG 則是遵循 OpenPGP 這套標準所實作的一個自由軟體。

架構

如果有 Yubikey、Nitrokey,可能架構會變成下圖,Sub Private Key 會被存在 Yubikey 或是 Nitrokey 上:

架設環境

GnuPG

通常會先生成 master key,再生成 sub key,將 master key 放到安全的地方儲存,這樣出事時只要重新再用 master key 生成一組新的 sub key 就好,方便管理。

生成 master key

1
$ gpg --full-gen-key --expert

–expert: getting alternative ciphers like ECC

ECC 的主要優勢是它相比 RSA 加密演算法使用較小的密鑰長度並提供相當等級的安全性。

由於我們不想直接使用 master key,所以選擇 8,好調整 master key 的功能

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
gpg (GnuPG) 2.2.21; Copyright (C) 2020 Free Software Foundation, Inc.
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 (default)
   (2) DSA and Elgamal
   (3) DSA (sign only)
   (4) RSA (sign only)
   (7) DSA (set your own capabilities)
   (8) RSA (set your own capabilities)
   (9) ECC and ECC
  (10) ECC (sign only)
  (11) ECC (set your own capabilities)
  (13) Existing key
  (14) Existing key from card
Your selection? 8

調整讓 master key 的功能只剩下 Certify

1
2
3
4
5
6
7
8
9
Possible actions for a RSA key: Sign Certify Encrypt Authenticate
Current allowed actions: Certify

   (S) Toggle the sign capability
   (E) Toggle the encrypt capability
   (A) Toggle the authenticate capability
   (Q) Finished

Your selection? Q

長度選擇 4096

1
2
3
RSA keys may be between 1024 and 4096 bits long.
What keysize do you want? (2048) 4096
Requested keysize is 4096 bits

因為平常不打算用 master key,所以設定不讓他過期

1
2
3
4
5
6
7
8
9
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) 0
Key does not expire at all
Is this correct? (y/N) y

輸入名字和 Email

1
2
3
4
5
6
7
8
9
GnuPG needs to construct a user ID to identify your key.

Real name: <NAME>
Email address: <EMAIL>
Comment:
You selected this USER-ID:
    "<NAME> <EMAIL>"

Change (N)ame, (C)omment, (E)mail or (O)kay/(Q)uit? O

等待生成,注意這邊 revocation certificate 也會同時被生成,revocation certificate 可以用來宣告這把 master key 是否還有效,等等會將 master key 與 revocation certificate 移動到安全的地方

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
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: key <MASTER-KEY-ID> marked as ultimately trusted
gpg: revocation certificate stored as '$HOME/.gnupg/openpgp-revocs.d/<MASTER-KEY-ID>.rev'
public and secret key created and signed.

pub   rsa4096 2020-07-17 [SCE]
      <MASTER-KEY-ID>
uid                      <NAME> <EMAIL>

生成 sub key

1
$ gpg --edit-key <MASTER-KEY-ID>

使用 addkey

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
gpg (GnuPG) 2.2.21; Copyright (C) 2020 Free Software Foundation, Inc.
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  rsa4096/<MASTER-KEY-ID>
     created: 2020-07-17  expires: never       usage: SCE
     trust: ultimate      validity: ultimate
[ultimate] (1). <NAME> <EMAIL>

gpg> addkey

選擇加密方式

1
2
3
4
5
6
7
Please select what kind of key you want:
   (3) DSA (sign only)
   (4) RSA (sign only)
   (5) Elgamal (encrypt only)
   (6) RSA (encrypt only)
  (14) Existing key from card
Your selection? 6

長度一樣設定 4096,設定過期時間,可以設短一點,強迫自己要定期更新 subkey,這步驟會彈出一個視窗,就輸入剛剛在生成 Master Key 時設定的密碼就可以了

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
RSA keys may be between 1024 and 4096 bits long.
What keysize do you want? (2048) 4096
Requested keysize is 4096 bits
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) 1y
Key expires at Sat 17 Jul 2021 05:06:10 PM UTC
Is this correct? (y/N) y
Really create? (y/N) y

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

等待生成

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
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  rsa4096/<MASTER-KEY-ID>
     created: 2020-07-20  expires: never       usage: C
     trust: ultimate      validity: ultimate
ssb  rsa4096/<SUB-KEY-ID>
     created: 2020-07-20  expires: 2023-07-20  usage: E
[ultimate] (1). <NAME> <EMAIL>

匯出 private key

1
$ gpg --export-secret-keys --armor <MASTER-KEY-ID> > private.asc

轉移 private key 及 revocation certificate

將前面拿到的 revocation certificate 與 private key 轉移到安全的地方,我自己是存在隨身碟上,並使用 eCryptfs 將 partition 做加密。

刪除 master private key

參考 Using an offline GnuPG master key,首先拿到 Keygrip 那行

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
$ gpg --list-secret-keys --with-keygrip

$HOME/.gnupg/pubring.kbx
-----------------------------
sec   rsa4096 2020-07-17 [SCE]
      12345...................................
      Keygrip = ABCDE...................................
uid           [ultimate] <NAME> <EMAIL>
ssb   rsa4096 2020-07-17 [E] [expires: 2021-07-17]
      Keygrip = FGHIJ...................................

將 master key 上的 Keygrip 帶進去下面的指令刪除

1
$ gpg-connect-agent "DELETE_KEY ABCDE..................................." /bye

# 的話就表示有成功刪除

1
2
3
4
5
6
$ gpg --list-secret-keys
-----------------------------
sec#  rsa4096 2020-07-17 [SCE]
      12345...................................
uid           [ultimate] <NAME> <EMAIL>
ssb   rsa4096 2020-07-17 [E] [expires: 2021-07-17]

pass (zx2c4)

我使用了 pass-tomb 這個 extension,他的作用是可以將整個 $HOME/.password-store 目錄在不使用 pass 時變成 tomb,使目錄下的檔案名稱 (通常是 domain、或是 username 的明文) 不會曝光。

pass 使用非常簡單,首先初始化:

1
$ pass tomb <MASTER-KEY-ID>

打開 tomb

1
$ pass open

初始化 git

1
$ pass git init

使用完畢後執行下方指令會將 tomb 導出到 $HOME/.password.tomb

1
$ pass close

git bare repository

在自己的 server 上建立一個目錄並執行

1
$ git init --bare

在本機上進入 pass 的資料夾,設定 remote 並 push 即可同步到雲端上

從其他平台轉移到 pass

可以使用 pass-import 這個 extension,或是使用官網提供的腳本,使用腳本的話要注意名字不能重複,我用了 lastpass 的腳本發現他沒有處理名稱衝突的問題。

日常使用

同步

客戶端基本上都有提供同步功能,只要設定好 git 應該就不難做同步

Chrome

我使用 browserpass-extension 這款 extension,他要先安裝 browserpass-native

使用方式大概就是 Ctrl+Shift+F 可以自動填入,Ctrl+Shift+L 可以叫出視窗,輸入關鍵字可以進行過濾。唯一比較不足的地方是如果要新增一條新的 password,要在外面執行 pass insert ... 不能直接像 lastpass 一樣彈出一個選項問你要不要加一條,不過應該平常也不會常加,所以也還好。

IOS

App Store 上有 app 叫做 passforios。基本上設定好 git 目錄就會自動同步了,也不太需要花什麼精力。

唯一比較 tricky 的是在傳送 PGP Key 的部份,我自從買 iPhone 後一直不知道要怎麼接電腦把檔案送進去,每次都要用雲端傳檔案 @@

還好 passforios 裡面有一個功能是掃 qrcode 輸入 key,後來找到 asc-key-to-qr-code 這個工具,透過 qrencode 可以把 key 變成幾張 qrcode,再進到程式裡把 key 掃進去就設定完了。

key 的過期與撤銷處理

若想繼續使用可以 gpg --edit-key <MASTER-KEY-ID> 透過 expire 更新過期時間。撤銷則是執行 revkey 這個指令。

comments powered by Disqus