暗号化とは 暗号方式の種類や復号化の方法について

スポンサーリンク

セキュリティの CIA

最初に、暗号化は以下のセキュリティの CIA を満たすために行います。

  • 機密性 (Confidentiality): 送信されるデータを盗聴できない
  • 完全性・整合性 (Integrity): 送信されるデータの欠損や改ざんを検出可能
  • 認証 (Authentication): 通信相手が正しいことを確認可能
スポンサーリンク

暗号方式とアルゴリズムの種類一覧

暗号方式は大きく分けて次の3つがあります。

暗号方式CIA利用用途暗号化アルゴリズム
一方向暗号完全性メッセージの変化を検出
- MAC(Message Authentication Code)
・MD5
・SHA-1
・SHA-2
・SHA-3
・AEAD
共通鍵暗号機密性通信の暗号化
- 公開鍵暗号より高速なため
・DES
・AES
・RC4
公開鍵暗号機密性共通鍵の交換
- 公開鍵は盗まれても問題無いため
- 共通鍵は盗まれると大問題
・DH
・ECDH
・ECDSA
・ECDHE
認証
電子署名
・RSA
・ECDSA
・EdDSA
・ECC

一方向暗号(ハッシュ関数)とは

一方向暗号(ハッシュ関数)とは、「元のデータ」を「ハッシュ値」に変換する関数です。
「ハッシュ値」は次の2つの特徴を持ちます。
「元のデータ」が同じ場合、「変換後のハッシュ値」は同じ文字列になる
「変換後のハッシュ値」から「元のデータ」を推測できない

一方向暗号(ハッシュ関数)の特徴・用途は以下のとおりです。

特徴・用途説明
利用用途MAC (Message Authentication Code)
MAC は、(共通鍵をもつ) 検証者がメッセージの内容の変化を検出可能とすることで完全性を確保

完全性を確保する方法は以下の手順
 1. 送信前の元のデータに対してハッシュ関数でハッシュ値を求める
 2. 送信後の元のデータに対してハッシュ関数でハッシュ値を求める
 3. 手順1. 2 のハッシュ値が同じであれば、完全性を確認できます
CIA完全性(送受信したデータに欠損や改ざんが無いかを確認)
暗号化アルゴリズム・MD5
・SHA-1
・SHA-2
・SHA-3

一方向暗号(ハッシュ関数)のサンプルコマンド

■ハッシュ値を生成

echo HelloWorld > data.txt
openssl sha256 < data.txt
89c99d37500be2061f853db3a4da2fcce4c0fc0f2f2b71bc2238acca0967c3b7

上記のハッシュ値は、元のデータ(data.txt)が改ざんされない限り、何回実行しても同じ値になります。

■ハッシュ値で改ざんを検出

echo GoobyeWorld > data.txt
openssl sha256 < data.txt
172666081ff2e826232b1a3ed3bbfcaa9b3056b2a79f8854b562cf17a1b46d13

先程とハッシュ値が異なることがわかります。

共通鍵暗号方式とは

共通鍵暗号とは、自分と通信相手で共通の鍵を利用する方式です。
共通鍵で暗号化されたデータは共通鍵で復号化できます。

つまり、暗号化・復号化できるのは、共通鍵を持つ相手と自分だけです。

共通鍵暗号方式の特徴・用途は以下のとおりです。

特徴・用途説明
利用用途・通信の暗号化
 - 送信するデータの暗号化
 - 受信した暗号化されたデータを復号化
CIA機密性(送信されるデータを盗聴できない)
暗号化アルゴリズム・DES
・AES
・RC4

共通鍵暗号のサンプルコマンド

■共通鍵を使ってデータを暗号化

echo HelloWorld > data.txt
openssl rand 32 -out common_key.txt -base64
openssl enc -e -aes128 -kfile common_key.txt -in data.txt -out encrypt.txt -base64
cat encrypt.txt
U2FsdGVkX18w4ce8ZuMsgmqBsLtYeHuvipXOSqrNHes=

共通鍵(common_key.txt)を利用してデータ(data.txt)を暗号化できました。

■共通鍵を使ってデータを復号化

openssl enc -d -aes128 -kfile common_key.txt -in encrypt.txt -out decrypt.txt -base64
cat decrypt.txt
HelloWorld

暗号化したデータ(encrypt.txt)を復号化できたこと(decrypt.txt)が確認できます。

公開鍵暗号方式とは

公開鍵暗号方式とは、「全世界に公開する公開鍵」と「自分だけが持つ秘密鍵」を利用する方式です。

公開鍵暗号方式は次の3つの利用用途があります。

なお、「通信の暗号化」に対する「共通鍵暗号方式」と「公開鍵暗号方式」の使い分けは以下のとおりです。

用途暗号方式説明
共通鍵の交換公開鍵暗号方式暗号化してない通信で渡せる鍵は公開鍵だけ
- 公開鍵は公開して良い
- 共通鍵は公開してはいけない

受け取った公開鍵と自分の秘密鍵を利用して、共通鍵を生成します。
共通鍵を交換した後の通信共通鍵暗号方式共通鍵暗号方式の方が復号化の計算時間が短いため

通信の暗号化

公開鍵で暗号化したデータは、秘密鍵でのみ復号化できます。

そのため、データを復号化できるのは秘密鍵を持つ自分だけです。

公開鍵暗号で暗号化するサンプルコマンド

■公開鍵でデータを暗号化

echo HelloWorld > data.txt
openssl genrsa > private.key
openssl rsa -in private.key -pubout -out public.key
openssl rsautl -encrypt -pubin -inkey public.key -in data.txt -out data.encrypt
hexdump data.encrypt
0000000 8a 61 e4 d4 5b fd 3f fd 74 bc 66 46 34 03 1e b9
0000010 76 11 a4 49 e0 64 37 37 bc 71 df 9f 80 d7 e7 e8
0000020 5d 74 a4 29 f5 48 1c 1f f2 f6 59 4c 14 9b ac 2d
0000030 bc 5c f4 76 23 c9 4e 03 bd b8 da 7c f9 6e 3e ff
0000040 c9 ba e7 69 01 96 11 0a 06 36 ae f4 d8 14 aa 22
0000050 46 a4 7f be 58 3f 59 bf 17 e1 ad 3b 94 a2 a3 b7
0000060 dd 25 69 38 d1 13 d4 12 d4 03 e9 f1 32 5b 09 04
0000070 ef b3 7e 69 f6 9e f3 1c 1b 83 f0 5d 9b f0 31 e8
0000080 3e 46 b0 0e 67 f3 1b ee c8 6e ec a9 07 99 f1 70
0000090 12 64 cb b6 66 3d 5d c9 a0 14 52 3f 19 5a 0b ad
00000a0 12 3e 58 75 a6 e0 73 84 75 f2 0c 0c 80 13 6c 9a
00000b0 4b 50 84 90 3e bb b8 96 9e 29 28 8e c5 53 85 13
00000c0 d6 25 56 0c a0 e6 2c 02 e7 64 1a ce c2 98 44 94
00000d0 0d a0 71 63 dd 23 16 b2 df 4f a4 1c e7 e2 81 a5
00000e0 94 f5 ed ff 81 5a 2c da d0 7c 5e f2 d4 63 a7 b5
00000f0 65 74 11 ca e7 6a 2a fa 8a d5 7e f6 64 09 99 3f
0000100

■秘密鍵でデータを復号化

openssl rsautl -decrypt -inkey private.key -in data.encrypt
HelloWorld
■公開鍵と対になっていない秘密鍵で復号化した場合
openssl genrsa > private2.key
openssl rsautl -decrypt -inkey private2.key -in data.encrypt
RSA operation error
-->ちゃんとエラーになる。

共通鍵の交換

特徴・用途説明
利用用途共通鍵の交換
CIA機密性(送信されるデータを盗聴できない)
暗号化アルゴリズム・DH
・ECDH
・ECDSA
・ECDHE

共通鍵暗号方式では、共通鍵を持ってない相手と安全に共通鍵を交換できません。

  1. 共通鍵は誰にもバレてはいけないため、相手に渡す際には暗号化する必要があります
  2. 受信した共通鍵を復号化するためには、相手から共通鍵を貰う必要があります
  3. 1に戻る

そこで、公開鍵暗号方式を利用して共通鍵を交換します。

■共通鍵の交換手順は以下のとおりです。(DH アルゴリズム)

  1. 各々が公開鍵を生成し交換します。(x, p は公開情報です。)

公開鍵は盗まれても大丈夫なので暗号化してない通信でも OK です。

2. 貰った公開鍵と持っている秘密鍵で共通鍵を生成します。

以下の計算式を用いると、「全く同じ共通鍵」が生成されることが数学的に証明されてます。

p は巨大な素数
https://github.com/crypto-browserify/diffie-hellman/blob/master/lib/primes.json

詳しくは以下の記事が参考になります。

【図解】素数とDiffie-Hellman鍵交換法 ~わかりやすい計算例とシーケンス,RFCや種類,アルゴリズムについて~
Diffie-Hellman 鍵共有とは IP ネットワーク通信において、暗号化による機密性と認証による通信相手の正当性を担保する技術として「IPsec」や「SSL/TLS」、「SSH」等があります。 この 3 つのプロトコルは用途によって
Diffie-Hellman鍵交換入門 - Qiita
鍵交換とは 例えば、zipを作成するときにはパスワードを設定しますね。これは、zip作成者がパスワードを知っている人だけが中身を読めるようにするためのものです。 我々がふだん使っているセキュアな…

電子署名

特徴・用途説明
利用用途電子署名
CIA認証
(通信相手が正しいことを確認可能)
暗号化アルゴリズム・RSA
・ECDSA
・EdDSA
・ECC

秘密鍵で暗号化したデータは、公開鍵で復号化可能です。

公開鍵で復号化可能なデータを生成できる人は、「秘密鍵を持ってる人」だけです。

そのため、「秘密鍵による暗号化」を「電子署名」として使うことができます。

公開鍵暗号で電子署名をするサンプルコマンド

■秘密鍵でデータの電子署名を作成

echo HelloWorld > data.txt
openssl genrsa > private.key
openssl rsa -in private.key -pubout -out public.key
openssl dgst -sha256 -sign private.key data.txt > sign.sig

電子署名は以下の手順でハッシュ値を暗号化したものです。

  1. ハッシュ関数 SHA256 を利用して、data.txt のハッシュ値を求める
  2. 秘密鍵を利用して、1で生成したハッシュ値を暗号化する←これが電子署名
hexdump sign.sig
0000000 9b 1e 19 eb 53 80 d9 8d d7 bf d7 fb 4a ca 89 da
0000010 9a 20 8e 46 13 98 c9 9f 72 28 0b d6 06 24 27 88
0000020 a8 d2 49 b6 15 23 f7 4f ac 71 ca 82 cc 0d 89 b8
0000030 35 fc 86 8f d3 fa 9d 5d 8a 14 cb d7 4e 5b 7f 5c
0000040 a3 f8 74 b9 57 ec 68 17 1d 20 44 b2 fe 67 23 13
0000050 df 1b 65 46 b8 d7 ac 27 c3 5e e5 e1 4a 42 35 c5
0000060 73 31 54 99 92 db ff 02 c3 43 78 f5 21 73 66 ac
0000070 55 3f c5 6d 66 31 5d 23 51 4e d8 ca 67 ac 2b 74
0000080 a4 68 a2 34 60 ec a8 72 17 e2 cd 74 dd 76 5a 0b
0000090 3f 2f a8 8a d7 5a f1 4f 76 42 ef 1f 16 ad 73 9d
00000a0 ab 2c 6e 99 fa 04 bf 72 ce 34 d9 2d 5d 1e d3 50
00000b0 88 15 e8 6f 1c 73 5c 6a ba ba 44 9c fd 91 17 d6
00000c0 d1 b1 f5 fc 16 2c b9 0c 45 09 a8 7a ad b6 46 dd
00000d0 be d3 8e f8 74 3e 21 21 78 fe 44 a5 a6 3f e7 ee
00000e0 bc 86 ce 08 a6 dd b6 94 09 42 b9 5c 17 9b c6 91
00000f0 62 2f 79 1b 1b 15 1c 85 d0 26 b5 e9 36 e1 93 f3
0000100

■公開鍵でデータの電子署名を検証

openssl dgst -sha256 -verify public.key -signature sign.sig data.txt
Verified OK

以下の2つが一致すれば「Verified OK」となります。

  • 公開鍵で、電子署名(sign.sig)を復号化した値を求める
  • ハッシュ関数 SHA256で、元のデータ(data.txt)のハッシュ値を求める
スポンサーリンク

Cipher Suite(暗号スイート)

Cipher Suite(暗号スイート)とは、サーバーとクライアント間で暗号通信を行う際に利用する以下の4つのアルゴリズムの組み合わせのことです。
一方向暗号アルゴリズム(Mac - Message Authentication Code
共通鍵暗号アルゴリズム(Enc - Encryption
公開鍵暗号アルゴリズム
 - 鍵交換アルゴリズム(Kx - Key Exchange
 - 認証アルゴリズム(Au - Authentication

要するに、最初で示した以下の各暗号方式で利用する「暗号化アルゴリズム」を決めます。

暗号方式CIA利用用途暗号化アルゴリズム
一方向暗号(Mac)完全性メッセージの変化を検出
- MAC(Message Authentication Code)
・MD5
・SHA-1
・SHA-2
・SHA-3
・AEAD
共通鍵暗号(Enc)機密性通信の暗号化
- 公開鍵暗号より高速なため
・DES
・AES
・RC4
公開鍵暗号機密性共通鍵の交換(Kx)
- 公開鍵は盗まれても問題無いため
- 共通鍵は盗まれると大問題
・DH
・ECDH
・ECDSA
・ECDHE
認証
電子署名(Au)
・RSA
・ECDSA
・EdDSA
・ECC

Cipher Suite(暗号スイート)の確認

利用可能な Cipher Suite を確認するには、以下のコマンドを利用します。

openssl ciphers -v 'ALL'
ECDHE-RSA-AES256-GCM-SHA384 TLSv1.2 Kx=ECDH Au=RSA Enc=AESGCM(256) Mac=AEAD
ECDHE-ECDSA-AES256-GCM-SHA384 TLSv1.2 Kx=ECDH Au=ECDSA Enc=AESGCM(256) Mac=AEAD
ECDHE-RSA-AES256-SHA384 TLSv1.2 Kx=ECDH Au=RSA Enc=AES(256) Mac=SHA384
(中略)

例えば3行目の "ECDHE-RSA-AES256-SHA384 TLSv1.2 Kx=ECDH Au=RSA Enc=AES(256) Mac=SHA384" は以下の意味を表します。

暗号方式利用するアルゴリズム
公開鍵暗号共通鍵の交換(Kx)ECDH
公開鍵暗号電子署名(Au)RSA
共通鍵暗号(Enc)AES(256)
一方向暗号(Mac)AEAD