🔐

Juliaで暗号化

2024/05/06に公開

※ドキュメントやソースコードをちゃんと読めてない,暗号の知識が弱い部分もあるので,今後調べながら修正します…

Juliaの暗号化関連でNettle.jlを使ってみて,いつかに備えてメモしておきます.
サンプルコード触れたレベルですが.
調べたきっかけは,業務でハードコーディング避けようぜって話が出ていて,Juliaで暗号化処理する場合,どんなパッケージあるのかなと思ったからです.
業務ではJulia使ってないです…

Juliaのバージョンは1.10.3です.
Dockerのjuliaのlatestのイメージを使いました.

レッツトライ

まずはPkgを追加しなければですので,REPLから追加しました(割愛).

using Nettle

以下は基本的にサンプルコードの模写なんですが…

#鍵の生成
passwd = "hogehoge"
salt = hex2bytes("a3e550e89e70996c") #8バイトじゃなくても良さげ
(key, iv16) = gen_key32_iv16(Vector{UInt8}(passwd), salt)

#plainがパスワードにあたるはず
enc = Encryptor("AES256", key)
plaintext = "Message"
ciphertext = encrypt(enc, :CBC, iv16, add_padding_PKCS5(Vector{UInt8}(plaintext), 16))
println(ciphertext)

saltは文字通りソルト,パスワードをハッシュ値にする際に利用するものと同じと思われます.
gen_key32_iv16はpasswdとソルトを使って32バイトの鍵と16バイトの初期化ベクトルを作成してます.

AESのアルゴリズムについては割愛します.マスタリングTCP/IPのセキュリティ編を流し読みでちゃんと読めてないので説明できないです…
encryptの引数のCBCは,ブロック暗号でのブロックチェイニングの一種CBCモードを指定していると思われます.
語源なのか調べてないんですが,ブロックチェイニングは,ブロックチェーンと同じように前ブロックを利用する仕組みだったはずです.ブロックチェーンは前ブロックの情報のハッシュ値を含めることで改竄を検知できて,ブロックチェイニングモードは前ブロックの情報を利用した暗号化によって推測を困難にしているらしいです.間違ってたらご指摘ください.
最初のブロックには前のブロックがないため,初期化ベクトルは排他的論理和する際に利用されるとか.

add_padding_PKCS5は名前からパディングだと思われます.plaintextである平文がブロック長に足りない場合のデータを埋め合わせてるものかと.PKCS5がパディング方式だそうです.

出力結果が以下になりました.

 0x9b
 0x79
 0xc6
 0xcf
 0x2b
 0x2a
 0x10
 0xa1
 0x83
 0xe2
 0x32
 0x31
 0x78
 0x81
 0x27
 0xe4

実際に何かしらのパスワードをコード内で使う,APIで認証情報を送信する際とかは以下の部分がメインですかね…

dec = Decryptor("AES256", key)
deciphertext = decrypt(dec, :CBC, iv16, ciphertext)
println(String(deciphertext))

これにて元のplaintextが出力されました.

所感

gen_key32_iv16のソースコードを見てみたのですが,digestしてハッシュ値を使って固定長にしているようでした..
また,引数にMD5と記載されていました,MD5は安全性に疑問視と聞くのですが,どちらかというと出力値の方が秘密にすべき値?と思われ,そこまで気にしなくても良いのか?と思ったり.
ただ,このパッケージの説明が必要最低限のため憶測でしかない箇所が多すぎる,というかソースコードをちゃんと読めてなさすぎまして,使うならもうちょっと調べる必要ありでした…今後の宿題です

GitHubで編集を提案

Discussion