Skip to content
shunsei.dev
Go back

GoでE2EE(エンドツーエンド暗号化)を実装してみた

Edit page

はじめに

近年、私たちのデジタルコミュニケーションにおけるプライバシー保護への意識は高まる一方です。そんな中、セキュリティ周りの勉強を始める時に、E2EEってなんだっけ?SSLとかもあったけど、違いは何?という疑問が自分の中で生まれたので、振り返りの記事になります。今回は、Go言語でこのE2EEを実装する方法について、手紙のやり取りを例えにしながら分かりやすく解説します。

E2EEって何?手紙で例えてみる

E2EEは、通信の安全性を極限まで高めるための暗号化技術です。メッセージの内容が、送信者から受信者に届くまで、誰にも読み取られないように保護します。 これを手紙のやり取りに例えると、以下のようになります。 あなたが書いた手紙を、あなたと相手だけが持つ鍵で開けられる南京錠付きの箱 に入れて送るイメージです。

E2EEとSSLの違い:運搬方法と中身の保護

通信の暗号化技術としてよく耳にする SSL(Secure Sockets Layer) とE2EEは、どちらもデータを保護する役割を持ちますが、その保護範囲と目的が異なります。こちらも手紙の例えで見てみましょう。

E2EE:誰にも開けられない南京錠付きの箱で手紙を送る

ここまでの流れをまとめる

Go言語でE2EEを実装する

Go言語には、E2EEを実装するために必要な暗号化関連のライブラリが豊富に用意されています。

GoでのE2EE実装例:シンプルなメッセージ暗号化・復号化

以下は、Go言語でシンプルなテキストメッセージの暗号化と復号化を行う例です。実際のE2EEシステムでは、より複雑な鍵交換などの処理が必要になります。 あくまで参考程度にしてください。

package main

import (
	"crypto/aes"
	"crypto/cipher"
	"crypto/rand"
	"encoding/base64"
	"fmt"
	"io"
)

// 暗号化
func encrypt(plaintext string, key []byte) (string, error) {
	block, err := aes.NewCipher(key)
	if err != nil {
		return "", err
	}

	ciphertext := make([]byte, aes.BlockSize+len(plaintext))
	iv := ciphertext[:aes.BlockSize]
	if _, err := io.ReadFull(rand.Reader, iv); err != nil {
		return "", err
	}

	stream := cipher.NewCFBEncrypter(block, iv)
	stream.XORKeyStream(ciphertext[aes.BlockSize:], []byte(plaintext))

	return base64.StdEncoding.EncodeToString(ciphertext), nil
}

// 復号化
func decrypt(ciphertext string, key []byte) (string, error) {
	ciphertextBytes, err := base64.StdEncoding.DecodeString(ciphertext)
	if err != nil {
		return "", err
	}

	block, err := aes.NewCipher(key)
	if err != nil {
		return "", err
	}

	if len(ciphertextBytes) < aes.BlockSize {
		return "", fmt.Errorf("ciphertext too short")
	}

	iv := ciphertextBytes[:aes.BlockSize]
	ciphertextBytes = ciphertextBytes[aes.BlockSize:]

	stream := cipher.NewCFBDecrypter(block, iv)
	stream.XORKeyStream(ciphertextBytes, ciphertextBytes)

	return string(ciphertextBytes), nil
}

func main() {
	// 暗号鍵(実際のシステムでは、安全な鍵交換が必要)
	key := []byte("secretkey1234567") // 16byte

	// 暗号化するメッセージ
	plaintext := "Hello, E2EE!"

	// 暗号化
	encrypted, err := encrypt(plaintext, key)
	if err != nil {
		panic(err)
	}
	fmt.Println("暗号化:", encrypted)

	// 復号化
	decrypted, err := decrypt(encrypted, key)
	if err != nil {
		panic(err)
	}
	fmt.Println("復号化:", decrypted)
}

注意点

まとめ:Goで実現するセキュアなコミュニケーション

Go言語は、豊富な暗号化ライブラリを備えており、E2EEを実装するための強力なツールとなります。手紙の例え話を通して、E2EEの仕組みとSSLとの違いを理解していただけたかと思います。 E2EEは、私たちのデジタルコミュニケーションにおけるプライバシーを強力に保護するための重要な技術です。これらをうまく活用し、堅牢なシステム開発に役立てたいと思います。


Edit page
Share this post on:

Previous Post
Go言語でのMCPサーバーSDKの存在について
Next Post
Goでの型推論と%Tの内部動作の仕組みについて