GoでAESアルゴリズム(CBCモード)+PKCS7パディング+HMACを使った実装をする
GoでAESアルゴリズム(CBCモード)+PKCS7パディング+HMACを使った実装をするの続きです。
さて、前回はAES+CBC+PKCSパディングを使った実装例を紹介した。パディングを使って、任意の平文をブロック型暗号で暗号化することが可能になったが、一方で脆弱性がうまれてしまった。暗号文+パディングを繰り返し送ることで平文を一部推測できてしまうような脆弱性だ。この脆弱性の根本原因は、誰もが復号できてしまう部分にある。従って、復号処理のための暗号文を入力するものを認証することで解決できる。その仕組がMAC(Message Authentication Code)であり、今回はHMAC(keyed-hash MAC)を使った実装例が今回のものになる。
AES暗号化によるHMACとは
暗号文をHMAC用の共有鍵とハッシュ関数で導きだされるもの。復号をするまえにHMACを検証することで、サブジェクトの真性正を認証することができる。こ
GoにおけるHMACは?
標準パッケージ内のcrypt/hmacで実装されている。パディングは実装されていなかったのに、なぜなのか。謎である。実装自体はシンプルになる。
func EncryptByCBCMode(key []byte, plainText string) ([]byte, error) {
block, err := aes.NewCipher(key); if err != nil {
return nil, err
}
paddedPlaintext := PadByPkcs7([]byte(plainText))
cipherText := make([]byte, len(paddedPlaintext)) // cipher text must be larger than plaintext
iv := make([]byte, aes.BlockSize)// Unique iv is required
_, err = rand.Read(iv); if err != nil {
return nil, err
}
cbc := cipher.NewCBCEncrypter(block, iv)
cbc.CryptBlocks(cipherText, paddedPlaintext)
cipherText = append(iv, cipherText...)
// MAC作成
mac := hmac.New(sha256.New, []byte("12345678912345678912345678912345")) // sha256のhmac_key(32 byte)
mac.Write(cipherText)
cipherText = mac.Sum(cipherText)
return []byte(cipherText), nil
func DecryptByCBCMode(key []byte, cipherText []byte) (string, error) {
if len(cipherText) < aes.BlockSize + sha256.Size {
panic("cipher text must be longer than blocksize")
} else if len(cipherText) % aes.BlockSize != 0 {
panic("cipher text must be multiple of blocksize(128bit)")
}
// macの取り出し
macSize := len(cipherText) - sha256.Size
macMessage := cipherText[macSize:]
// 暗号文から想定macを計算
mac := hmac.New(sha256.New, []byte("12345678912345678912345678912345")) // sha256のhmac_key(32 byte)
mac.Write(cipherText[:macSize])
expectedMAC := mac.Sum(nil)
// MACによる認証
if !hmac.Equal(macMessage, expectedMAC) {
return "", errors.New("Failed Decrypting")
}
iv := cipherText[:aes.BlockSize]
plainText := make([]byte, len(cipherText[aes.BlockSize:macSize]))
block, err := aes.NewCipher(key); if err != nil {
return "", err
}
cbc := cipher.NewCBCDecrypter(block, iv)
cbc.CryptBlocks(plainText, cipherText[aes.BlockSize:macSize])
return string(UnPadByPkcs7(plainText)), nil
}
その他
AES +CBC +パディング + hmacでためしたが、 AES +GCMで全てやりたかったことが出来るみたいなので、次回はそちらを試してみる.
Author And Source
この問題について(GoでAESアルゴリズム(CBCモード)+PKCS7パディング+HMACを使った実装をする), 我々は、より多くの情報をここで見つけました https://qiita.com/ken5scal/items/82d15c2f51c71759fcb9著者帰属:元の著者の情報は、元のURLに含まれています。著作権は原作者に属する。
Content is automatically searched and collected through network algorithms . If there is a violation . Please contact us . We will adjust (correct author information ,or delete content ) as soon as possible .