【Go】AES暗号を使用した暗号化、復号化のサンプルコード

更新日:2025/3/13/(木) 12:38

タグ:Go

概要

暗号技術入門 第3版に出てきたAESで暗号化、復号化をGoで実装してみた

cryptoパッケージを使用

サンプルコード

package main import ( "crypto/aes" "crypto/cipher" "crypto/rand" "encoding/base64" "errors" "fmt" "io" ) // encryptAES 関数は、指定された平文データを AES-GCM を使用して暗号化し、結果を Base64 エンコードした文字列として返します。 // // Parameters: // - plainText: 暗号化するデータ (平文)。 // - key: 暗号化に使用する秘密鍵。長さは 16, 24, 32 バイト(AES-128, AES-192, AES-256 に対応)である必要があります。 // // Returns: // - 暗号化されたデータを Base64 エンコードした文字列。 // - エラーが発生した場合にはエラーメッセージ。 func encryptAES(plainText, key string) (string, error) { // AES 暗号化モジュールを作成(指定された鍵を使用)。 block, err := aes.NewCipher([]byte(key)) if err != nil { return "", err } // GCM (Galois/Counter Mode) インスタンスを作成。 gcm, err := cipher.NewGCM(block) if err != nil { return "", err } // 暗号化のために Nonce(初期化ベクトル、IV)を生成。Nonce のサイズは GCM 仕様に依存。 nonce := make([]byte, gcm.NonceSize()) // 暗号学的に安全な乱数生成器を使用して Nonce を埋める。 if _, err = io.ReadFull(rand.Reader, nonce); err != nil { return "", err } // 平文(plainText)を暗号化し、Nonce をプレフィックスとして付与。 cipherText := gcm.Seal(nonce, nonce, []byte(plainText), nil) // 暗号文を Base64 形式の文字列に変換して返す。 return base64.StdEncoding.EncodeToString(cipherText), nil } // decryptAES 関数は、AES-GCM を使用して暗号文を復号化し、平文データを返します。 // // Parameters: // - cipherText: Base64 エンコードされた暗号文。 // - key: 復号化に使用する秘密鍵。暗号化時に使用したものと同じ鍵を指定する必要があります。 // // Returns: // - 復号化された平文データ。 // - エラーが発生した場合にはエラーを返す。 func decryptAES(cipherText, key string) (string, error) { // AES 復号化モジュールを作成(指定された鍵を使用)。 block, err := aes.NewCipher([]byte(key)) if err != nil { return "", err } // GCM (Galois/Counter Mode) インスタンスを作成。 gcm, err := cipher.NewGCM(block) if err != nil { return "", err } // Base64 形式の暗号文をデコードしてバイトデータに変換する。 data, err := base64.StdEncoding.DecodeString(cipherText) if err != nil { return "", err } // 暗号文の先頭に付加された Nonce を分離。Nonce サイズを確認。 nonceSize := gcm.NonceSize() if len(data) < nonceSize { // データが Nonce サイズより小さい場合は不正な暗号文としてエラーを返す。 return "", errors.New("不正な暗号文です") } // Nonce(初期化ベクトル)と暗号化されたデータそれぞれに分割。 nonce, cipherTextBytes := data[:nonceSize], data[nonceSize:] // 暗号化データを復号化して平文を取得。 plainText, err := gcm.Open(nil, nonce, cipherTextBytes, nil) if err != nil { return "", err } // 復号化された平文を文字列として返す。 return string(plainText), nil }

使用

func main() { // keyを32バイトに設定 aesKey := "aaaaaaaaaabbbbbbbbbbccccccccccdd" plainText := "Hello, World!" cipherText, err := encryptAES(plainText, aesKey) if err != nil { panic(err) } decryptText, err := decryptAES(cipherText, aesKey) if err != nil { panic(err) } fmt.Println("plainText: " + plainText) fmt.Println("cipherText: " + cipherText) fmt.Println("decryptText: " + decryptText) } // 出力 // plainText: hello,world! // cipherText: rJWxz1xCgZuG9LPBLhz3kgjChsEeYQVXSI4+dEr2ftzlkH1gLRZ3hg== // decryptText: hello,world!