Python暗号化ライブラリを用いて仮想通貨ウォレットのセキュリティを強化する!!
近頃、仮想通貨の盛り上がりと同時に個人ウォレットに対するハッキング事件が散見されます。
直近ではGoogleアカウントが乗っ取られクラウド上に保管していた秘密鍵を窃取され、仮想通貨資産を失うという痛ましい事件が発生していました。
Googleアカウントが不正ログインされてしまい、不用意に暗号資産walletのシードフレーズを置いてしまっていて3400万円近く抜き取られてしまいました。
— e-l-m-o (@e_l_m_o_2_fx) May 23, 2025
最近スキャム踏んで有志の皆様に救出してもらったばかりなのにただただ情けないのと申し訳ないのと、金銭的にかなり暗号資産に頼っていたので
筆者はクラウド上は流石にセキュリティ的に怖いな、という思いがありそういう保管方法はしていませんが、外付けSSDにtxtファイルのまま保管している状態なのでPCにマルウェアなど仕組まれてしまえば盗まれる可能性は全然あります。
一見するとただの通話アプリにマルウェアが仕組まれていて遠隔操作ハッキングされたというケースもあります。
資金全部抜かれました
— Grypto (@g_resident) May 11, 2024
完全にやられました
「インタビューをする」という名目で色々やり取りし最後に「vorion」というミーティングアプリをダウンロードしてしまい10個以上のウォレットに分散してた資産全部抜かれました
metamask
phantomなど
抜かれた時間帯からしてほぼ間違いないです… pic.twitter.com/DwjEXTeTR9
上記のケースからクラウドだろうとローカルだろうと秘密鍵そのまま保管することは想像以上にリスクの高い状態であることが理解できるかと思います。
セキュリティ意識の高い方はハードウェアウォレットを利用したり、マルチシグ機能を活用したり、仮想通貨取引専用のPCを用意する等方法ありますがコストと手間がかかります。
そこで筆者は考えました、手間を増やさずにクラウドやローカル環境にウォレットの秘密鍵を保管するにはどうすれば良いか。
秘密鍵を対称暗号方式で暗号化&復号化できるようにすれば良いのでは、と。
対称暗号方式とは
- 同じ鍵を使ってデータを「暗号化(ロック)」と「復号(アンロック)」する方式です。
-
送信者と受信者が同じ鍵を共有している必要があります。
-
処理が高速で、大量のデータの暗号化に向いています。
-
鍵の管理・共有が難点(盗まれたら安全でなくなる)。
パスワードに関してはクラウドに残すこともローカルに残す必要はなく、忘れそうだったらPCの近くに付箋を貼りメモしておけば良いのです。(秘密鍵を手書きするよりは楽ですよね)
つまり、対称暗号方式を取り入れることで秘密鍵を使途不明の文字列データに変換してクラウドまたはローカルストレージに置くことができ、憶えやすいパスワードを自身の脳内にだけ残しておけばあまり手間をかけることなくセキュリティ的に強固な布陣にできると考えたということです。(とはいってもpasswordリストに載っているような単純なパスワードはよくないです)
対称暗号方式をPythonで実装する
追記(5/26):※下記の解説は旧バージョンのスクリプトの解説となります。現行バージョンはセキュリティ強化のためキー生成プロセスにArgon2を用いており、暗号化プロセスにAES-256-CBC+HMACという構成になっています。
1. キーの生成プロセス _generate_key_from_password関数
パスワード + Salt → PBKDF2(10万回反復) → 暗号化キー
- Saltを用いることで同一のパスワードであっても出力されるキーはランダムになります。
- PBKDF2によるパスワードベースの暗号化キーを生成します。
- 10万回のイテレーションによりブルートフォース攻撃を困難にしています。
- Salt生成:os.urandom(16)で暗号学的に安全なランダム値を生成します。
- キー生成:入力したパスワードとSaltを元に一意のキーを作成します。
- 暗号化:Fernetアルゴリズムで平文を暗号化します。
- データ結合:Saltと暗号文を結合し暗号文の完成です。
- データ分離:暗号化データからSalt(最初の16バイト)を抽出します。
- キー再生成:入力したパスワードとSaltから暗号化時と同じキーを再生成します。
- 復号化:Fernetアルゴリズムで暗号文を復号します。
ウォレットの秘密鍵を暗号化&復号化してみよう
ウォレットを作成する際にニーモニックフレーズや秘密鍵をtxtファイルで保存される方は多いと思います(筆者もそうです)、そのファイルを暗号化&復号化してみましょう。ファイル名を"rabby_secret.txt" と仮定します。保存されている内容はシードフレーズ、秘密鍵のどちらでも良いです。今回は下記のように仮定します。
$ python crypto_cli.py encrypt -f rabby_secret.txt
$ 暗号化用パスワードを入力してください:
$ パスワードを再入力してください:
$ ファイル暗号化完了: rabby_secret.txt -> rabby_secret.txt.encrypted
$ python crypto_cli.py decrypt -f rabby_secret.txt.encrypted
$ 復号化用パスワードを入力してください:
$ 復号化されたファイル: road light welcome broccoli rug pen blue rough remind
mail june camera
コメント
コメントを投稿