From dff044b25b4512944a2e89ef2188516af558658e Mon Sep 17 00:00:00 2001 From: ncaq Date: Wed, 25 May 2022 18:38:39 +0900 Subject: [PATCH] =?UTF-8?q?added:=20OpenSSL=20ver3=E7=B3=BB=E3=81=AB?= =?UTF-8?q?=E5=AF=BE=E5=BF=9C=E3=81=99=E3=82=8B=E3=81=9F=E3=82=81=E3=81=AB?= =?UTF-8?q?=E6=9A=97=E5=8F=B7=E5=8C=96=E6=96=B9=E6=B3=95=E3=82=92=E5=A4=89?= =?UTF-8?q?=E6=9B=B4=E3=81=99=E3=82=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 変更内容 === 暗号化方法を`AES-256-CBC`に変更した。 設定ファイルのキー保存形式をハッシュに変更して、 暗号化方法を設定ファイルに保存するようにした。 これによりまたこの暗号形式が廃止予定になった時に、 今度は自動でマイグレーションがかけられる可能性がある。 本当にそんな日が来るまでTwitterなどが生きているかは不明だが。 そのため暗号インスタンスは使いまわしている。 別の暗号化手法を使われると大混乱が起きてしまうので。 復号化失敗時にエラーメッセージをGUIでも出すようにして、 黙って死ぬのをある程度抑止。 復旧のヒントも出す。 一応旧形式のキーが設定にある場合は自動で削除する程度のマイグレーションは可能だが、 どうせOpenSSLが既にアップデートされてる場合は、 手動で再度アカウントを設定し直さないといけないので不完全です。 また不用意に勝手にユーザの設定やファイルを消してしまうのは危険な挙動なため、 どうせユーザの操作が必要になるなら避けることにした。 動作確認した環境 === `cat /etc/os-release` ~~~ PRETTY_NAME="Ubuntu 22.04 LTS" NAME="Ubuntu" VERSION_ID="22.04" VERSION="22.04 LTS (Jammy Jellyfish)" VERSION_CODENAME=jammy ID=ubuntu ID_LIKE=debian HOME_URL="https://www.ubuntu.com/" SUPPORT_URL="https://help.ubuntu.com/" BUG_REPORT_URL="https://bugs.launchpad.net/ubuntu/" PRIVACY_POLICY_URL="https://www.ubuntu.com/legal/terms-and-policies/privacy-policy" UBUNTU_CODENAME=jammy ~~~ `uname -a` ~~~ Linux (ホストネームは一応隠す) 5.10.102.1-microsoft-standard-WSL2 #1 SMP Wed Mar 2 00:30:59 UTC 2022 x86_64 x86_64 x86_64 GNU/Linux ~~~ 要するにWSL2です。 `openssl version` ~~~ OpenSSL 3.0.2 15 Mar 2022 (Library: OpenSSL 3.0.2 15 Mar 2022) ~~~ `ruby --version` ~~~ ruby 3.1.2p20 (2022-04-12 revision 4491bb740a) [x86_64-linux] ~~~ --- plugin/world/keep.rb | 47 +++++++++++++++++++++++++++++++++----------- 1 file changed, 35 insertions(+), 12 deletions(-) diff --git a/plugin/world/keep.rb b/plugin/world/keep.rb index c4ae7d3b..b61aaab4 100644 --- a/plugin/world/keep.rb +++ b/plugin/world/keep.rb @@ -15,14 +15,21 @@ module Plugin::World module Keep ACCOUNT_FILE = File.join(Environment::SETTINGDIR, 'core', 'token').freeze ACCOUNT_TMP = (ACCOUNT_FILE + ".write").freeze - ACCOUNT_CRYPT_KEY_LEN = 16 + # 暗号化ライブラリが32 bytesを要求してくる。 + ACCOUNT_CRYPT_KEY_LEN = 32 extend Keep @@service_lock = Monitor.new + # 暗号化手法を統一して扱いたいので共有変数にする。 + @@cipher = OpenSSL::Cipher::AES256.new("cbc") + def key - key = UserConfig[:account_crypt_key] ||= SecureRandom.random_bytes(ACCOUNT_CRYPT_KEY_LEN) - key[0, ACCOUNT_CRYPT_KEY_LEN] end + # また暗号化方法が将来的な非推奨になった時に、削除される前に変換出来るように暗号化方法を保存しておく。 + account_crypt = + UserConfig[:account_crypt] || {key: SecureRandom.random_bytes(ACCOUNT_CRYPT_KEY_LEN).to_s, cipher_name: @@cipher.name} + UserConfig[:account_crypt] = account_crypt + account_crypt[:key][0, ACCOUNT_CRYPT_KEY_LEN] end # 全てのアカウント情報をオブジェクトとして返す # ==== Return @@ -122,17 +129,33 @@ module Plugin::World account_data end def encrypt(str) - cipher = OpenSSL::Cipher.new('bf-ecb').encrypt - cipher.key_len = ACCOUNT_CRYPT_KEY_LEN - cipher.key = key - cipher.update(str) << cipher.final end + begin + @@cipher.encrypt + @@cipher.key_len = ACCOUNT_CRYPT_KEY_LEN + @@cipher.key = key + @@cipher.update(str) << @@cipher.final + rescue => e + chi_fatal_alert e.inspect + end end def decrypt(binary_data) - cipher = OpenSSL::Cipher.new('bf-ecb').decrypt - cipher.key = key - str = cipher.update(binary_data) << cipher.final - str.force_encoding(Encoding::UTF_8) - str end + begin + @@cipher.decrypt + @@cipher.key = key + str = @@cipher.update(binary_data) << @@cipher.final + str.force_encoding(Encoding::UTF_8) + str + rescue => e + chi_fatal_alert <<"EOS" +暗号の復号時にエラーが起きました。 +特にOpenSSLがアップデートされたりした場合にこのエラーが起きた場合は、 +~/.mikutter/settings/setting.ymlからaccount_cryptで始まるものを消して、 +~/.mikutter/settings/core/tokenファイルを消して、 +アカウントを再認証すると上手くいく可能性があります。 + +#{e.inspect} +EOS + end end private -- 2.34.1