巴比特论坛

发表于 2018-6-8 09:36:38 | 显示全部楼层
微信图片_20180524162734.jpg

AES加密常用的概念

加密模式
ECB模式 全称Electronic Codebook模式,译为电子密码本模式
CBC模式 全称Cipher Block Chaining模式,译为密文分组链接模式
CFB模式 全称Cipher FeedBack模式,译为密文反馈模式
OFB模式 全称Output Feedback模式,译为输出反馈模式。
CTR模式 全称Counter模式,译为计数器模式。
初始向量
当加密第一个明文分组时,由于不存在 “前一个密文分组”,因此需要事先准备一个长度为一个分组的比特序列来代替 “前一个密文分组”,这个比特序列称为初始化向量(InitializationVector),通常缩写为 IV。
填充方式
当明文长度不为分组长度的整数倍时,需要在最后一个分组中填充一些数据使其凑满一个分组长度。
NoPadding
API或算法本身不对数据进行处理,加密数据由加密双方约定填补算法。例如若对字符串数据进行加解密,可以补充\0或者空格,然后trim
PKCS5Padding
加密前:数据字节长度对8取余,余数为m,若m>0,则补足8-m个字节,字节数值为8-m,即差几个字节就补几个字节,字节数值即为补充的字节数,若为0则补充8个字节的8
解密后:取最后一个字节,值为m,则从数据尾部删除m个字节,剩余数据即为加密前的原文。
加密字符串为为AAA,则补位为AAA55555;加密字符串为BBBBBB,则补位为BBBBBB22;加密字符串为CCCCCCCC,则补位为CCCCCCCC88888888。
PKCS7Padding
PKCS7Padding 的填充方式和PKCS5Padding 填充方式一样。只是加密块的字节数不同。PKCS5Padding明确定义了加密块是8字节,PKCS7Padding加密快可以是1-255之间。

实现 AES 加密和解密

使用CBC模式+PKCS7 填充方式实现AES的加密和解密
package main

import (
    "bytes"
    "crypto/cipher"
    "crypto/aes"
    "encoding/base64"
    "fmt"
)

func PKCS7Padding(ciphertext []byte, blockSize int) []byte {
    padding := blockSize - len(ciphertext) % blockSize
    padtext := bytes.Repeat([]byte{byte(padding)}, padding)
    return append(ciphertext, padtext...)
}

func PKCS7UnPadding(origData []byte) []byte {
    length := len(origData)
    unpadding := int(origData[length-1])
    return origData[:(length - unpadding)]
}

func AesEncrypt(origData, key []byte) ([]byte, error) {
    block, err := aes.NewCipher(key)
    if err != nil {
        return nil, err
    }
    blockSize := block.BlockSize()
    origData = PKCS7Padding(origData, blockSize)
    blockMode := cipher.NewCBCEncrypter(block, key[:blockSize])
    crypted := make([]byte, len(origData))
    blockMode.CryptBlocks(crypted, origData)
    return crypted, nil
}

func AesDecrypt(crypted, key []byte) ([]byte, error) {
    block, err := aes.NewCipher(key)
    if err != nil {
        return nil, err
    }
    blockSize := block.BlockSize()
    blockMode := cipher.NewCBCDecrypter(block, key[:blockSize])
    origData := make([]byte, len(crypted))
    blockMode.CryptBlocks(origData, crypted)
    origData = PKCS7UnPadding(origData)
    return origData, nil
}

func main() {
    key := []byte("0123456789abcdef")
    result, err := AesEncrypt([]byte("hello world"), key)
    if err != nil {
        panic(err)
    }
    fmt.Println(base64.StdEncoding.EncodeToString(result))
    origData, err := AesDecrypt(result, key)
    if err != nil {
        panic(err)
    }
    fmt.Println(string(origData))
}
运行结果:
$ go run aes.go

wem0Upqsl5MBD0Z39jWO/g==
hello world

4条回复 跳转到指定楼层

Peeta | 副船长 | 发表于 2018-6-8 09:51:49 | 显示全部楼层
懂的人不用讲 不懂的讲也不懂 再说这东西跟区块链也没啥关系
bitsbetter | 海盗王 | 发表于 2018-6-8 10:43:30 | 显示全部楼层
收藏了。请继续。
bitsbetter | 海盗王 | 发表于 2018-6-8 10:45:03 | 显示全部楼层
收藏了。请继续。
任凭那时光流逝 | 船长 | 发表于 2018-6-8 10:56:18 | 显示全部楼层
听不懂。。。。。
高级模式
您需要登录后才可以发帖 登录 | 立即注册 | 用新浪微博登录

本版积分规则

搜索

0关注 1粉丝 104主题

作者的其他主题

返回顶部 返回列表

登录

分享 发帖