对称加密

对称加密算法是相对于非对称加密算法而言,两者的区别在于,对称加密和加密和解密时使用相同的秘钥,而非对称加密在加密和解密时使用不同的秘钥(公钥和私钥)。常见的对称加密算法:DES3DESAES

DES

DES的基础结构,由IBM公司的Horst Feistel设计,因此称Feistel网络。在Feistel网络中,加密的每个步骤称为轮,经过初始置换后的64位明文,进行了16轮Feistel轮的加密过程,最后经过终结置换后形成最终的64位密文,如下图:

clipboard.png

go实现DES

package main

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

//利用秘钥通过DES算法实现明文的加密
//利用秘钥通过DES算法实现密文的解密

//在加密和解密之前,首先需要补码和去码的操作

//补码
func PKCS5Padding(orgData []byte, blockSize int) [] byte {
    //abc55555
    padding := blockSize - len(orgData)%8
    padtxt := bytes.Repeat([]byte{byte(padding)}, padding)
    return append(orgData, padtxt...)

}

//去码
func PKCS5UnPadding(cipherTxt []byte) []byte {
    length := len(cipherTxt)
    unpadding := int(cipherTxt[length-1])
    return cipherTxt[:length-unpadding]
    //cipherTxt[:4]

}

//DES加密,加密会用到补码
func DesEncrypt(orig []byte, key []byte) []byte {
    //首先检验秘钥是否合法
    //DES加密算法,秘钥的长度必须为8bit block.BlockSize() = 8;
    block, _ := des.NewCipher(key)
    //补码
    origData := PKCS5Padding(orig, block.BlockSize())
    //设置加密方式
    blockMode := cipher.NewCBCEncrypter(block, key)
    //加密处理
    crypted := make([]byte, len(origData)) //存放加密后的密文
    blockMode.CryptBlocks(crypted, origData)
    return crypted
}

//DES解密,解密要用到去码
func DesDecrypt(cipherTxt []byte, key []byte) [] byte {
    //校验key的有效性
    block, _ := des.NewCipher(key)
    //设置解码方式
    blockMode := cipher.NewCBCDecrypter(block, key)
    //创建缓冲,存放解密后的数据
    orgData := make([]byte, len(cipherTxt))
    //开始解密
    blockMode.CryptBlocks(orgData, cipherTxt)
    //去掉编码
    orgData = PKCS5UnPadding(orgData)
    return orgData
}

func main() {

    //pad:=PKCS5Padding([]byte("abcd"),8)
    //fmt.Println(pad)
    var cipherTxt = DesEncrypt([]byte("kongyixueyuan"), []byte("12345678"))
    fmt.Println(cipherTxt)
    //通过base64处理秘文
    fmt.Println(base64.StdEncoding.EncodeToString(cipherTxt))

    //解码
    var plainText = DesDecrypt(cipherTxt, []byte("12345678"))
    fmt.Println(string(plainText))

    //对称加密中,加密与解密是互逆的

    //DES加密中秘钥长度必须为8字节,3DES秘钥长度必须为24,AES加密算法中秘钥长度必须为16或24或32字节
}
  • DES加密中秘钥长度必须为8字节
  • 在加密前需要补码操作(比如abc加密前,补码到8位:abc55555)
  • 在解密后需要去码操作

3DES

DES的56位的秘钥安全性不足,已被证实可以在短时间破解,为解决此问题,出现了3DES。3DES为DES向AES过渡的加密算法,它使用3条56位的秘钥对数据进行3次加密。为兼容普通的DES,3DES并没有直接使用加密->加密->加密的方式。

加密

clipboard.png

当三重秘钥均相同时,前两步相互抵消,相当于仅实现了一次加密,因此可以实现对普通DES加密算法的兼容。

clipboard.png

解密

与加密过程相反,是以秘钥3、秘钥2、秘钥1的顺序执行解密->加密->解密

AES

3DES因秘钥长度变长,安全性提升,但处理速度不高。因此又出现了AES加密算法。AES比3DES速度更快,安全性更高。
AES全称Advanced Encryption Standard,即:高级加密标准。AES加密算法中秘钥长度必须为16或24或32字节

go实现aes

package main

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

//PKCS5的分组是以8为单位
//PKCS7的分组长度为1-255
func PKCS7Padding(org []byte, blockSize int) []byte {
    pad := blockSize - len(org)%blockSize
    padArr := bytes.Repeat([]byte{byte(pad)}, pad)
    return append(org, padArr...)
}

//通过AES方式解密密文
func PKCS7UnPadding(org []byte) []byte {
    //abcd4444
    l := len(org)
    pad := org[l-1]
    //org[0:4]
    return org[:l-int(pad)]
}

func AESDecrypt(cipherTxt []byte, key []byte) []byte {
    block, _ := aes.NewCipher(key)
    blockMode := cipher.NewCBCDecrypter(block, key)
    //创建明文缓存
    org := make([]byte, len(cipherTxt))
    //开始解密
    blockMode.CryptBlocks(org, cipherTxt)

    //去码
    org = PKCS7UnPadding(org)
    //返回明文
    return org

}

//AES加密
func AESEncrypt(org []byte, key [] byte) []byte {
    //检验秘钥
    block, _ := aes.NewCipher(key)
    //对明文进行补码
    org = PKCS7Padding(org, block.BlockSize())
    //设置加密模式
    blockMode := cipher.NewCBCEncrypter(block, key)

    //创建密文缓冲区
    cryted := make([]byte, len(org))
    //加密
    blockMode.CryptBlocks(cryted, org)
    //返回密文
    return cryted

}

func main() {
    var Encode = AESEncrypt([]byte("kongyixueyuan"), []byte("1234567890123456"))
    fmt.Println(base64.StdEncoding.EncodeToString(Encode))

    fmt.Println("名文为:", string(AESDecrypt([]byte(Encode), []byte("1234567890123456"))))
}

分组模式

  • ECB:Electronic CodeBook mode (电子密码模式)
  • CBC:Cipher Block Chaining mode(密码分组链接模式)
  • CFB:Cipher FeedBack mode (密文反馈模式)
  • OFB:Output FeedBack mode (输出反馈模式)
  • CTR:CounTeR mode (计数器模式)

ECB

  • ECB模式是所有模式中最简单的一种。ECB的明文分组和密文分组是一一对应关系,因此,如果明文中存在多个相同的明文分组,则这些明文分组最终都会转换成相同的密文分组。这样一来,只要观察一下密文,就可以知道明文中存在怎样的重复组合,并可以以此为线索来破译密码,因此ECB模式是存在风险的。

clipboard.png

clipboard.png

CBC

  • 明文分组在加密之前一定会与“前一个密文分组”进行XOR运算,因此即便明文分组1和2的值是相等的,密文分组1和2也不一定相等,这样ECB模式的缺陷在CBC模式中就不存在了。
  • 在CBC模式中,无法单独对一个中间的明文分组进行加密。例如,如果要生成密文分组3,则至少需要凑齐分组1、2、3才行。
  • 如果密文分组中有一些比特缺失了,即便只缺失了1比特,那么缺失比特的位置之后的密文分组也就全部无法解密了。

clipboard.png

clipboard.png

在上述的机密代码中,采用的就是CBC模式加密。

blockMode := cipher.NewCBCEncrypter(block, key)

jincheng828
49 声望9 粉丝

在奔向财富自由的路上...