程序员首页投稿(暂停使用,暂停投稿)golang研究所

对称加密算法和分组密码的模式

2017-05-14  本文已影响3309人  linjinhe
  • 对称加密算法,即加密和解密使用一样的密钥的加解密算法。
  • 分组密码(block cipher),是每次只能处理特定长度的一块(block)数据的一类加解密算法。
  • 目前常见的对称加密算法DES、3DES、AES都是属于分组密码。

DES

DES加密 DES解密

3DES

注:E表示Encrypt,D表示Decrypt。

3DES加密 3DES解密

AES

分组密码的模式

分组密码简介

ECB模式

ECB加密 ECB解密

CBC模式

CBC加密 CBC解密

CFB模式

CFB加密 CFB解密

OFB模式

OFB加密 OFB解密

分组模式小结

推荐使用CBC模式。

填充

示例

这里用golang写一个AES加密的例子。

由于加密出来的数据很可能有很多不可见字符,因此这里会将加密后的结果进行一次Base64Encode。

这里采用CBC模式+PKCS7填充方式。

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))
}

参考文档

上一篇 下一篇

猜你喜欢

热点阅读