LoginSignup
0
0

More than 3 years have passed since last update.

rubyでtripleDESやったらめちゃハマった話

Last updated at Posted at 2020-05-29

やりたいこと

tripleDESのCBCモードで暗号化したデータを先方のサーバーにリクエストすると、同様の方式でデータがレスポンスされるので復号する。

で、このtripleDESについて全く無知だったのでググってみると、Rubyの記事って案外情報が見つかりにくいんですね。
色々検索してこちらのページにたどり着きました。
http://timolshansky.com/2011/10/23/ruby-triple-des-encryption.html

実際ここで書かれているコードを実行すると、ちゃんと動くんです。が、ここからが長かった。

先方の認証サーバーにリクエストするもうまくいかない

いただいた鍵を使って、その他パラメータを何度確認してもミスはない。ぐぬぬ...

恥を忍んで先方の方が暗号化の際に使っているコード(別の言語)を見せていただくと....おや?暗号化したバイトの先頭に何かくっつけているぞ?

初期化ベクトルというもう一つの鍵

実は、今回の暗号化方式(des-ede3-cbc)では、秘密鍵の他に初期化ベクトルという物を実質鍵のように使って暗号化しているんですね。
これに気づくのに随分と時間がかかった。なんでかっていうと、↑に挙げたページやその他ぐぐったページでは 'pkcs5_keyivgen' というメソッドを使っているんですよ。
要は インスタンス作る -> pkcs5_keyivgenで鍵と初期化ベクトルをセット -> 暗号、復号する という流れなんですが、これだと同じ初期化ベクトルを使っていることになる。だから復号できる。

が、今回の条件は こちらの手元で暗号化 -> 相手サーバーで復号 となるので、相手は秘密鍵だけでなく初期化ベクトルの情報を知らなければいけない んですね。 (先頭に初期化ベクトル入れるってのはtripleDESの仕様なのでしょうか?これはググってもわからんかった)

実装

というわけで、実際にやってみたのがこちら。今回は、先頭8byteが初期化ベクトル。

class TripleDES
  class << self
    IV_LENGTH = 8
    SECRET_KEY = 'your__awesome_Secret_Key'

    def get_cipher
      cipher = OpenSSL::Cipher.new('des-ede3-cbc')
      cipher.key = SECRET_KEY
      cipher
    end

    def encrypt(plain_string)
      cipher = get_cipher
      cipher.encrypt

      # 初期化ベクトルを生成する
      iv = OpenSSL::PKCS5.pbkdf2_hmac(SecureRandom.alphanumeric(10), SecureRandom.alphanumeric(10), 2, IV_LENGTH, 'sha1')
      cipher.iv = iv

      output = cipher.update(plain_string)
      output << cipher.final

      # 生成した暗号の前に初期化ベクトルを入れる
      iv + output
    end

    def decrypt(encrypted_byte_string)
      cipher = get_cipher
      cipher.decrypt

      # 初期化ベクトルと本文をそれぞれ取り出す
      iv = encrypted_byte_string.byteslice(0, IV_LENGTH)
      cipher.iv = iv
      target_bytes = encrypted_byte_string.byteslice(IV_LENGTH, encrypted_byte_string.chars.count)

      output = cipher.update(target_bytes)
      output << cipher.final
    end
  end
end

余談

pkcs5_keyivgenは非推奨メソッドってちゃんと書いてあるのにしばらく気づかなかった。笑
https://docs.ruby-lang.org/ja/latest/method/OpenSSL=3a=3aCipher/i/pkcs5_keyivgen.html

こちらの方が詳しい。そうなんですよ、pkcs5_keyivgenはivを取って来れないんですよね。
https://techmedia-think.hatenablog.com/entry/20110527/1306499951

今後実装される方のヒントになれば幸いです。久々にハマった....

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0