以下の内容はhttps://sabakunotabito.hatenablog.com/entry/2024/10/27/203946より取得しました。


失われし暗号秘儀の再構築 ~C#でOpenSSLの魔法を詠唱する~

どうやら、一筋縄ではいかない砂の迷宮に迷い込んだらしい。この顛末を書き残しておくか。

とあるAPIという名の神殿の扉を開けるには、OpenSSLという古の魔法で暗号化した合言葉が何度も必要だった。毎回コンソールで呪文を唱える非効率な儀式に、私はうんざりしていた。「この儀式そのものを、C#という名のゴーレムに覚えさせられないか?」…そんな些細な怠け心が、この壮大な冒険の始まりである。

旅の目的は、OpenSSLのencコマンドが生み出す暗号と、C#が生み出す暗号が、寸分違わぬ同一のものであることを証明すること。特に、OpenSSLのバージョンによって作法が異なる「SHA256+PBKDF2」と、古の「MD5」という、二つの魔法体系を完全に再現する。情報の砂漠を彷徨い、古文書の断片を繋ぎ合わせ、ついに辿り着いたその秘儀のすべてを、この羊皮紙に刻み込む。

この羊皮紙のあらまし

この羊皮紙が導く者

  • OpenSSLのencコマンドという、古の暗号魔法の真髄に触れたい探求者
  • その難解な魔法を、C#という現代の言葉で再現したいと願う魔法使い
  • 情報の砂漠で、暗号化という迷宮の出口を探している全ての冒険者

第一の儀式:古文書の解読(openssl encコマンド)

まずは、我々が再現すべき古の魔法、openssl encの作法を理解する。 Ubuntuという名の賢者に尋ねると、OpenSSLのバージョンは3.0.13。そのヘルプという名の巻物を広げると、無数のオプションが記されている。

その中でも、今回の儀式で極めて重要な役割を果たす呪文の詠唱法(オプション)は、以下の通りだ。これらを正確に組み合わせることで、初めて魔法は正しく発動する。

enc オプション 詠唱法(説明)
-e 暗号化の章を唱える
-d 複合化の章を唱える
-aes-256-cbc AES-256-CBCという術式を用いる
-md val sha256またはmd5で魂を練り上げる
-base64 結果をBase64という異国の言葉に変換する
-A 異国の言葉を一行で記述する
-pass val パスフレーズという合言葉を用いる
-pbkdf2 PBKDF2という秘儀で合言葉を強化する
-iter +int 秘儀のストレッチング回数を指定する(標準10,000回)

新世界の魔法:SHA256 + PBKDF2

現代の標準的な詠唱法。これで「Ubuntu:SHA256 + PBKDF2」という言葉を暗号化し、それを再び複合化して、儀式が可逆であることを確認する。

# 暗号化の詠唱
$ echo -n 'Ubuntu:SHA256 + PBKDF2' | openssl enc -e -aes-256-cbc -md sha256 -base64 -A -pass pass:password -pbkdf2
U2FsdGVkX180uM6YCr78gph0+q9msr+1uQ+ypYaJ3OlN8Dvx4dm/LPKfEK/N0ukM
# 複合化の詠唱
$ echo -n 'U2FsdGVkX1...ukM' | openssl enc -d -aes-256-cbc -md sha256 -base64 -A -pass pass:password -pbkdf2
Ubuntu:SHA256 + PBKDF2

古の魔法:MD5

OpenSSL 1.1.0未満で標準だった、今や非推奨の詠唱法。賢者からは警告(WARNING)を受けるが、古のゴーレムと対話するためには、この魔法も習得せねばならない。

# 暗号化の詠唱
$ echo -n 'Ubuntu:MD5' | openssl enc -e -aes-256-cbc -md md5 -base64 -A -pass pass:password
*** WARNING : deprecated key derivation used.
...
U2FsdGVkX1+q3wHjghZvztfesMppgfFP917KweDAtYA=
# 複合化の詠唱
$ echo -n 'U2FsdGVkX1...AtYA=' | openssl enc -d -aes-256-cbc -md md5 -base64 -A -pass pass:password
*** WARNING : deprecated key derivation used.
...
Ubuntu:MD5

第二の儀式:C#による魔法の再構築

いよいよ、この二つの魔法体系を、.NET 8.0という現代の言葉で再現する。 この呪文(コード)の核心は、パスフレーズとSalt(塩)から、鍵(Key)と初期化ベクトル(IV)を導き出すDeriveKeyAndIVの儀式にある。

(byte[], byte[]) DeriveKeyAndIV(string passphrase, byte[] salt)
{
    byte[] key, iv;
    var pass = Encoding.UTF8.GetBytes(passphrase);
    if (isPbkdf2)
    {
        // 新世界の魔法:SHA256 + PBKDF2
        using var derivedBytes = new Rfc2898DeriveBytes(pass, salt, 10000, HashAlgorithmName.SHA256);
        key = derivedBytes.GetBytes(32);
        iv = derivedBytes.GetBytes(16);
    }
    else
    {
        // 古の魔法:MD5
        // この難解な詠唱法は、古文書の断片を繋ぎ合わせて再現した秘儀である
        var hash1 = MD5.HashData([.. pass, .. salt]);
        var hash2 = MD5.HashData([.. hash1, .. pass, .. salt]);
        key = (byte[])[.. hash1, .. hash2];
        iv = MD5.HashData([.. hash2, .. pass, .. salt]);
    }
    return (key, iv);
}

MD5の作法は、公式の古文書には記されておらず、Stack Overflowという名の賢者の集会所で、幾多の議論の末にようやく再現された、まさに失われし秘儀だ。

この核心部分を組み込んだ完全な呪文を唱え、実行した結果がこれだ。

Encrypt-1: U2FsdGVkX1/IMEcoUYTS3hIIoOLOTUA4JPX8ynfjdxYl/7dKvmPWfADXcux6gWpt
Decrypt-1: C#: SHA256 + PBKDF2

Encrypt-2: U2FsdGVkX18Hcilj4MDr3lbWmhiDq8yYDNA/clavnPM=
Decrypt-2: C#: MD5

Decrypt-3: U2FsdGVkX180uM6YCr78gph0+q9msr+1uQ+ypYaJ3OlN8Dvx4dm/LPKfEK/N0ukM
Decrypt-3: Ubuntu:SHA256 + PBKDF2

Decrypt-4: U2FsdGVkX1+q3wHjghZvztfesMppgfFP917KweDAtYA=
Decrypt-4: Ubuntu:MD5

C#で生み出した暗号文が、OpenSSLの古の魔法で正しく複合化できることも確認できた。我々はついに、二つの世界の言葉を繋ぐことに成功したのだ。

羊皮紙を巻く前に

今回のOpenSSL暗号秘儀の再現は、情報の砂漠を彷徨う、困難な旅だった。GitHubにあるOpenSSLのソースコードという名の聖典は、あまりに難解で、途中で投げ出してしまったほどだ。

結局、我々を救ってくれたのは、Stack Overflowという賢者の集会所に残された、先人たちの議論の軌跡だった。 この羊皮紙に記したC#の呪文を元に、クラス化と例外処理という鎧を着せれば、冒頭で述べた非効率な儀式を自動化する、頼れるゴーレムを創り出せるだろう。

この記録が、同じように暗号の迷宮で迷う、未来の冒険者の助けとなることを願う。

焚き火の火も小さくなってきた。夜が更ける前に、筆を置くとしよう。

砂漠で見つけた魔法のランプ

ラクダの独り言

ご主人が「あんごうか」とかいう、誰にも読めない言葉を作るのに夢中になっている。そんなに隠したいことがあるなら、最初から言わなきゃいいのに、と思うのは俺だけか?どうせ俺の晩飯のことなんて、誰も読めやしねえのにな。おっと、また腹が鳴っちまった。




以上の内容はhttps://sabakunotabito.hatenablog.com/entry/2024/10/27/203946より取得しました。
このページはhttp://font.textar.tv/のウェブフォントを使用してます

不具合報告/要望等はこちらへお願いします。
モバイルやる夫Viewer Ver0.14