Created
December 10, 2016 09:34
-
-
Save ken5scal/b2c182724ae05be5d6964ad47b5acced to your computer and use it in GitHub Desktop.
GoでAESアルゴリズム(CBCモード)+PKCS7パディングを使った実装をする ref: http://qiita.com/ken5scal/items/538febf69f9ac98ab292
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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 | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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