Problem 59 - XOR暗号解読

はじめての暗号解読に挑んでみる。


Problem 59 - PukiWiki

(訳者注: 文字コードの説明は適当です) 各文字はそれぞれ一意のコードに割り当てられている. よく使われる標準としてASCII (American Standard Code for Information Interchange) がある. ASCIIでは, 大文字A = 65, アスタリスク (*) = 42, 小文字k = 107というふうに割り当てられている.

モダンな暗号化の方法として, テキストファイルの各バイトをASCIIに変換し, 秘密鍵から計算された値とXORを取るという手法がある. XOR関数の良い点は, 暗号化に用いたのと同じ暗号化鍵でXORを取ると平文を復号できる点である. 65 XOR 42 = 107であり, 107 XOR 42 = 65である.

破られない暗号化のためには, 鍵は平文と同じ長さのランダムなバイト列でなければならない. ユーザーは暗号文と暗号化鍵を別々の場所に保存する必要がある. また, もし一方が失われると, 暗号文を復号することは不可能になる.

悲しいかな, この手法はほとんどのユーザーにとって非現実的である. そこで, 鍵の変わりにパスワードを用いる手法が用いられる. パスワードが平文より短ければ (よくあることだが), パスワードは鍵として繰り返し用いられる. この手法では, 安全性を保つために十分長いパスワードを用いる必要があるが, 記憶するためにはある程度短くないといけない.

この問題での課題は簡単になっている. 暗号化鍵は3文字の小文字である. cipher1.txtは暗号化されたASCIIのコードを含んでいる. また, 平文はよく用いられる英単語を含んでいる. この暗号文を復号し, 平文のASCIIでの値の和を求めよ

要するにXOR暗号を解読せよって事。


結構ハマりポイント多数。

  • abcというパスワードがあったら、1文字目をaでxor。2文字目をbでxor。3文字目をcでxor。
    • という感じ。3回xorしてたよ・・・あんま意味なし。
  • 記号、数字を含むけど、あんまり記号を含みすぎるとどんなパスワードでもマッチしちゃって、解読できない。

結構大変でした。


方針は,

  • とりあえず3つに分けちまう
  • xorしてアタック
  • 文字としての整合性をチェック
  • 繋げる

デス。


暗号作成ツールを作りながら進めたほうがいいかも。


文字の解析部分はもうちょっとなんとかなると思うけど、疲れたので・・・。

(define (problem59 data)
  (letrec ((a (char->integer #\a))
           (z (char->integer #\z))
           (A (char->integer #\A))
           (Z (char->integer #\Z))
           (real-string? (lambda (s)
                           (cond ((null? s) #t)
                                 ((not (or (and (>= (car s) a)
                                                (<= (car s) z))
                                           (and (>= (car s) A)
                                                (<= (car s) Z))
                                           (and (>= (car s) (char->integer #\0))
                                                (<= (car s) (char->integer #\9)))
                                           (= (car s) (char->integer #\space))
                                           (= (car s) (char->integer #\())
                                           (= (car s) (char->integer #\)))
                                           (= (car s) (char->integer #\;))
                                           (= (car s) (char->integer #\'))
                                           (= (car s) (char->integer #\.))
                                           (= (car s) (char->integer #\,))
                                           (= (car s) (char->integer #\!))))
                                  #f)
                                 (else
                                   (real-string? (cdr s))))))
           (attack (lambda (key data)
                     (let ((code (map (lambda (n)
                                           (bitwise-xor n key))
                                         data)))
                       (and (real-string? code) code))))
           (try (lambda (key data)
                  (let ((res (attack key data)))
                    (cond (res res)
                          ((> key z) #f)
                          (else
                            (try (+ key 1) data))))))
           (rotate-list (lambda (n l)
                          (if (zero? n)
                              l
                              (rotate-list (- n 1)
                                           (append
                                             (cdr l)
                                             (list (car l)))))))
           (make-attack-list (lambda (data)
                                 (fold-right
                                   (lambda (s acc)
                                     (rotate-list 1 (cons (cons s (car acc)) (cdr acc))))
                                   '(() () ())
                                   data))))
    (apply + (apply append (map (lambda (x)
                                  (try a x))
                                (make-attack-list data))))))

(problem59 *code*) ; 107359

; (The Gospel of John, chapter 1)
; 1 In the beginning the Word already existed.He was with God, and he was God.
; 2 He was in the beginning with God.
; 3 He created everything there is. Nothing exists that he didn't make.
; 4 Life itself was in him, and this life gives light to everyone.
; 5 The light shines through the darkness, and the darkness can never extinguish it.
; 6 God sent John the Baptist
; 7 to tell everyone about the light so that everyone might believe because of his testimony.
; 8 John himself was not the light; he was only a witness to the light.
; 9 The one who is the true light, who gives light to everyone, was going to come into the world.
; 10 But although the world was made through him, the world didn't recognize him when he came.
; 11 Even in his own land and among his own people, he was not accepted.
; 12 But to all who believed him and accepted him, he gave the right to become children of God.
; 13 They are reborn! This is not a physical birth resulting from human passion or plan, this rebirth comes from God.
; 14 So the Word became human and lived here on earth among us. He was full of unfailing
; love and faithfulness. And we have seen his glory, the glory of the only Son of the Father

聖書か。


3文字というヒントがなかったらかなり辛かった。