Aes加密/解密

模式
填充
密钥
偏移量

示例代码

  • aes加解密-go语言版
      1package main
                  2
                  3import (
                  4	"bytes"
                  5	"crypto/aes"
                  6	"crypto/cipher"
                  7	"errors"
                  8	"fmt"
                  9)
                 10
                 11func main() {
                 12	str := "www.lovefree.cc"
                 13	key := "aeskeyisverygood"
                 14	data, err := AesEncrypt([]byte(str), []byte(key))
                 15	if err != nil {
                 16		fmt.Println(err)
                 17		return
                 18	}
                 19	fmt.Println(string(data))
                 20	data, err = AesDecrypt(data, []byte(key))
                 21	if err != nil {
                 22		fmt.Println(err)
                 23		return
                 24	}
                 25	fmt.Println(string(data))
                 26}
                 27
                 28func AesDecrypt(crypted, key []byte) ([]byte, error) {
                 29	block, err := aes.NewCipher(key)
                 30	if err != nil {
                 31		return nil, err
                 32	}
                 33	blockMode := NewECBDecrypter(block)
                 34	origData := make([]byte, len(crypted))
                 35	blockMode.CryptBlocks(origData, crypted)
                 36	origData = PKCS5UnPadding(origData)
                 37	return origData, nil
                 38}
                 39
                 40func AesEncrypt(content, key []byte) ([]byte, error) {
                 41	block, err := aes.NewCipher(key)
                 42	if err != nil {
                 43		return nil, err
                 44	}
                 45	if len(content) == 0 {
                 46		return nil, errors.New("plain content empty")
                 47	}
                 48	ecb := NewECBEncrypter(block)
                 49	content = PKCS5Padding(content, block.BlockSize())
                 50	crypted := make([]byte, len(content))
                 51	ecb.CryptBlocks(crypted, content)
                 52	return crypted, nil
                 53}
                 54
                 55func PKCS5Padding(ciphertext []byte, blockSize int) []byte {
                 56	padding := blockSize - len(ciphertext)%blockSize
                 57	padtext := bytes.Repeat([]byte{byte(padding)}, padding)
                 58	return append(ciphertext, padtext...)
                 59}
                 60
                 61func PKCS5UnPadding(origData []byte) []byte {
                 62	length := len(origData)
                 63	unpadding := int(origData[length-1])
                 64	return origData[:(length - unpadding)]
                 65}
                 66
                 67// ECB
                 68type ecb struct {
                 69	b         cipher.Block
                 70	blockSize int
                 71}
                 72
                 73func newECB(b cipher.Block) *ecb {
                 74	return &ecb{
                 75		b:         b,
                 76		blockSize: b.BlockSize(),
                 77	}
                 78}
                 79
                 80type ecbEncrypter ecb
                 81
                 82// NewECBEncrypter returns a BlockMode which encrypts in electronic code book
                 83// mode, using the given Block.
                 84func NewECBEncrypter(b cipher.Block) cipher.BlockMode {
                 85	return (*ecbEncrypter)(newECB(b))
                 86}
                 87func (x *ecbEncrypter) BlockSize() int { return x.blockSize }
                 88func (x *ecbEncrypter) CryptBlocks(dst, src []byte) {
                 89	if len(src)%x.blockSize != 0 {
                 90		panic("crypto/cipher: input not full blocks")
                 91	}
                 92	if len(dst) < len(src) {
                 93		panic("crypto/cipher: output smaller than input")
                 94	}
                 95	for len(src) > 0 {
                 96		x.b.Encrypt(dst, src[:x.blockSize])
                 97		src = src[x.blockSize:]
                 98		dst = dst[x.blockSize:]
                 99	}
                100}
                101
                102type ecbDecrypter ecb
                103
                104// NewECBDecrypter returns a BlockMode which decrypts in electronic code book
                105// mode, using the given Block.
                106func NewECBDecrypter(b cipher.Block) cipher.BlockMode {
                107	return (*ecbDecrypter)(newECB(b))
                108}
                109func (x *ecbDecrypter) BlockSize() int { return x.blockSize }
                110func (x *ecbDecrypter) CryptBlocks(dst, src []byte) {
                111	if len(src)%x.blockSize != 0 {
                112		panic("crypto/cipher: input not full blocks")
                113	}
                114	if len(dst) < len(src) {
                115		panic("crypto/cipher: output smaller than input")
                116	}
                117	for len(src) > 0 {
                118		x.b.Decrypt(dst, src[:x.blockSize])
                119		src = src[x.blockSize:]
                120		dst = dst[x.blockSize:]
                121	}
                122}
                
  • aes加解密-js语言版
     1const txt = 'Message';
                 2const key = 'Secret Passphrase';
                 3const iv = '';
                 4
                 5// 加密
                 6function encrypt(text) {
                 7    return CryptoJS.AES.encrypt(text, CryptoJS.enc.Utf8.parse(key), {
                 8        iv: CryptoJS.enc.Utf8.parse(iv),
                 9        mode: CryptoJS.mode.CBC,
                10        padding: CryptoJS.pad.Pkcs7
                11    }).toString()
                12}
                13
                14// 解密
                15function decrypt(text) {
                16    let decrypted = CryptoJS.AES.decrypt(text, CryptoJS.enc.Utf8.parse(key), {
                17        iv: CryptoJS.enc.Utf8.parse(iv),
                18        mode: CryptoJS.mode.CBC,
                19        padding: CryptoJS.pad.Pkcs7
                20    });
                21    return decrypted.toString(CryptoJS.enc.Utf8)
                22}
                23
                24const sign = encrypt(txt);
                25console.log('加密:', sign);
                26const _src = decrypt(sign);
                27console.log('解密:', _src);

小知识

密码学中的高级加密标准(Advanced Encryption Standard,AES),又称Rijndael加密法,是美国联邦政府采用的一种区块加密标准。

对称/分组密码一般分为流加密(如OFB、CFB等)和块加密(如ECB、CBC等)。对于流加密,需要将分组密码转化为流模式工作。对于块加密(或称分组加密),如果要加密超过块大小的数据,就需要涉及填充和链加密模式。