GO言語(golang)でテキストファイルをAES暗号化する

AES(Advanced Encryption Standard)は強度が極めて高いと言われている共通鍵暗号化方式の一つで、アメリカ政府が政府内の標準として策定した暗号化規格です。

C#とPythonではプログラムを書いたことがありますが、golangではどうするのだろうと思い、作ってみました。

プログラムの主要部分はこちらのサイトを参考にさせていただきました。

以下、暗号化するプログラムです。

package main

import (
	"fmt"
	"io/ioutil"
	"gopkg.in/alecthomas/kingpin.v2"
	"github.com/howeyc/gopass"
	"crypto/aes"
	"crypto/cipher"
	"crypto/rand"
	"encoding/base64"
)

func main() {
	var (
		in   = kingpin.Arg("infile", "Input text File Name").Required().String()
		out   = kingpin.Arg("outfile", "Output text File Name").Required().String()
	)

	//コマンドライン引数を受け取る
	kingpin.Parse()
	fmt.Println("input  txt file :", *in)
	fmt.Println("output txt file :", *out)

	for {
			//16文字のパスワード入力
			fmt.Printf("Enter 16 bytes password: ")
			Password, err := gopass.GetPasswdMasked()
			if err != nil{
				fmt.Println(err)
			}
			if len(Password) == 16 {
				//テキストファイル読み込み
				plainText, err := ioutil.ReadFile(*in)
				if err != nil {
					panic(err)
				}
				//鍵の設定
				block, err := aes.NewCipher([]byte(Password)); if err != nil {
					fmt.Println(err)
				}
				//ガロアカウンタモードのブロック暗号
				gcm, err := cipher.NewGCM(block); if err != nil {
					fmt.Println(err)
				}
				//一度きりの初期化ベクトル作成
				nonce := make([]byte, gcm.NonceSize())
				_, err = rand.Read(nonce); if err != nil {
					fmt.Println(err)
				}
				cipherText := gcm.Seal(nil, nonce, plainText, nil) //暗号化
				cipherText = append(nonce, cipherText...) //初期化ベクトルを先頭に付与

				//Base64 Encode
				sEnc := base64.StdEncoding.EncodeToString(cipherText)
				err = ioutil.WriteFile(*out, []byte(sEnc), 0644); if err != nil {
					fmt.Println(err)
				}

				break

			} else {
				fmt.Println("Password not equal 16 bytes")
			}
		}
}
cat test.txt

Hello World !
あいうえお
かきくけこ
①②③④⑤
go run encaes.go test.txt out.txt

input  txt file : test.txt
output txt file : out.txt
Enter 16 bytes password: ****************
cat out.txt

v3rnUlLk5kha6smtAtNq2hDBrOSFQTg8jM702TQv/pgsouvQX9vlmQlWRQEh76kNcz+muHnhKXygBwqarjWNakNKxup+uZ46Jl5x+dmXF8XCAKauUs8RMoks

そして、以下が複合するプログラムです。

package main

import (
	"fmt"
	"io/ioutil"
	"gopkg.in/alecthomas/kingpin.v2"
	"github.com/howeyc/gopass"
	"crypto/aes"
	"crypto/cipher"
	"encoding/base64"
)

func main() {
	var (
		in   = kingpin.Arg("infile", "Input text File Name").Required().String()
		out   = kingpin.Arg("outfile", "Output text File Name").Required().String()
	)

	//コマンドライン引数を受け取る
	kingpin.Parse()
	fmt.Println("input  txt file :", *in)
	fmt.Println("output txt file :", *out)

	for {
			//16文字のパスワード入力
			fmt.Printf("Enter 16 bytes password: ")
			Password, err := gopass.GetPasswdMasked()
			if err != nil{
				fmt.Println(err)
			}
			if len(Password) == 16 {
				//暗号化されたBase64テキストファイルの読み込み
				sEnc, err := ioutil.ReadFile(*in)
				if err != nil {
					panic(err)
				}
				cipherText, _ := base64.StdEncoding.DecodeString(string(sEnc))
				//鍵の設定
				block, err := aes.NewCipher([]byte(Password)); if err != nil {
					fmt.Println(err)
				}
				//ガロアカウンタモードのブロック暗号
				gcm, err := cipher.NewGCM(block); if err != nil {
					fmt.Println(err)
				}
				//先頭に追加された初期化ベクトルを取り出す
				nonce := cipherText[:gcm.NonceSize()]
				plainByte, err := gcm.Open(nil, nonce, cipherText[gcm.NonceSize():], nil); if err != nil {
					fmt.Println(err)
				}
				err = ioutil.WriteFile(*out, []byte(plainByte), 0644); if err != nil {
					fmt.Println(err)
				}

				break

			} else {
				fmt.Println("Password not equal 16 bytes")
			}
		}
}
go run decaes.go out.txt dec.txt

input  txt file : out.txt
output txt file : dec.txt
Enter 16 bytes password: ****************
cat dec.txt

Hello World !
あいうえお
かきくけこ
①②③④⑤

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です

CAPTCHA