go使用des加密

一、DES算法簡(jiǎn)介

DES(Data Encryption Standard)是一種常見的分組加密算法植锉,由IBM公司在1971年提出辫樱。它是一種對(duì)稱加密算法,也就是說它使用同一個(gè)密鑰來加密和解密數(shù)據(jù)俊庇。

二狮暑、密鑰

DES使用一個(gè)56位的初始密鑰,但是這里提供的是一個(gè)64位的值辉饱,這是因?yàn)樵谟布?shí)現(xiàn)中每8位可以用于奇偶校驗(yàn)搬男。可以通過設(shè)定8位字符串彭沼,由crypto/des庫(kù)的des.NewCipher(key)函數(shù)生成密鑰

三缔逛、填充算法

DES分組的大小是64位,如果加密的數(shù)據(jù)長(zhǎng)度不是64位的倍數(shù),可以按照某種具體的規(guī)則來填充位褐奴。常用的填充算法有pkcs5按脚,zero

pkcs5填充

//pkcs5補(bǔ)碼算法
func pkcs5Padding(ciphertext []byte, blockSize int) []byte {
    padding := blockSize - len(ciphertext)%blockSize
    padtext := bytes.Repeat([]byte{byte(padding)}, padding)
    return append(ciphertext, padtext...)
}

//pkcs5減碼算法
func pkcs5UnPadding(origData []byte) []byte {
    length := len(origData)
    unpadding := int(origData[length-1])
    return origData[:(length - unpadding)]
}

zero填充

//zero補(bǔ)碼算法
func zeroPadding(ciphertext []byte, blockSize int) []byte {
    padding := blockSize - len(ciphertext)%blockSize
    padtext := bytes.Repeat([]byte{0}, padding)
    return append(ciphertext, padtext...)
}

//zero減碼算法
func zeroUnPadding(origData []byte) []byte {
    return bytes.TrimFunc(origData,
        func(r rune) bool {
            return r == rune(0)
        })
}

四、加密模式

  • 密碼分組鏈接模式(Cipher Block Chaining敦冬,簡(jiǎn)稱CBC):是一種循環(huán)模式辅搬,前一個(gè)分組的密文和當(dāng)前分組的明文異或操作后再加密,這樣做的目的是增強(qiáng)破解難度脖旱。
  • 電碼本模式(Electronic Codebook Book伞辛,簡(jiǎn)稱ECB):是一種基礎(chǔ)的加密方式,密文被分割成分組長(zhǎng)度相等的塊(不足補(bǔ)齊)夯缺,然后單獨(dú)一個(gè)個(gè)加密蚤氏,一個(gè)個(gè)輸出組成密文。
  • 計(jì)算器模式(Counter踊兜,簡(jiǎn)稱CTR):計(jì)算器模式不常見竿滨,在CTR模式中, 有一個(gè)自增的算子捏境,這個(gè)算子用密鑰加密之后的輸出和明文異或的結(jié)果得到密文于游,相當(dāng)于一次一密。這種加密方式簡(jiǎn)單快速垫言,安全可靠贰剥,而且可以并行加密,但是在計(jì)算器不能維持很長(zhǎng)的情況下筷频,密鑰只能使用一次蚌成。
  • 輸出反饋模式(Output FeedBack,簡(jiǎn)稱OFB):實(shí)際上是一種反饋模式凛捏,目的也是增強(qiáng)破解的難度担忧。
  • 密碼反饋模式(Cipher FeedBack,簡(jiǎn)稱CFB):實(shí)際上是一種反饋模式坯癣,目的也是增強(qiáng)破解的難度瓶盛。
//---------------DES ECB加密--------------------
// data: 明文數(shù)據(jù)
// key: 密鑰字符串
// 返回密文數(shù)據(jù)
func DesECBEncrypt(data, key []byte) []byte {
    //NewCipher創(chuàng)建一個(gè)新的加密塊
    block, err := des.NewCipher(key)
    if err != nil {
        return nil
    }

    bs := block.BlockSize()
    // pkcs5填充
    data = pkcs5Padding(data, bs)
    if len(data)%bs != 0 {
        return nil
    }

    out := make([]byte, len(data))
    dst := out
    for len(data) > 0 {
        //Encrypt加密第一個(gè)塊,將其結(jié)果保存到dst
        block.Encrypt(dst, data[:bs])
        data = data[bs:]
        dst = dst[bs:]
    }
    return out
}

//---------------DES ECB解密--------------------
// data: 密文數(shù)據(jù)
// key: 密鑰字符串
// 返回明文數(shù)據(jù)
func DesECBDecrypter(data, key []byte) []byte {
    //NewCipher創(chuàng)建一個(gè)新的加密塊
    block, err := des.NewCipher(key)
    if err != nil {
        return nil
    }

    bs := block.BlockSize()
    if len(data)%bs != 0 {
        return nil
    }

    out := make([]byte, len(data))
    dst := out
    for len(data) > 0 {
        //Encrypt加密第一個(gè)塊示罗,將其結(jié)果保存到dst
        block.Decrypt(dst, data[:bs])
        data = data[bs:]
        dst = dst[bs:]
    }

    // pkcs5填充
    out = pkcs5UnPadding(out)

    return out
}

//---------------DES CBC加密--------------------
// data: 明文數(shù)據(jù)
// key: 密鑰字符串
// iv:iv向量
// 返回密文數(shù)據(jù)
func DesCBCEncrypt(data, key, iv []byte) []byte {
    block, err := des.NewCipher(key)
    if err != nil {
        return nil
    }

    // pkcs5填充
    data = pkcs5Padding(data, block.BlockSize())
    cryptText := make([]byte, len(data))

    blockMode := cipher.NewCBCEncrypter(block, iv)
    blockMode.CryptBlocks(cryptText, data)
    return cryptText
}

//---------------DES CBC解密--------------------
// data: 密文數(shù)據(jù)
// key: 密鑰字符串
// iv:iv向量
// 返回明文數(shù)據(jù)
func DesCBCDecrypter(data, key, iv []byte) []byte {
    block, err := des.NewCipher(key)
    if err != nil {
        return nil
    }

    blockMode := cipher.NewCBCDecrypter(block, iv)
    cryptText := make([]byte, len(data))
    blockMode.CryptBlocks(cryptText, data)
    // pkcs5填充
    cryptText = pkcs5UnPadding(cryptText)

    return cryptText
}

//---------------DES CTR加密--------------------
// data: 明文數(shù)據(jù)
// key: 密鑰字符串
// iv:iv向量
// 返回密文數(shù)據(jù)
func DesCTREncrypt(data, key, iv []byte) []byte {
    block, err := des.NewCipher(key)
    if err != nil {
        return nil
    }

    // pkcs5填充
    data = pkcs5Padding(data, block.BlockSize())
    cryptText := make([]byte, len(data))

    blockMode := cipher.NewCTR(block, iv)
    blockMode.XORKeyStream(cryptText, data)
    return cryptText
}

//---------------DES CTR解密--------------------
// data: 密文數(shù)據(jù)
// key: 密鑰字符串
// iv:iv向量
// 返回明文數(shù)據(jù)
func DesCTRDecrypter(data, key, iv []byte) []byte {
    block, err := des.NewCipher(key)
    if err != nil {
        return nil
    }

    blockMode := cipher.NewCTR(block, iv)
    cryptText := make([]byte, len(data))
    blockMode.XORKeyStream(cryptText, data)

    // pkcs5填充
    cryptText = pkcs5UnPadding(cryptText)

    return cryptText
}

//---------------DES OFB加密--------------------
// data: 明文數(shù)據(jù)
// key: 密鑰字符串
// iv:iv向量
// 返回密文數(shù)據(jù)
func DesOFBEncrypt(data, key, iv []byte) []byte {
    block, err := des.NewCipher(key)
    if err != nil {
        return nil
    }

    // pkcs5填充
    data = pkcs5Padding(data, block.BlockSize())
    cryptText := make([]byte, len(data))

    blockMode := cipher.NewOFB(block, iv)
    blockMode.XORKeyStream(cryptText, data)
    return cryptText
}

//---------------DES OFB解密--------------------
// data: 密文數(shù)據(jù)
// key: 密鑰字符串
// iv:iv向量
// 返回明文數(shù)據(jù)
func DesOFBDecrypter(data, key, iv []byte) []byte {
    block, err := des.NewCipher(key)
    if err != nil {
        return nil
    }

    blockMode := cipher.NewOFB(block, iv)
    cryptText := make([]byte, len(data))
    blockMode.XORKeyStream(cryptText, data)

    // pkcs5填充
    cryptText = pkcs5UnPadding(cryptText)

    return cryptText
}

//---------------DES CFB加密--------------------
// data: 明文數(shù)據(jù)
// key: 密鑰字符串
// iv:iv向量
// 返回密文數(shù)據(jù)
func DesCFBEncrypt(data, key, iv []byte) []byte {
    block, err := des.NewCipher(key)
    if err != nil {
        return nil
    }

    // pkcs5填充
    data = pkcs5Padding(data, block.BlockSize())
    cryptText := make([]byte, len(data))

    blockMode := cipher.NewCFBDecrypter(block, iv)
    blockMode.XORKeyStream(cryptText, data)
    return cryptText
}

//---------------DES CFB解密--------------------
// data: 密文數(shù)據(jù)
// key: 密鑰字符串
// iv:iv向量
// 返回明文數(shù)據(jù)
func DesCFBDecrypter(data, key, iv []byte) []byte {
    block, err := des.NewCipher(key)
    if err != nil {
        return nil
    }

    blockMode := cipher.NewCFBEncrypter(block, iv)
    cryptText := make([]byte, len(data))
    blockMode.XORKeyStream(cryptText, data)

    // pkcs5填充
    cryptText = pkcs5UnPadding(cryptText)

    return cryptText
}

五惩猫、測(cè)試

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

func main() {
    key := []byte("12345678")
    src := []byte("這是需要加密的明文哦!")

    // ECB 加密
    cipher := DesECBEncrypt(src, key)

    // 轉(zhuǎn)base64
    bs64 := base64.StdEncoding.EncodeToString(cipher)
    fmt.Println(bs64)

    // 轉(zhuǎn)回byte
    bt, err := base64.StdEncoding.DecodeString(bs64)
    if err != nil {
        fmt.Println("base64轉(zhuǎn)換失敗")
    }
    // ECB 解密
    str := DesECBEncrypt(bt, key)
    fmt.Println(str)
}
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末蚜点,一起剝皮案震驚了整個(gè)濱河市轧房,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌禽额,老刑警劉巖锯厢,帶你破解...
    沈念sama閱讀 217,542評(píng)論 6 504
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異脯倒,居然都是意外死亡实辑,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,822評(píng)論 3 394
  • 文/潘曉璐 我一進(jìn)店門藻丢,熙熙樓的掌柜王于貴愁眉苦臉地迎上來剪撬,“玉大人,你說我怎么就攤上這事悠反〔泻冢” “怎么了?”我有些...
    開封第一講書人閱讀 163,912評(píng)論 0 354
  • 文/不壞的土叔 我叫張陵斋否,是天一觀的道長(zhǎng)梨水。 經(jīng)常有香客問我,道長(zhǎng)茵臭,這世上最難降的妖魔是什么疫诽? 我笑而不...
    開封第一講書人閱讀 58,449評(píng)論 1 293
  • 正文 為了忘掉前任,我火速辦了婚禮旦委,結(jié)果婚禮上奇徒,老公的妹妹穿的比我還像新娘。我一直安慰自己缨硝,他們只是感情好摩钙,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,500評(píng)論 6 392
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著查辩,像睡著了一般胖笛。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上宜岛,一...
    開封第一講書人閱讀 51,370評(píng)論 1 302
  • 那天匀钧,我揣著相機(jī)與錄音,去河邊找鬼谬返。 笑死之斯,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的遣铝。 我是一名探鬼主播佑刷,決...
    沈念sama閱讀 40,193評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼酿炸!你這毒婦竟也來了瘫絮?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,074評(píng)論 0 276
  • 序言:老撾萬榮一對(duì)情侶失蹤填硕,失蹤者是張志新(化名)和其女友劉穎麦萤,沒想到半個(gè)月后鹿鳖,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,505評(píng)論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡壮莹,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,722評(píng)論 3 335
  • 正文 我和宋清朗相戀三年翅帜,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片命满。...
    茶點(diǎn)故事閱讀 39,841評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡涝滴,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出胶台,到底是詐尸還是另有隱情歼疮,我是刑警寧澤,帶...
    沈念sama閱讀 35,569評(píng)論 5 345
  • 正文 年R本政府宣布诈唬,位于F島的核電站韩脏,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏铸磅。R本人自食惡果不足惜骤素,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,168評(píng)論 3 328
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望愚屁。 院中可真熱鬧济竹,春花似錦、人聲如沸霎槐。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,783評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽丘跌。三九已至袭景,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間闭树,已是汗流浹背耸棒。 一陣腳步聲響...
    開封第一講書人閱讀 32,918評(píng)論 1 269
  • 我被黑心中介騙來泰國(guó)打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留报辱,地道東北人与殃。 一個(gè)月前我還...
    沈念sama閱讀 47,962評(píng)論 2 370
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像碍现,于是被迫代替她去往敵國(guó)和親幅疼。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,781評(píng)論 2 354

推薦閱讀更多精彩內(nèi)容