セキュリティ基礎コース3/8
簡易的な暗号化について
こちらでは、Pythonを使った暗号化について解説します。
シナリオ内で登場する関数などについて説明していきたいと思います。
こちらの記事では、実際にシナリオ内で使用されているスクリプトについて解説しています。
まだ問題を解いていない方にとってはネタバレになります!
まずは一度トライしてから解説を読むことをオススメします!
level_1.py
まずは、1問目で登場するlevel_1.pyから見ていきましょう。
==================================================
【与えられている手がかり】
- Pythonスクリプト(level_1.py)
- 暗号文(
sfeuiyC;iAc89895j78>6b:5h8j<8=89:;95j@9
)
==================================================
text = "secret=xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
encrypted_text = ""
for i, v in enumerate(text):
encrypted_text += chr(ord(v)+(i % 10))
print(encrypted_text)
こちらのスクリプトには、ある平文を暗号化するための処理が書かれています。
暗号化と復号は表裏一体なものですので、暗号化と逆の処理を実行すれば復号できます。
ここでは、textが平文であり、encrypted_textはその名の通り暗号文です。
今回は暗号文が与えられており、平文を求める問題であるため、初めの2行は以下のようになります。
encrypted_text = "sfeuiyC;iAc89895j78>6b:5h8j<8=89:;95j@9"
text = ""
次に、for文で繰り返し処理が展開されます。
ここでは、
enumerate()という関数を用いて
for i, v in enumerate(encrypted_text):
text += chr(ord(v)-(i % 10))
最後に復号した平文を出力すれば完成です。
完成したスクリプトは以下のようになります。
1 | encrypted_text = "sfeuiyC;iAc89895j78>6b:5h8j<8=89:;95j@9"
2 | text= ""
3 |
4 | for i, v in enumerate(encrypted_text):
5 | text += chr(ord(v)-(i % 10))
6 |
7 | print(text)
base64によるエンコード
つづいて、2問目を見ていく前に、もう少し簡単なスクリプトを例にbase64を使ったエンコード/デコードについて理解していきましょう。
(※なお、base64によるエンコードの手順に関しましては、**こちらの記事**をご覧ください。)
実際にスクリプトを見てみましょう。
# encoding.pyというPythonファイルを作成します。
$ vi encoding.py
=============================================
1 | import base64
2 |
3 | text = "Kryptonian"
4 | text_bytes = text.encode('ascii')
5 | base64_bytes = base64.b64encode(text_bytes)
6 | base64_text = base64_bytes.decode('ascii')
7 |
8 | print(base64_text)
=============================================
# encoding.pyを実行してみます。(textをエンコードした文字列が出力されます。)
$ python encoding.py
S3J5cHRvbmlhbg==
それでは、スクリプトで行っている処理を順を追って解説していきます。
-
まずはじめに、Pythonにはbase64モジュールがあります。
base64によるエンコード/デコードを行う際には、このモジュールをインポートします。
1 | import base64
-
次に、
text
にエンコードしたい文字列を代入します。今回は、”Kryptonian”という文字列を代入しました。
3 | text = "Kryptonian"
-
つづいて、ASCIIコード表にもとづいて
text
をバイナリに変換したものをtext_bytes
に代入しています。文字は、それぞれ8bitのバイナリに変換されます。4 | text_bytes = text.encode('ascii') -------------------------------------- # 実際には以下のように変換されています。 "Kryptonian" => { 01001011011100100111100101110000011101000110111101101110011010010110000101101110 }
-
さらに、
text_bytes
をbase64でエンコードし、base64_bytes
に代入します。ここでは、base64モジュールのb64encode()関数を使用してエンコードします。
b64encode()関数は、第一引数でバイナリを受け取って、別の形式に変換します。
ここでは、8bitのバイナリ(
text_bytes
)を受け取りますが、その羅列を6bitごとに区切ります。これによって、”Kryptonian”ではない文字列のバイナリになります。※実際に
text_bytes
とbase64_bytes
をPrint()関数で出力してみると、以下のような結果になります。$ python encoding.py b'Kryptonian' b'S3J5cHRvbmlhbg=='
出力結果の文字列の頭には
b
が付いています。これは、バイナリ(binary)のb
です。b'Kryptonian'
は、”Kryptonian”という文字列のバイナリで、b'S3J5cHRvbmlhbg=='
は、”S3J5cHRvbmlhbg==”という文字列のバイナリです。つまり、
text_bytes
とbase64_bytes
に代入されているバイナリが別のバイナリとなっていることが分かります。5 | base64_bytes = base64.b64encode(text_bytes) ------------------------------------------------ # 実際には以下のように変換されています。 # バイナリを6bitごとに区切ります。 { 01001011, 01110010, 01111001, 01110000, 01110100, 01101111, 01101110, 01101001, 01100001, 01101110 } => { 010010, 110111, 001001, 111001, 011100, 000111, 010001, 101111, 011011, 100110, 100101, 100001, 011011, 10 } # 末尾が10となっており4bit分の余りがあるので、0で埋め合わせて6bitちょうどにします。 { 010010,11....011, ****10**0000 }**
-
最後に、バイナリをASCIIコード表にもとづいて文字列に変換したものを
base64_text
に代入します。最終的には
base64_text
を出力します。6 | base64_text = base64_bytes.decode('ascii') 7 | 8 | print(base64_text) ----------------------------------------------- # ここでは、バイナリから文字列への変換が行われています。 { 010010, 110111, 001001, 111001, 011100, 000111, 010001, 101111, 011011, 100110, 100101, 100001, 011011, 100000 } => "S3J5cHRvbmlhbg=="
次に、base64でデコードするスクリプトを見てみましょう。
暗号化/復号と同じように、エンコードの逆の処理をすればデコードすることができますので、ここではエンコードのように細かい説明はしません。
# decoding.pyを作成します。
vi decoding.py
=============================================
import base64
base64_text = 'S3J5cHRvbmlhbg=='
base64_bytes = base64_text.encode('ascii')
text_bytes = base64.b64decode(base64_bytes)
text = text_bytes.decode('ascii')
print(text)
=============================================
# decoding.pyを実行してみます。(base64_textをデコードした文字列が出力されます。)
python decoding.py
Kryptonian
ここまで見てきたように、プログラムがどのように処理を進めているのかを理解できれば、エンコードするためのスクリプトをデコードするためのスクリプトに書き換えることもできます。
問題を解くためには、十分な画面サイズのPC環境をご利用下さい。