Follow #ソシム販売部Twitterアイコン

  

Pythonでいかにして暗号を破るか古典暗号解読プログラムを自作する本

Al Sweigart/翻訳:IPUSIRON

『退屈なことはPythonにやらせよう』の著者Al Sweigart氏による、Pythonと暗号の超実践的入門書!

定価
3,960円(本体価格 3,600円)
  • 発売日
    2020年12月22日
  • 判型/ページ数
    B5変型判/520
  • ISBN
    978-4-8026-1216-6

この書籍を問い合わせる

キーワード:
/ / / / / / / / / / / / / / / / / / /

暗号を用いた秘密のメッセージの作り方を指南する、初心者向けの書籍はたくさんあります。また、暗号の解読法を指南する、初心者向けの書籍はいくつか存在します。しかし、暗号を解読するためのプログラミングを指南する、初心者向けの書籍は皆無といえるでしょう。本書はそのギャップを埋めるためのものです。 本書は、暗号、暗号解読、暗号学について興味を持っている人のためのものです。本書の暗号(23章と24章の公開鍵暗号を除く)はすべて古典的なものであり、ノートPCの計算能力でも解読できます。現在の組織や個人はこうした古典暗号を使用しません。しかし、古典暗号を通じて、暗号を構成する土台や、脆弱な暗号の解読法について学べます。

追加のオンラインリソース

原文Additional Online Resources
原著者Webサイトhttps://inventwithpython.com/cracking/
原著出版社によるサポートページhttps://nostarch.com/crackingcodes/

第1章

モールス符号
https://ja.wikipedia.org/wiki/モールス符号
オンライン暗号ホイール
https://inventwithpython.com/cipherwheel/
負数の加算と減算(英文、原著者のサイトにリンク)
https://inventwithpython.com/chapter12.html#_Toc405145134

第2章

一般的なPythonのエラーメッセージ(英文、原著者のブログ記事にリンク)
https://inventwithpython.com/blog/2012/07/09/16-common-python-runtime-errors-beginners-find/

第3章

オンライン差分ツール(原著者運営)
https://inventwithpython.com/cracking/diff/
日本語版サイトで配布されるソースコードはコメントを訳出しています。 オンライン差分ツールで差分を確認する際はご注意ください。

第5章

Pyperclipモジュール(原著者が作成したモジュール)
https://inventwithpython.com/pyperclip.py

第7章

helloFunction.pyの実行をトレースする(外部サイトpythontutor.comへのリンク)
https://goo.gl/KzXaRr
transpositionEncrypt.pyの実行をトレースする(外部サイトpythontutor.comへのリンク)
https://goo.gl/b5nTeu

第9章

random.SystemRandom().randint()関数についての情報(Python 3公式ドキュメント)
https://docs.python.org/3/library/random.html#random.SystemRandom

第10章

Pythonのdatetimeモジュールについての情報
https://automatetheboringstuff.com/chapter15/

第13章

拡張ユークリッドのアルゴリズム
https://ja.wikipedia.org/wiki/ユークリッドの互除法

第16章

単一換字式暗号の鍵の総数は、26×25×24×…×1または26!(「26の階乗」)または403,291,461,126,605,635,584,000,000です。これは、単一換字式暗号の鍵がアルファベットの26文字をランダムに並べたものであることに由来します。鍵を作成する場合、鍵の最初の文字は、26文字の中から選べます。鍵の2番目の文字は、残りの25文字の中から選べます。鍵の3番目の文字は24文字の中から1つを選べます。つまり、可能な組み合わせの数は、26から1までの数字の積である403,291,461,126,605,635,584,000,000になります。

第17章

正規表現についての詳細情報(英文、著者が執筆した書籍の公開原稿へのリンク)
https://automatetheboringstuff.com/chapter7/

第23章

暗号化ソフトウェアの一覧(英文)
https://en.wikipedia.org/wiki/Comparison_of_disk_encryption_software
暗号通貨についての詳細情報
https://ja.wikipedia.org/wiki/暗号通貨
認証と公開鍵基盤についての詳細情報
https://ja.wikipedia.org/wiki/公開鍵基盤
匿名Webサーフィンについての詳細情報(英文)
https://www.torproject.org/

第0章 導入

0.1 本書が想定する読者
0.2 本書の内容
0.3 本書の使い方
0.3.1 ソースコードの入力
0.3.2 タイプミスの確認
0.3.3 本書のコーディング規約
0.3.4 オンライン・リソース
0.4 Pythonのダウンロードとインストール
0.4.1 Windowsの場合
0.4.2 macOSの場合
0.4.3 Ubuntuの場合
0.5 pyperclip.pyのダウンロード
0.6 IDLEを開始する
0.7 まとめ

第1章 紙製の暗号ツールをつくる

1.1 暗号学とは何か?
1.2 符号 vs. 暗号
1.3 シーザー暗号
1.3.1 暗号ホイール
1.3.2 暗号ホイールで暗号化する
1.3.3 暗号ホイールで復号する
1.3.4 算術による暗号化と復号
1.4 二重暗号化はなぜうまくいかないのか
1.5 まとめ (練習問題)

第2章 対話型シェルのプログラミング

2.1 いくつかの簡単な数式
2.1.1 整数と浮動小数点数
2.1.2 式
2.1.3 演算の順序
2.1.4 式の評価
2.2 変数への値の代入
2.2.1 変数の上書き
2.2.2 変数名
2.3 まとめ (練習問題)

第3章 文字列とプログラムの作成

3.1 文字列を用いてテキストを操作する
3.1.1 +演算子による文字列の連結
3.1.2 *演算子を使った文字列の複製
3.1.3 インデックスを使用して文字列から文字を取得する
3.2 print()関数で値を出力する
3.3 エスケープ文字を表示する
3.4 一重引用符と二重引用符
3.5 IDLEのファイルエディターでプログラムを書く
3.6 “Hello, World!”プログラムのソースコード
3.7 オンライン差分ツールでソースコードを確認する
3.8 プログラムにアクセスするためにIDLEを使用する
3.8.1 プログラムを保存する
3.8.2 プログラムを実行する
3.8.3 保存済みのプログラムを開く
3.9 “Hello, World!”プログラムがどのように動作するのか
3.9.1 コメント
3.9.2 ユーザーへの指示を表示する
3.9.3 ユーザーからの入力を受け取る
3.9.4 プログラムを終了する
3.10 まとめ (練習問題)

第4章 逆暗号

4.1 逆暗号プログラムのソースコード
4.2 逆暗号プログラムの実行例
4.3 コメントと変数を設定する
4.4 文字列の長さを調べる
4.5 whileループ
4.5.1 bool型
4.5.2 比較演算子
4.5.3 ブロック
4.5.4 whileループ文
4.5.6 文字列の成長
4.6 input()プロンプトでプログラムを改善する
4.7 まとめ(練習問題)

第5章 シーザー暗号

5.1 シーザー暗号プログラムのソースコード
5.2 シーザー暗号プログラムの実行例
5.3 モジュールのインポートと変数の設定
5.4 定数と変数
5.5 forループ文
5.5.1 forループの例
5.5.2 whileループとforループの等価性
5.6 if文
5.6.1 if文の例
5.6.2 else文
5.6.3 elif文
5.7 in演算子とnot in演算子
5.8 find()文字列メソッド
5.9 シンボルの暗号化と復号
5.9.1 ラップアラウンドの処理
5.9.2 シンボルセットに含まれないシンボルに対する処理
5.10 変換された文字列の表示とコピー
5.11 他のシンボルを暗号化する
5.12 まとめ(練習問題)

第6章 総当たり攻撃によるシーザー暗号の解読

6.1 シーザー暗号を解読するプログラムのソースコード
6.2 シーザー暗号の解読プログラムの例
6.3 変数を設定する
6.4 range()関数でループする
6.5 メッセージを復号する
6.6 鍵と復号したメッセージを表示するために文字列書式化を使う
6.7 まとめ(練習問題)

第7章 転置式暗号で暗号化する

7.1 転置式暗号の仕組み
7.1.1 手動でメッセージを暗号化する
7.1.2 暗号化プログラムを作成する
7.2 転置式暗号プログラムのソースコード
7.3 転置式暗号プログラムの実行例
7.4 def文を使って独自の関数を作成する
7.4.1 パラメーターを持ち、引数を取る関数を定義する
7.4.2 関数内でのみに存在するパラメーターを変更する
7.4.3 main()関数を定義する
7.5 引数として鍵とメッセージを渡す
7.6 リスト型
7.6.1 リスト内の要素に再代入する
7.6.2 リストのリスト
7.6.3 リストに対してlen()とin演算子を使用する
7.6.4 +および*演算子を使った、リストの連結と複製
7.7 転置式暗号の暗号化のアルゴリズム
7.8 拡張代入演算子
7.9 messageを通じてcurrentIndexを移動する
7.10 join()文字列メソッド
7.11 返り値とreturn文
7.11.1 return文の例
7.11.2 暗号文を返す
7.12 変数__name__
7.13 まとめ(練習問題)

第8章 転置式暗号を復号する

8.1 紙上で転置式暗号を復号する方法
8.2 転置式暗号の復号プログラムのソースコード
8.3 転置式暗号の復号プログラムの実行例
8.4 モジュールのインポートとmain()関数の設定
8.5 鍵を使用してメッセージを復号する
8.5.1 round()、math.ceil()、math.floor()関数
8.5.2 decryptMessage()関数
8.5.3 論理演算子
8.5.4 列と行の変数を調整する
8.6 main()関数を呼び出す
8.7 まとめ(練習問題)

第9章 プログラムテスト用プログラムを作成する

9.1 転置式暗号のテストプログラムのソースコード
9.2 転置式暗号のテストプログラムの実行例
9.3 モジュールをインポートする
9.4 疑似乱数を作成する
9.5 ランダムな文字列を作成する
9.5.1 文字列をランダムな回数分複製する
9.5.2 リストの変数は参照を使用する
9.5.3 参照を渡す
9.5.4 copy.deepcopy()を使用してリストを複製する
9.5.5 random.shuffle()関数
9.5.6 文字列をランダムに撹拌する
9.6 各メッセージをテストする
9.7 暗号の動作確認とプログラムの終了
9.8 main()関数を呼び出す
9.9 テストプログラムをテストする
9.10 まとめ(練習問題)

第10章 ファイルの暗号化と復号

10.1 プレーンテキストファイル
10.2 転置式ファイル暗号プログラムのソースコード
10.3 転置式ファイル暗号プログラムの実行例
10.4 ファイルを操作する
10.4.1 ファイルを開く
10.4.2 ファイルへの書き込みとクローズ
10.4.3 ファイルから読み込む
10.5 main()関数を設定する
10.6 ファイルの存在を確認する
10.6.1 os.path.exists()関数
10.6.2 os.path.exists()関数で入力ファイルが存在するかどうかを確認する
10.7 文字列メソッドを使用してユーザー入力をより柔軟にする
10.7.1 upper()、lower()、title()文字列メソッド
10.7.2 startswith()とendswith()文字列メソッド
10.7.3 文字列メソッドをプログラムで使用する
10.8 入力ファイルを読み込む
10.9 暗号化や復号のための時間を計測する
10.9.1 timeモジュールとtime.time()関数
10.9.2 プログラムでtime.time()関数を使う
10.10 出力ファイルを書き込む
10.11 main()関数を呼び出す
10.12 まとめ(練習問題)

第11章 プログラムによる英語の検出

11.1 コンピュータは英語であることをどのようにしてわかるのか?
11.2 英語検知モジュールのソースコード
11.3 英語検知モジュールの動作例
11.4 指示と定数の設定
11.5 辞書型
11.5.1 辞書とリストの違い
11.5.2 辞書の要素を追加・変更する
11.5.3 辞書に対してlen()関数を使用する
11.5.4 辞書と一緒にin演算子を使用する
11.5.5 リストより辞書の方が高速に要素を検索する
11.5.6 辞書と一緒にループを使用する
11.6 辞書ファイルを実装する
11.6.1 split()メソッド
11.6.2 辞書ファイルを個々の単語に分割する
11.6.3 辞書データを返す
11.7 メッセージ内の英単語を数える
11.7.1 ゼロ除算エラー
11.7.2 英単語と一致したものを数える
11.7.3 float()、int()、str()関数と整数の除算
11.7.4 メッセージ内の英単語の割合を求める
11.8 非アルファベット文字を削除する
11.8.1 append()リストメソッド
11.8.2 アルファベット文字だけの文字列を作成する
11.9 英単語を検出する
11.9.1 デフォルト引数を使用する
11.9.2 割合を計算する
11.10 まとめ(練習問題)

第12章 転置式暗号を解読する

12.1 転置式暗号解読プログラムのソースコード
12.2 転置式暗号解読プログラムの実行例
12.3 モジュールをインポートする
12.4 三重引用符を含む複数行の文字列
12.5 メッセージを解読した結果を表示する
12.6 解読されたメッセージを取得する
12.6.1 strip()文字列メソッド
12.6.2 strip()文字列メソッドを適用する
12.6.3 メッセージの解読の失敗
12.7 main()関数を呼び出す
12.8 まとめ(練習問題)

第13章 アフィン暗号のためのモジュラー算術モジュール

13.1 モジュラー算術
13.2 モジュラー演算子
13.3 最大公約数を計算するための約数を見つける
13.4 多重代入
13.5 GCDを求めるユークリッドのアルゴリズム
13.6 乗法暗号とアフィン暗号の仕組みの理解
13.6.1 妥当な乗法鍵を選択する
13.6.2 アフィン暗号による暗号化
13.6.3 アフィン暗号の復号
13.6.4 モジュラー逆数を求める
13.6.5 整数除算演算子
13.7 Cryptomathモジュールのソースコード
13.8 まとめ(練習問題)

第14章 アフィン暗号のプログラミング

14.1 アフィン暗号プログラムのソースコード
14.2 アフィン暗号プログラムの実行例
14.3 モジュール、定数、およびmain()関数を設定する
14.4 鍵の計算と検証
14.4.1 タプル型
14.4.2 脆弱な鍵を確認する
14.4.3 アフィン暗号の鍵の総数はいくつか?
14.5 暗号化関数を作成する
14.6 復号関数を作成する
14.7 ランダムな鍵を生成する
14.8 main()関数を呼び出す
14.9 まとめ(練習問題)

第15章 アフィン暗号を解読する

15.1 アフィン暗号解読プログラムのソースコード
15.2 アフィン暗号解読プログラムの実行例
15.3 モジュール、定数、およびmain()関数を設定する
15.4 アフィン暗号の解読関数
15.4.1 指数演算子
15.4.2 鍵の総数を計算する
15.4.3 continue文
15.4.4 コードをスキップするためにcontinueを使う
15.5 main()関数を呼び出す
15.6 まとめ(練習問題)

第16章 単一換字式暗号のプログラミング

16.1 単一換字式暗号の仕組み
16.2 単一換字式暗号プログラムのソースコード
16.3 単一換字式暗号プログラムの実行例
16.4 モジュール、定数、およびmain()関数を設定する
16.5 sort()リストメソッド
16.6 ラッパー関数
16.7 translateMessage()関数
16.7.1 isupper()とislower()文字列メソッド
16.7.2 isupper()で大文字を保持する
16.8 ランダムな鍵を生成する
16.9 main()関数を呼び出す
16.10 まとめ(練習問題)

第17章 単一換字式暗号を解読する

17.1 単語パターンを用いて解読する
17.1.1 単語パターンを検索する
17.1.2 復号文字の候補を検索する
17.2 解読プロセスの概要
17.3 単語パターンのモジュール
17.4 単一換字式暗号解読プログラムのソースコード
17.5 単一換字式暗号解読プログラムの実行例
17.6 モジュールと定数を設定する
17.7 正規表現で文字を検索する
17.8 main()関数を設定する
17.9 ユーザーに解読結果を表示する
17.10 暗号文字マッピングを作成する
17.10.1 空のマッピングを作成する
17.10.2 マッピングに文字を追加する
17.10.3 2つのマッピングを交差させる
17.10.4 文字マッピングのヘルパー関数の仕組み
17.10.5 マッピングで解読された文字を識別する
17.10.6 removeSolvedLetterFromMapping()関数をテストする
17.11 hackSimpleSub()関数
17.11.1 replace()文字列メソッド
17.11.2 メッセージを復号する
17.11.3 対話型シェルで復号する
17.12 main()関数を呼び出す
17.13 まとめ(練習問題)

第18章 ヴィジュネル暗号のプログラミング

18.1 ヴィジュネル暗号で複数の文字鍵を使用する
18.1.1 長いヴィジュネル暗号の鍵はより安全になる
18.1.2 辞書式攻撃を防ぐ鍵を選択する
18.2 ヴィジュネル暗号プログラムのソースコード
18.3 ヴィジュネル暗号プログラムの実行例
18.4 モジュール、定数、およびmain()関数を設定する
18.5 List-Append-Joinプロセスで文字列を作成する
18.6 メッセージを暗号化・復号する
18.7 main()関数を呼び出す
18.8 まとめ(練習問題)

第19章 頻度分析

19.1 テキスト内の文字の頻度を分析する
19.2 文字の頻度とのマッチング
19.2.1 単一換字式暗号の頻度マッチスコアを計算する
19.2.2 転置式暗号の頻度マッチスコアを計算する
19.2.3 ヴィジュネル暗号を頻度分析する
19.3 文字の頻度分析のためのソースコード
19.4 ETAOIN順で文字を保持する
19.5 メッセージ内の文字をカウントする
19.6 タプルの最初の要素を取得する
19.7 頻度によって文字を並び替える
19.7.1 getLetterCount()で文字をカウントする
19.7.2 出現回数と文字リストの辞書を作成する
19.7.3 文字リストをETAOINの逆順で並び替える
19.7.4 出現回数で辞書リストをソートする
19.7.5 ソートされた文字たちのリストを作成する
19.8 メッセージの頻度マッチスコアを計算する
19.9 まとめ(練習問題)

第20章 ヴィジュネル暗号を解読する

20.1 ヴィジュネル暗号を辞書式攻撃する
20.2 ヴィジュネル暗号の辞書式攻撃プログラムのソースコード
20.3 ヴィジュネル暗号の辞書式攻撃プログラムの実行例
20.4 ヴィジュネル暗号の辞書式攻撃プログラムについて
20.5 カシスキー検査で鍵長を発見する
20.5.1 反復を見つける
20.5.2 スペーシングの因数を取得する
20.5.3 文字列からN番目の文字を取得する
20.5.4 頻度分析でサブ鍵を解読する
20.5.5 鍵の候補で総当たり攻撃する
20.6 ヴィジュネル暗号解読プログラムのソースコード
20.7 ヴィジュネル暗号解読プログラムの実行例
20.8 モジュールのインポートとmain()関数の設定
20.9 反復を見つける
20.10 スペーシングの因数を計算する
20.10.1 set()関数で重複を削除する
20.10.2 重複する因数の削除とリストのソート
20.10.3 もっとも共通する因数を探す
20.11 もっとも可能性の高い鍵長を見つける
20.11.1 extend()リストメソッド
20.11.2 辞書repeatedSeqSpacingsを拡張する
20.11.3 factorsByCountから因数を取得する
20.12 同じサブ鍵で暗号化された文字を取得する
20.13 可能性が高い鍵長で復号を試みる
20.13.1 print()のためのendキーワード引数
20.13.2 サイレントモードでのプログラムの実行、またはユーザーへの情報の表示
20.13.3 サブ鍵の候補の組み合わせを得る
20.13.4 元の大文字・小文字の書式を維持した復号結果を表示する
20.14 解読したメッセージを返す
20.14.1 鍵の候補が見つかったときにループを中断する
20.14.2 他のすべての鍵長で総当たり攻撃する
20.15 main()関数を呼び出す
20.16 解読プログラムの定数を修正する
20.17 まとめ(練習問題)

第21章 ワンタイムパッド暗号

21.1 解読できないワンタイムパッド暗号
21.1.1 鍵長をメッセージ長と同じにする
21.1.2 鍵を真にランダムにする
21.1.3 ツータイムパッドを避ける
21.1.4 ツータイムパッド暗号はなぜヴィジュネル暗号なのか
21.2 まとめ(練習問題)

第22章 素数の検索と生成

22.1 素数とは何か?
22.2 素数モジュールのソースコード
22.3 素数モジュールの実行例
22.4 試し割りアルゴリズムの仕組み
22.5 試し割りアルゴリズムによる素数テストを実装する
22.6 エラトステネスのふるい
22.7 エラトステネスのふるいで素数を生成する
22.8 Rabin-Millerの素数テストのアルゴリズム
22.9 巨大な素数を見つける
22.10 巨大な素数を生成する
22.11 まとめ(練習問題)

第23章 公開鍵暗号の鍵を生成する

23.1 公開鍵暗号
23.2 認証の問題
23.2.1 デジタル署名
23.2.2 中間者攻撃に注意する
23.3 公開鍵と秘密鍵を生成するためのステップ
23.4 公開鍵生成プログラムのソースコード
23.5 鍵生成プログラムの実行例
23.6 main()関数を作成する
23.7 generateKey()関数を使用して鍵を生成する
23.7.1 eの値を計算する
23.7.2 dの値を計算する
23.7.3 鍵を返す
23.8 makeKeyFiles()関数で鍵ファイルを作成する
23.9 main()関数を呼び出す
23.10 ハイブリッド暗号方式
23.11 まとめ(練習問題)

第24章 公開鍵暗号のプログラミング

24.1 公開鍵暗号の仕組み
24.1.1 ブロックを作成する
24.1.2 文字列をブロック値に変換する
24.1.3 公開鍵暗号における暗号化と復号の数学的理論
24.1.4 ブロック値を文字列に変換する
24.1.5 なぜ公開鍵暗号を解読できないのか?
24.2 公開鍵暗号プログラムのソースコード
24.3 公開鍵暗号プログラムの実行例
24.4 プログラムを設定する
24.5 プログラムが暗号化または復号するかどうかを決定する方法
24.6 getBlocksFromText()で文字列をブロックに変換する
24.6.1 min()関数とmax()関数
24.6.2 ブロックをblockIntに格納する
24.7 復号のためにgetTextFromBlocks()を使う
24.7.1 insert()リストメソッドを使う
24.7.2 メッセージリストを結合して単一の文字列にする
24.8 encryptMessage()関数を作成する
24.9 decryptMessage()関数を作成する
24.10 公開鍵や秘密鍵の鍵ファイルから鍵を読み込む
24.11 ファイルに暗号文を書き込む
24.12 ファイルを復号する
24.13 main()関数を呼び出す
24.14 まとめ

付録 Pythonコードのデバッグ

A.1 デバッガーの仕組み
A.2 逆暗号プログラムをデバッグする
A.3 ブレークポイントを設定する
A.4 まとめ

索引

ダウンロードデータ

本書で解説したサンプルデータをダウンロードできます。
なお、使用方法などに関しては、必ず書籍の該当箇所をご確認の上、ご利用ください。
ダウンロード後、解凍したファイル内に「readme.txt」ファイルなどが含まれる場合は、使用前にこちらもご確認ください。

こちらでは、本書で解説したソースコード一式、および練習問題とその解答をダウンロードしていただけます。
下記の説明をよくご確認のうえ、ご利用ください。

ソースコード

「ソースコード一式」はZIPでアーカイブされており、pyperclip.pyが含まれています。各ソースコードのコメントは、日本語に翻訳されています。各ソースコードのライセンスは、オリジナルのソースコードのライセンスに準じます。オリジナルのソースコードは、著者のサイトから入手可能です。著者が提供するオンライン差分ツールを利用する場合は、オリジナルのソースコードの方が、都合がよい場合がございます。

練習問題と解答

練習問題とその解答はPDF形式で配布します。著者の解答を補筆しているため、著者の解答とは異なる点にご注意ください。また、解答の理解を補足するPythonプログラムを同梱しています。解答ファイルの閲覧にはAdobe Acrobat Readerなどのソフトウェアが必要です。オリジナルの問題は原著出版社のサイト、あるいはオリジナルのソースコード一式に含まれるSolutionsForPracticeProblems.htmlで確認できます。

正誤情報

お問い合わせ

本書に関するお問い合わせは、下記のボタンをクリックしてお問い合わせフォームよりお問い合わせください。

この書籍を問い合わせる

[ この書籍をシェアする ]

関連する書籍

カテゴリから本を探す

シリーズから本を探す

本を探す