亚洲视频二区_亚洲欧洲日本天天堂在线观看_日韩一区二区在线观看_中文字幕不卡一区

公告:魔扣目錄網(wǎng)為廣大站長提供免費(fèi)收錄網(wǎng)站服務(wù),提交前請做好本站友鏈:【 網(wǎng)站目錄:http://www.430618.com 】, 免友鏈快審服務(wù)(50元/站),

點(diǎn)擊這里在線咨詢客服
新站提交
  • 網(wǎng)站:51998
  • 待審:31
  • 小程序:12
  • 文章:1030137
  • 會(huì)員:747

密碼學(xué)系列 - 對稱加密

本文討論的對稱加密算法主要包括 DES、3DES、AES

DES

明文:64 bit 密文:64 bit 密鑰:56/64 bit(每 7 位插入一個(gè)校驗(yàn)位的時(shí)候?yàn)?64 bit) 其設(shè)計(jì)思想充分體現(xiàn)了香農(nóng)提出的混淆和擴(kuò)散原則

密碼學(xué)系列 - 對稱加密

 

DES 使用的是 Feistel 結(jié)構(gòu)來加密的,一共需要 16 輪,加密過程如下:

  1. 將明文進(jìn)行初始置換(通過置換表)
  2. 將置換后的數(shù)據(jù)分為左右 L1 R1 各 32 bit
  3. 將 48 bit 的子密鑰與 R1 作為輪函數(shù)F的輸入
  4. 將 L1 與輪函數(shù)的輸出異或運(yùn)算,得到 L1密文
  5. 將 L1 密文與 R1 交換位置,分別作為下一輪的 R2,L2
  6. 將 2-5 再重復(fù) 15 次
  7. 將 L17 R17 交換位置,并拼接為 64bit 數(shù)據(jù)
  8. 將 64bit 數(shù)據(jù)進(jìn)行逆初始置換,得到最終密文

需要注意的是:

  • 子密鑰在每一輪中都是不一樣的
  • 每一輪之間會(huì)將左側(cè)和右側(cè)對調(diào)(右側(cè)沒有加密)
  • 解密的過程就是將輸出用相同的子密鑰再走一遍,如果加密的子密鑰順序是key1 key2 key3,則解密的子密鑰為key3 key2 key1
  • 輪函數(shù)可以設(shè)計(jì)為不可逆函數(shù)如hash,對解密沒有影響
密碼學(xué)系列 - 對稱加密

 

golang 代碼實(shí)戰(zhàn):

func TestDesEncrypt(t *testing.T) {
	key:=[]byte{0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01}
	cipherBlock,err:=des.NewCipher(key)
	if err!=nil{
		t.Error(err)
	}
	src:=[]byte{0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08}
	encrptDst :=make([]byte,len(src))
	cipherBlock.Encrypt(encrptDst,src)
	t.Log(encrptDst)
	plainDst:=make([]byte,len(encrptDst))
	cipherBlock.Decrypt(plainDst, encrptDst)
	t.Log(plainDst)
}

//out: [206 173 55 61 184 14 171 248]
//out: [1 2 3 4 5 6 7 8]

三重DES

明文:64 bit 密文:64 bit 密鑰:56/64 * 3 bit(加入校驗(yàn)位的時(shí)候?yàn)?4 bit)

為了增加 DES 的強(qiáng)度,明文經(jīng)過 3 次 DES 處理后變成最后的密文,因此密鑰長度為 56/64 * 3 bit。3 次 DES 處理并不是簡單的 3 次加密的過程,而是加密、解密、加密,解密的過程相應(yīng)的就是解密、解密、解密。這樣設(shè)計(jì)是因?yàn)樵?3 個(gè)密鑰相同時(shí),可以兼容 DES 算法

密碼學(xué)系列 - 對稱加密

 

golang 代碼實(shí)戰(zhàn):

func TestTripleDesEncrypt(t *testing.T) {
	key:=[]byte{0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,
	0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01}
	cipherBlock,err:=des.NewTripleDESCipher(key)
	if err!=nil{
		t.Error(err)
	}
	src:=[]byte{0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08}
	encrptDst :=make([]byte,len(src))
	cipherBlock.Encrypt(encrptDst,src)
	t.Log(encrptDst)
	plainDst:=make([]byte,len(encrptDst))
	cipherBlock.Decrypt(plainDst, encrptDst)
	t.Log(plainDst)
}

//此處3個(gè)密鑰相同,兼容DES
//out: [206 173 55 61 184 14 171 248]
//out: [1 2 3 4 5 6 7 8]

AES

明文:128 bit 密文:128 bit 密鑰:128/192/256 bit (分別需要10/12/14輪)

AES 標(biāo)準(zhǔn)最后評選出的算法是 Rijindale 算法,該算法支持密鑰 128/192/256 bit ,分別需要 10/12/14 輪,本文討論的是 128 bit密鑰。它的加密過程并沒有使用 DES 的 feistel 結(jié)構(gòu),而是使用了一種新的 SPN 結(jié)構(gòu),需要 10-14 輪計(jì)算,如下圖:

密碼學(xué)系列 - 對稱加密

 

其中每一輪計(jì)算過程如下:

  1. SubBytes(字節(jié)替換):以字節(jié)大小為索引,與s_box表中字節(jié)映射
  2. ShiftRows(行移位-擴(kuò)散):從上到下從左到右的順序組成 4 * 4 數(shù)組,從 0 行開始,第 n 行向左平移 n 個(gè)字節(jié)
  3. MixColums(列混肴-擴(kuò)散):對每一列進(jìn)行矩陣運(yùn)算,共四列
  4. AddRoundKey(輪密鑰加):與輪密鑰即子密鑰異或運(yùn)算

需要注意的是:

  • 最后一輪沒有列混淆
  • 加密時(shí):SubBytes -> ShiftRows -> MixColums -> AddRoundKey 解密時(shí):AddRoundkey -> InvMixColums -> InvShiftRows -> InvSubBytes (Inv代表逆運(yùn)算)

golang 代碼實(shí)戰(zhàn):

func TestAesEncrypt(t *testing.T){
	key:=[]byte{0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01}
	cipherBlock,err:=aes.NewCipher(key)
	if err!=nil{
		t.Error(err)
	}
	src:=[]byte{0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08}
	encrptDst :=make([]byte,len(src))
	cipherBlock.Encrypt(encrptDst,src)
	t.Log(encrptDst)
	plainDst:=make([]byte,len(encrptDst))
	cipherBlock.Decrypt(plainDst, encrptDst)
	t.Log(plainDst)
}

//out [19 7 34 196 163 153 225 186 223 245 40 131 80 80 70 203]
//out [1 2 3 4 5 6 7 8 1 2 3 4 5 6 7 8]

迭代模式

以上討論的三種加密算法都是分組密碼,每次只能處理特定長度的一塊數(shù)據(jù),例如 DES 和 3DES 能處理的這塊數(shù)據(jù)長度為 8 bytes,AES 的為 16 bytes。而我們的日常需要加密的明文基本上都是大于這個(gè)長度,這就需要我們將明文的內(nèi)容進(jìn)行分組并迭代加密,這個(gè)迭代加密的方式就是模式。

ECB 模式

電子密碼本模式(electronic codebook ),最簡單的模式,將明文分組直接作為加密算法的輸入,加密算法的輸出直接作為密文分組。

CBC 模式

密文分組鏈接模式(Cipher Block Chaining),密文之間是鏈狀的,明文分組跟上個(gè)密文分組異或之后作為加密算法的輸入,加密算法的輸出作為密文分組。第一個(gè)明文分組加密時(shí)需要一個(gè)初始化向量。

CFB 模式

密文反饋模式(Cipher FeedBack),上一個(gè)密文分組作為下一個(gè)加密算法的輸入,加密算法的輸出與明文分組異或結(jié)果作為密文分組。同樣需要一個(gè)初始化向量

OFB 模式

輸出反饋模式(OutPut FeedBack),上一個(gè)加密算法的輸出作為下一個(gè)加密算法的輸入,明文與加密算法的輸出異或作為密文分組。需要初始化向量

CTR 模式

計(jì)數(shù)器模式(Counter),將計(jì)數(shù)器作為加密算法的輸入,加密算法的輸出與明文分組異或作為密文分組,計(jì)數(shù)器是累加的。需要一個(gè)初始的計(jì)數(shù)器值

以上各種模式,ECB 不推薦使用

golang 代碼實(shí)戰(zhàn):

func TestCBCMode(t *testing.T) {
	key:=[]byte{0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01}
	cipherBlock,err:=aes.NewCipher(key)
	if err!=nil{
		t.Error(err)
	}
	src:=[]byte{0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08}
	inv:=[]byte{0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08}
	cbcEncrypter:=cipher.NewCBCEncrypter(cipherBlock,inv)
	encrptDst :=make([]byte,len(src))
	cbcEncrypter.CryptBlocks(encrptDst,src)
	t.Log(encrptDst)

	plainDst:=make([]byte,len(encrptDst))
	cbcDecrypter:=cipher.NewCBCDecrypter(cipherBlock,inv)
	cbcDecrypter.CryptBlocks(plainDst,encrptDst)
	t.Log(plainDst)
}

//out [182 174 175 250 117 45 192 139 81 99 151 49 118 26 237 0 98 117 59 208 145 166 116 62 43 199 115 70 250 251 56 226]
//out [1 2 3 4 5 6 7 8 1 2 3 4 5 6 7 8 1 2 3 4 5 6 7 8 1 2 3 4 5 6 7 8]

關(guān)于本文作者更多信息請查看: https://tpkeep.com

密碼學(xué)系列 - 對稱加密

本文討論的對稱加密算法主要包括 DES、3DES、AES

DES

明文:64 bit 密文:64 bit 密鑰:56/64 bit(每 7 位插入一個(gè)校驗(yàn)位的時(shí)候?yàn)?64 bit) 其設(shè)計(jì)思想充分體現(xiàn)了香農(nóng)提出的混淆和擴(kuò)散原則

密碼學(xué)系列 - 對稱加密

 

DES 使用的是 Feistel 結(jié)構(gòu)來加密的,一共需要 16 輪,加密過程如下:

  1. 將明文進(jìn)行初始置換(通過置換表)
  2. 將置換后的數(shù)據(jù)分為左右 L1 R1 各 32 bit
  3. 將 48 bit 的子密鑰與 R1 作為輪函數(shù)F的輸入
  4. 將 L1 與輪函數(shù)的輸出異或運(yùn)算,得到 L1密文
  5. 將 L1 密文與 R1 交換位置,分別作為下一輪的 R2,L2
  6. 將 2-5 再重復(fù) 15 次
  7. 將 L17 R17 交換位置,并拼接為 64bit 數(shù)據(jù)
  8. 將 64bit 數(shù)據(jù)進(jìn)行逆初始置換,得到最終密文

需要注意的是:

  • 子密鑰在每一輪中都是不一樣的
  • 每一輪之間會(huì)將左側(cè)和右側(cè)對調(diào)(右側(cè)沒有加密)
  • 解密的過程就是將輸出用相同的子密鑰再走一遍,如果加密的子密鑰順序是key1 key2 key3,則解密的子密鑰為key3 key2 key1
  • 輪函數(shù)可以設(shè)計(jì)為不可逆函數(shù)如hash,對解密沒有影響
密碼學(xué)系列 - 對稱加密

 

golang 代碼實(shí)戰(zhàn):

func TestDesEncrypt(t *testing.T) {
    key:=[]byte{0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01}
    cipherBlock,err:=des.NewCipher(key)
    if err!=nil{
        t.Error(err)
    }
    src:=[]byte{0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08}
    encrptDst :=make([]byte,len(src))
    cipherBlock.Encrypt(encrptDst,src)
    t.Log(encrptDst)
    plainDst:=make([]byte,len(encrptDst))
    cipherBlock.Decrypt(plainDst, encrptDst)
    t.Log(plainDst)
}

//out: [206 173 55 61 184 14 171 248]
//out: [1 2 3 4 5 6 7 8]

三重DES

明文:64 bit 密文:64 bit 密鑰:56/64 * 3 bit(加入校驗(yàn)位的時(shí)候?yàn)?4 bit)

為了增加 DES 的強(qiáng)度,明文經(jīng)過 3 次 DES 處理后變成最后的密文,因此密鑰長度為 56/64 * 3 bit。3 次 DES 處理并不是簡單的 3 次加密的過程,而是加密、解密、加密,解密的過程相應(yīng)的就是解密、解密、解密。這樣設(shè)計(jì)是因?yàn)樵?3 個(gè)密鑰相同時(shí),可以兼容 DES 算法

密碼學(xué)系列 - 對稱加密

 

golang 代碼實(shí)戰(zhàn):

func TestTripleDesEncrypt(t *testing.T) {
    key:=[]byte{0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,
    0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01}
    cipherBlock,err:=des.NewTripleDESCipher(key)
    if err!=nil{
        t.Error(err)
    }
    src:=[]byte{0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08}
    encrptDst :=make([]byte,len(src))
    cipherBlock.Encrypt(encrptDst,src)
    t.Log(encrptDst)
    plainDst:=make([]byte,len(encrptDst))
    cipherBlock.Decrypt(plainDst, encrptDst)
    t.Log(plainDst)
}

//此處3個(gè)密鑰相同,兼容DES
//out: [206 173 55 61 184 14 171 248]
//out: [1 2 3 4 5 6 7 8]

AES

明文:128 bit 密文:128 bit 密鑰:128/192/256 bit (分別需要10/12/14輪)

AES 標(biāo)準(zhǔn)最后評選出的算法是 Rijindale 算法,該算法支持密鑰 128/192/256 bit ,分別需要 10/12/14 輪,本文討論的是 128 bit密鑰。它的加密過程并沒有使用 DES 的 feistel 結(jié)構(gòu),而是使用了一種新的 SPN 結(jié)構(gòu),需要 10-14 輪計(jì)算,如下圖:

密碼學(xué)系列 - 對稱加密

 

其中每一輪計(jì)算過程如下:

  1. SubBytes(字節(jié)替換):以字節(jié)大小為索引,與s_box表中字節(jié)映射
  2. ShiftRows(行移位-擴(kuò)散):從上到下從左到右的順序組成 4 * 4 數(shù)組,從 0 行開始,第 n 行向左平移 n 個(gè)字節(jié)
  3. MixColums(列混肴-擴(kuò)散):對每一列進(jìn)行矩陣運(yùn)算,共四列
  4. AddRoundKey(輪密鑰加):與輪密鑰即子密鑰異或運(yùn)算

需要注意的是:

  • 最后一輪沒有列混淆
  • 加密時(shí):SubBytes -> ShiftRows -> MixColums -> AddRoundKey 解密時(shí):AddRoundkey -> InvMixColums -> InvShiftRows -> InvSubBytes (Inv代表逆運(yùn)算)

golang 代碼實(shí)戰(zhàn):

func TestAesEncrypt(t *testing.T){
    key:=[]byte{0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01}
    cipherBlock,err:=aes.NewCipher(key)
    if err!=nil{
        t.Error(err)
    }
    src:=[]byte{0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08}
    encrptDst :=make([]byte,len(src))
    cipherBlock.Encrypt(encrptDst,src)
    t.Log(encrptDst)
    plainDst:=make([]byte,len(encrptDst))
    cipherBlock.Decrypt(plainDst, encrptDst)
    t.Log(plainDst)
}

//out [19 7 34 196 163 153 225 186 223 245 40 131 80 80 70 203]
//out [1 2 3 4 5 6 7 8 1 2 3 4 5 6 7 8]

迭代模式

以上討論的三種加密算法都是分組密碼,每次只能處理特定長度的一塊數(shù)據(jù),例如 DES 和 3DES 能處理的這塊數(shù)據(jù)長度為 8 bytes,AES 的為 16 bytes。而我們的日常需要加密的明文基本上都是大于這個(gè)長度,這就需要我們將明文的內(nèi)容進(jìn)行分組并迭代加密,這個(gè)迭代加密的方式就是模式。

ECB 模式

電子密碼本模式(electronic codebook ),最簡單的模式,將明文分組直接作為加密算法的輸入,加密算法的輸出直接作為密文分組。

CBC 模式

密文分組鏈接模式(Cipher Block Chaining),密文之間是鏈狀的,明文分組跟上個(gè)密文分組異或之后作為加密算法的輸入,加密算法的輸出作為密文分組。第一個(gè)明文分組加密時(shí)需要一個(gè)初始化向量。

CFB 模式

密文反饋模式(Cipher FeedBack),上一個(gè)密文分組作為下一個(gè)加密算法的輸入,加密算法的輸出與明文分組異或結(jié)果作為密文分組。同樣需要一個(gè)初始化向量

OFB 模式

輸出反饋模式(OutPut FeedBack),上一個(gè)加密算法的輸出作為下一個(gè)加密算法的輸入,明文與加密算法的輸出異或作為密文分組。需要初始化向量

CTR 模式

計(jì)數(shù)器模式(Counter),將計(jì)數(shù)器作為加密算法的輸入,加密算法的輸出與明文分組異或作為密文分組,計(jì)數(shù)器是累加的。需要一個(gè)初始的計(jì)數(shù)器值

以上各種模式,ECB 不推薦使用

golang 代碼實(shí)戰(zhàn):

func TestCBCMode(t *testing.T) {
    key:=[]byte{0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01}
    cipherBlock,err:=aes.NewCipher(key)
    if err!=nil{
        t.Error(err)
    }
    src:=[]byte{0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08}
    inv:=[]byte{0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08}
    cbcEncrypter:=cipher.NewCBCEncrypter(cipherBlock,inv)
    encrptDst :=make([]byte,len(src))
    cbcEncrypter.CryptBlocks(encrptDst,src)
    t.Log(encrptDst)

    plainDst:=make([]byte,len(encrptDst))
    cbcDecrypter:=cipher.NewCBCDecrypter(cipherBlock,inv)
    cbcDecrypter.CryptBlocks(plainDst,encrptDst)
    t.Log(plainDst)
}

//out [182 174 175 250 117 45 192 139 81 99 151 49 118 26 237 0 98 117 59 208 145 166 116 62 43 199 115 70 250 251 56 226]
//out [1 2 3 4 5 6 7 8 1 2 3 4 5 6 7 8 1 2 3 4 5 6 7 8 1 2 3 4 5 6 7 8]

分享到:
標(biāo)簽:密碼學(xué)
用戶無頭像

網(wǎng)友整理

注冊時(shí)間:

網(wǎng)站:5 個(gè)   小程序:0 個(gè)  文章:12 篇

  • 51998

    網(wǎng)站

  • 12

    小程序

  • 1030137

    文章

  • 747

    會(huì)員

趕快注冊賬號,推廣您的網(wǎng)站吧!
最新入駐小程序

數(shù)獨(dú)大挑戰(zhàn)2018-06-03

數(shù)獨(dú)一種數(shù)學(xué)游戲,玩家需要根據(jù)9

答題星2018-06-03

您可以通過答題星輕松地創(chuàng)建試卷

全階人生考試2018-06-03

各種考試題,題庫,初中,高中,大學(xué)四六

運(yùn)動(dòng)步數(shù)有氧達(dá)人2018-06-03

記錄運(yùn)動(dòng)步數(shù),積累氧氣值。還可偷

每日養(yǎng)生app2018-06-03

每日養(yǎng)生,天天健康

體育訓(xùn)練成績評定2018-06-03

通用課目體育訓(xùn)練成績評定