Skip to content

Instantly share code, notes, and snippets.

@ken5scal
Created December 10, 2016 09:34
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save ken5scal/b2c182724ae05be5d6964ad47b5acced to your computer and use it in GitHub Desktop.
Save ken5scal/b2c182724ae05be5d6964ad47b5acced to your computer and use it in GitHub Desktop.
GoでAESアルゴリズム(CBCモード)+PKCS7パディングを使った実装をする ref: http://qiita.com/ken5scal/items/538febf69f9ac98ab292
func PadByPkcs7(data []byte) []byte {
padSize := aes.BlockSize
if len(data) % aes.BlockSize != 0 {
padSize = aes.BlockSize - (len(data)) % aes.BlockSize
}
pad := bytes.Repeat([]byte{byte(padSize)}, padSize)
return append(data, pad...) // Dots represent it unpack Slice(pad) into individual bytes
}
func UnPadByPkcs7(data []byte) []byte {
padSize := int(data[len(data) - 1])
return data[:len(data) - padSize]
}
func EncryptByCBCMode(key []byte, plainText string) ([]byte, error) {
//if len(plainText) % aes.BlockSize != 0 { <-いらなくなった
// panic("Plain text must be multiple of 128bit")
//}
block, err := aes.NewCipher(key); if err != nil {
return nil, err
}
paddedPlaintext := PadByPkcs7([]byte(plainText))
fmt.Printf("Padded Plain Text in byte format: %v\n", paddedPlaintext)
cipherText := make([]byte, aes.BlockSize + len(paddedPlaintext)) // cipher text must be larger than plaintext
iv := cipherText[:aes.BlockSize] // Unique iv is required
_, err = rand.Read(iv); if err != nil {
return nil, err
}
cbc := cipher.NewCBCEncrypter(block, iv)
cbc.CryptBlocks(cipherText[aes.BlockSize:], paddedPlaintext)
cipherTextBase64 := base64.StdEncoding.EncodeToString(cipherText)
return []byte(cipherTextBase64), nil
}
func DecryptByCBCMode(key []byte, cipherTextBase64 []byte) (string, error) {
block, err := aes.NewCipher(key); if err != nil {
return "", err
}
cipherText, _ := base64.StdEncoding.DecodeString(string(cipherTextBase64))
if len(cipherText) < aes.BlockSize {
panic("cipher text must be longer than blocksize")
} else if len(cipherText) % aes.BlockSize != 0 {
panic("cipher text must be multiple of blocksize(128bit)")
}
iv := cipherText[:aes.BlockSize] // assuming iv is stored in the first block of ciphertext
cipherText = cipherText[aes.BlockSize:]
plainText := make([]byte, len(cipherText))
cbc := cipher.NewCBCDecrypter(block, iv)
cbc.CryptBlocks(plainText, cipherText)
return string(UnPadByPkcs7(plainText)), nil
}
func main() {
plainText = "12345" // Paddingしないとエラーになる平文
cipherText, _ = EncryptByCBCMode(key, plainText)
fmt.Printf("Plaintext %v is encrypted into %v:\n", plainText, cipherText)
decryptedText,_ = DecryptByCBCMode(key, cipherText)
fmt.Printf("Decrypted Text: %v\n ", decryptedText)
}
>>
|-> こっからパディング
Padded Plain Text in byte format: [49 50 51 52 53 11 11 11 11 11 11 11 11 11 11 11]
Plaintext 12345 is encrypted into [116 51 109 107 87 53 103 43 86 65 114 73 104 99 75 97 85 76 121 71 109 90 122 70 83 122 90 120 98 102 112 72 43 74 111 69 48 76 79 97 98 69 56 61]:
Decrypted Text: 12345
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment