はじめに
Chacha20-Poly1305の解説と実装 の子記事になります.
上記事ではChacha20-Poly1305をPythonで再実装しましたが, 本記事ではGolangを用いて再再実装しました.
RFCs
- ChaCha20 and Poly1305 for IETF Protocols
RFC7539 - HMAC-based Extract-and-Expand Key Derivation Function (HKDF)
RFC5869 - The Transport Layer Security (TLS) Protocol Version 1.3
RFC8446
test vector
のtest vectorを通してあるので実装としては信用して利用できます. 書き方については信用できませんが.
コードの解説がまだ書ききれていませんが一旦投稿します(ごめんなさい)
やったこと
基本的にはクライアントとサーバー間でデータを送受信してるだけです.
クライアントからの最初の送信(いわゆるClient Hello1)とそれに対するサーバーからの返答(いわゆるServer Hello)で共有鍵を作り, 以降の通信は鍵を使ってChacha20で暗号化しています. 今回は省きましたが, "Chacha20-Poly1305"を実装しているのでもちろんPoly1305を使ってメッセージ認証ができます.
socket通信はこちら(【Golang】Socket通信するプログラムを書いてみた)を参考にしました.
big.Intの扱い方やbig.Int to Bytes (Bytes to big.Int), SHA256やHMAC2など調べることが多くて大変でした.
以下の動画のように動作します.
DHで鍵交換, chachs20で暗号化するサーバーとクライアント(鍵導出はできていないので雑に秘密鍵の先頭数バイト) pic.twitter.com/0YbVsJmjYc
— ゆうけむ (@ykm_kn) 2018年12月7日
上がserver, 下がclientになっています.
共有鍵がちゃんと同じであること, サーバーから送られてきた(暗号化されている)メッセージをクライアント側でちゃんと復号して"this is a message"と表示されていることが確認できました.
コードの解説
chacha20に使用するkey, nonceはTLS1.3であればHKDFで導出しますが, まだそこまで実装ができていないので今回は雑にDiffie-Hellmannで共有した鍵の先頭のバイトを使っています.
サーバー
クライアント
おわりに
最終的にはハンドシェイクも実装してTLS1.3サーバとして動くようにしたいと思います.
自作OS上の自作ブラウザで自作TLS対応サーバで動く自作ブログを閲覧(認証局を自作するな)
— ゆうけむ (@ykm_kn) 2018年12月6日
1: 実際にはClient Helloしていない
2: 今回は出てこない HKDFに使う