Because the project needs to use a special encryption and decryption algorithm Golang AES/ECB/PKCS5, but the algorithm is not included in the standard library, after many unsuccessful attempts, finally decoding success, hereby share:
/ *
Figure: golang AES / ECB / PKCS5 encryption and decryption
date: 2016-04-08
author: herohenu
* /
package main
import (
"bytes"
"crypto / aes"
"crypto / cipher"
"encoding / base64"
"fmt"
"strings"
)
func main () {
/ *
* src string to be encrypted
* key The key used for encryption. The key length can be any of 128bit, 192bit, and 256bit.
* 16-bit key corresponds to 128bit
* /
src: = "0.56"
key: = "0123456789abcdef"
crypted: = AesEncrypt (src, key)
AesDecrypt (crypted, [] byte (key))
Base64URLDecode ("39W7dWTd_SBOCM8UbnG6qA")
}
func Base64URLDecode (data string) ([] byte, error) {
var missing = (4-len (data)% 4)% 4
data + = strings.Repeat ("=", missing)
res, err: = base64.URLEncoding.DecodeString (data)
fmt.Println ("decodebase64urlsafe is:", string (res), err)
return base64.URLEncoding.DecodeString (data)
}
func Base64UrlSafeEncode (source [] byte) string {
// Base64 Url Safe is the same as Base64 but does not contain ‘/‘ and ‘+‘ (replaced by ‘_’ and ‘-’) and trailing ‘=‘ are removed.
bytearr: = base64.StdEncoding.EncodeToString (source)
safeurl: = strings.Replace (string (bytearr), "/", "_", -1)
safeurl = strings.Replace (safeurl, "+", "-", -1)
safeurl = strings.Replace (safeurl, "=", "", -1)
return safeurl
}
func AesDecrypt (crypted, key [] byte) [] byte {
block, err: = aes.NewCipher (key)
if err! = nil {
fmt.Println ("err is:", err)
}
blockMode: = NewECBDecrypter (block)
origData: = make ([] byte, len (crypted))
blockMode.CryptBlocks (origData, crypted)
origData = PKCS5UnPadding (origData)
fmt.Println ("source is:", origData, string (origData))
return origData
}
func AesEncrypt (src, key string) [] byte {
block, err: = aes.NewCipher ([] byte (key))
if err! = nil {
fmt.Println ("key error1", err)
}
if src == "" {
fmt.Println ("plain content empty")
}
ecb: = NewECBEncrypter (block)
content: = [] byte (src)
content = PKCS5Padding (content, block.BlockSize ())
crypted: = make ([] byte, len (content))
ecb.CryptBlocks (crypted, content)
// ordinary base64 encoding encryption is different from urlsafe base64
fmt.Println ("base64 result:", base64.StdEncoding.EncodeToString (crypted))
fmt.Println ("base64UrlSafe result:", Base64UrlSafeEncode (crypted))
return crypted
}
func PKCS5Padding (ciphertext [] byte, blockSize int) [] byte {
padding: = blockSize-len (ciphertext)% blockSize
padtext: = bytes.Repeat ([] byte (byte (padding)}, padding)
return append (ciphertext, padtext ...)
}
func PKCS5UnPadding (origData [] byte) [] byte {
length: = len (origData)
// remove the last byte unpadding times
unpadding: = int (origData [length-1])
return origData [:( length-unpadding)]
}
type ecb struct {
b cipher.Block
blockSize int
}
func newECB (b cipher.Block) * ecb {
return & ecb {
b: b,
blockSize: b.BlockSize (),
}
}
type ecbEncrypter ecb
// NewECBEncrypter returns a BlockMode which encrypts in electronic code book
// mode, using the given Block.
func NewECBEncrypter (b cipher.Block) cipher.BlockMode {
return (* ecbEncrypter) (newECB (b))
}
func (x * ecbEncrypter) BlockSize () int {return x.blockSize}
func (x * ecbEncrypter) CryptBlocks (dst, src [] byte) {
if len (src)% x.blockSize! = 0 {
panic ("crypto / cipher: input not full blocks")
}
if len (dst) <len (src) {
panic ("crypto / cipher: output smaller than input")
}
for len (src)> 0 {
x.b.Encrypt (dst, src [: x.blockSize])
src = src [x.blockSize:]
dst = dst [x.blockSize:]
}
}
type ecbDecrypter ecb
// NewECBDecrypter returns a BlockMode which decrypts in electronic code book
// mode, using the given Block.
func NewECBDecrypter (b cipher.Block) cipher.BlockMode {
return (* ecbDecrypter) (newECB (b))
}
func (x * ecbDecrypter) BlockSize () int {return x.blockSize}
func (x * ecbDecrypter) CryptBlocks (dst, src [] byte) {
if len (src)% x.blockSize! = 0 {
panic ("crypto / cipher: input not full blocks")
}
if len (dst) <len (src) {
panic ("crypto / cipher: output smaller than input")
}
for len (src)> 0 {
x.b.Decrypt (dst, src [: x.blockSize])
src = src [x.blockSize:]
dst = dst [x.blockSize:]
}
}
This is the author of a number of blogs and code, if you think this article is helpful to you, welcome to enjoy a cup of coffee as an encouragement to the author, thank you!
Acknowledgement:
aes:http://blog.studygolang.com/tag/aes_encrypt/of Go encryption and decryption
Yinheli:https://gist.github.com/yinheli/3370e0e901329b639be4
Golang AES/ECB/PKCS5 Encryption and decryption url-safe-base64