まずは手作業で生成。これと同じような性質を持った鍵を自動生成したい
$ gpg --gen-key gpg (GnuPG) 1.4.18; Copyright (C) 2014 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) Your selection? 1 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) 0 Key does not expire at all Is this correct? (y/N) y You need a user ID to identify your key; the software constructs the user ID from the Real Name, Comment and Email Address in this form: "Heinrich Heine (Der Dichter) <heinrichh@duesseldorf.de>" Real name: hoge fuga Email address: hoge@example.com Comment: You selected this USER-ID: "hoge fuga <hoge@example.com>" Change (N)ame, (C)omment, (E)mail or (O)kay/(Q)uit? O You need a Passphrase to protect your secret key. 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: key DDEC2E41 marked as ultimately trusted public and secret key created and signed. gpg: checking the trustdb gpg: 3 marginal(s) needed, 1 complete(s) needed, PGP trust model gpg: depth: 0 valid: 2 signed: 0 trust: 0-, 0q, 0n, 0m, 0f, 2u pub 4096R/DDEC2E41 2015-12-30 Key fingerprint = 06B3 443E 7938 F2C6 00E5 63B1 6BA1 F472 DDEC 2E41 uid hoge fuga <hoge@example.com> sub 4096R/1F4E2F6B 2015-12-30
$ gpg --with-colons --list-public-keys DDEC2E41 && gpg --with-colons --list-secret-keys DDEC2E41 tru::1:1451463850:0:3:1:5 pub:u:4096:1:6BA1F472DDEC2E41:2015-12-30:::u:hoge fuga <hoge@example.com>::scESC: sub:u:4096:1:2CD4B6281F4E2F6B:2015-12-30::::::e: sec::4096:1:6BA1F472DDEC2E41:2015-12-30::::hoge fuga <hoge@example.com>::scESC: ssb::4096:1:2CD4B6281F4E2F6B:2015-12-30::::::e:
次に自動生成テスト
$ cat << 'EOT' | gpg --batch --gen-key Key-Type: RSA Key-Length: 4096 Key-Usage: encrypt sign Subkey-Type: RSA Subkey-Length: 4096 Subkey-Usage: encrypt Name-Real: hoge fuga Name-Email: hoge@example.com Expire-Date: 0 Passphrase: hoge %commit EOT ....+++++ .+++++ .........................+++++ ...+++++ gpg: key 29C464C3 marked as ultimately trusted
$ gpg --with-colons --list-public-keys 29C464C3 tru::1:1451465282:0:3:1:5 pub:u:4096:1:6BF5D97229C464C3:2015-12-30:::u:hoge fuga <hoge@example.com>::escESC: sub:u:4096:1:17BF764173B8F76E:2015-12-30::::::e: $ gpg --with-colons --list-secret-keys 29C464C3 sec::4096:1:6BF5D97229C464C3:2015-12-30::::hoge fuga <hoge@example.com>::escESC: ssb::4096:1:17BF764173B8F76E:2015-12-30::::::e:
相手の公開鍵を使って暗号化
$ gpg --recipient 29C464C3 --encrypt-files --armor ls.txt
gpg を使ってファイル (originated_from_29C464C3.txt) の出自を保証する。
$ ls -la > originated_from_29C464C3.txt
ファイル (originated_from_29C464C3.txt) に対して自分の秘密鍵 (--default-key 29C464C3) を使って ASCII 形式 (--armor) で署名して (--detach-sign)、内容を署名ファイル (--output originated_from_29C464C3.txt.asc) に出力。
$ gpg --default-key 29C464C3 \ --armor \ --detach-sign \ --output originated_from_29C464C3.txt.asc \ originated_from_29C464C3.txt You need a passphrase to unlock the secret key for user: "hoge fuga <hoge@example.com>" 4096-bit RSA key, ID 29C464C3, created 2015-12-30
まずは署名した本人で内容検証。署名ファイル (originated_from_29C464C3.txt.asc) を使って出自を保証したいファイル (originated_from_29C464C3.txt) の内容を検証 (--verify)。
$ gpg --verify originated_from_29C464C3.txt.asc originated_from_29C464C3.txt gpg: Signature made Wed Dec 30 18:46:14 2015 JST using RSA key ID 29C464C3 gpg: Good signature from "hoge fuga <hoge@example.com>" $ echo $? 0
出自を保証したいファイル (originated_from_29C464C3.txt) と署名ファイル (originated_from_29C464C3.txt.asc) をもらった人も内容検証。ファイルを貰った人は署名ファイルの示す鍵 ID (29C464C3) に対応する公開鍵を持っていなかったので、検証に失敗している。
$ gpg --verify originated_from_29C464C3.txt.asc originated_from_29C464C3.txt gpg: Signature made Wed 30 Dec 2015 06:46:14 PM JST using RSA key ID 29C464C3 gpg: Can't check signature: public key not found $ echo $? 2
ファイルを貰った人はまず公開サーバを確認した。どうやら鍵サーバには鍵 ID (29C464C3) は存在しない。ということで、ファイルを送った人に公開鍵をくれるように頼んだ。
$ gpg --search-keys 29C464C3 gpg: searching for "29C464C3" from hkp server keys.gnupg.net gpg: key "29C464C3" not found on keyserver
ファイルを送った人は署名を施した秘密鍵に対応する公開鍵をエクスポートしなければいけない。秘密鍵の鍵 ID (29C464C3) に対応する公開鍵を ASCII 形式 (--armor) でエクスポート (--export) した内容をファイルに出力 (--output 29C464C3.asc) する。このファイルを渡す。
$ gpg --output 29C464C3.asc --armor --export 29C464C3
ファイルを貰った人は受け取った公開鍵ファイル (29C464C3.asc) を自分の鍵束にインポート (--import) する。その後、もう一回検証を行う。gpg の exit code は0ということで検証には成功している。
$ gpg --import 29C464C3.asc gpg: key 29C464C3: public key "hoge fuga <hoge@example.com>" imported gpg: Total number processed: 1 gpg: imported: 1 (RSA: 1) $ gpg --verify originated_from_29C464C3.txt.asc originated_from_29C464C3.txt gpg: Signature made Wed 30 Dec 2015 06:46:14 PM JST using RSA key ID 29C464C3 gpg: Good signature from "hoge fuga <hoge@example.com>" gpg: WARNING: This key is not certified with a trusted signature! gpg: There is no indication that the signature belongs to the owner. Primary key fingerprint: EE7F 5AD7 FBFD D033 71EA C6FB 6BF5 D972 29C4 64C3 $ echo $? 0
ここで例えば originated_from_29C464C3.txt を改ざんすると、検証に失敗することがわかる。
$ echo > originated_from_29C464C3.txt $ gpg --verify originated_from_29C464C3.txt.asc originated_from_29C464C3.txt gpg: Signature made Wed 30 Dec 2015 06:46:14 PM JST using RSA key ID 29C464C3 gpg: BAD signature from "hoge fuga <hoge@example.com>"