一、3DES加密
DES是一个经典的对称加密算法,但也缺陷明显,即56位的密钥安全性不足,已被证实可以在短时间内破解。为解决此问题,出现了3DES,也称Triple DES,3DES为DES向AES过渡的加密算法,它使用3条56位的密钥对数据进行三次加密。为了兼容普通的DES,3DES并没有直接使用 加密->加密->加密 的方式,而是采用了加密->解密->加密 的方式。
当三重密钥均相同时,前两步相互抵消,相当于仅实现了一次加密,因此可实现对普通DES加密算法的兼容。
二、3DES解密
3DES解密过程,与加密过程相反,即逆序使用密钥。是以密钥3、密钥2、密钥1的顺序执行 解密->加密->解密。
相比DES,3DES因密钥长度变长,安全性有所提高,但其处理速度不高。因此又出现了AES加密算法,AES较于3DES速度更快、安全性更高。
三、Go语言使用3DES算法
对比DES,发现只是换了NewTripleDESCipher。不过,需要注意的是,密钥长度必须24byte,否则直接返回错误。
package mainimport ("crypto/des""bytes""crypto/cipher""fmt"
)//为最后一组填充数据
func PaddingText(src []byte,blockSize int)[]byte{length := len(src)%blockSize//获取需要填充的字节数padding := blockSize-length//填充数据paddText := bytes.Repeat([]byte{byte(padding)},padding)//将填充数据追加到原始数据newText := append(src,paddText...)return newText
}func UnPaddingText(src []byte) []byte{length := len(src)//取出原始数据最后一个字节number := int(src[length-1])//去除填充数据newText := src[:length-number]return newText
}//使用DES算法对文件进行加密
//src:需要被加密的明文
//key:秘钥
func EncryptDES(src,key []byte)([]byte,error){//生成加密用的blockblock, err := des.NewTripleDESCipher(key)if err!=nil{return []byte(""),err}length := block.BlockSize()//拼接数据src = PaddingText(src,length)//NewCBCEncrypter第二个参数是初始化向量,长度要求和块大小一样,内容随意(需要和解密初始化向量相同)//根据块和向量创建CBC加密模式blockMode := cipher.NewCBCEncrypter(block,key[:block.BlockSize()])//创建切片,用于存储加密之后的密文dest := make([]byte,len(src))//加密blockMode.CryptBlocks(dest,src)return dest,nil
}//使用DES算法解密
//src:需要被解密的密文
//key:秘钥,需要和加密时使用的秘钥相同
func DecryptDES(src,key []byte)([]byte,error){block, err := des.NewTripleDESCipher(key)if err != nil{return []byte(""),err}//准备初始化向量//创建解密模式blockMode := cipher.NewCBCDecrypter(block,key[:block.BlockSize()])//创建切片,用于存储解密之后的明文dest := make([]byte,len(src))//解密blockMode.CryptBlocks(dest,src)NewText := UnPaddingText(dest)return NewText,nil
}func main(){src := []byte("单枪匹马你别怕,一腔孤勇又如何!")key := []byte("12345678")ciphertext,err := EncryptDES(src,key)if err != nil{fmt.Println("Encrypt err:",err)return}fmt.Printf("%x\n",ciphertext)plaintext,err := DecryptDES(ciphertext,key)if err != nil{fmt.Println("Decrypt err:",err)return}fmt.Println(string(plaintext))
}