密碼技術(shù)###
1. 介紹
1.1 加密/解密三要素: 明文/ 密文, 秘鑰, 密碼算法
-
明文/密文:
加密之前的消息稱為明文(plaintext)用押,加密之后的消息稱為密文(cipher-text)。 -
秘鑰 :
密碼算法中需要密鑰(key)。現(xiàn)實(shí)世界中的“鑰'',是像 :key: 這樣的形狀微妙而復(fù)雜的小金屬片旭寿。然而警绩,密碼算法中的密鑰,則是像203554728568477650354673080689430768這樣的一串非常大的數(shù)字盅称。
-
密碼算法 :
用于解決復(fù)雜問題的步驟肩祥,通常稱為算法(algorithm)后室。從明文生成密文的步驟,也就是加密的步驟混狠,稱為“加密算法"岸霹,而解密的步驟則稱為“解密算法"。加密将饺、解密的算法合在一起統(tǒng)稱為密碼算法贡避。
1.2密碼信息威脅
我們將信息安全所面臨的威脅與用來用對(duì)這些威脅的密碼技術(shù)直接的關(guān)系用一張圖標(biāo)來表示出來。
2. 對(duì)稱加密
對(duì)稱加密: 也稱為對(duì)稱密碼, 是指在加密和解碼時(shí)使用同一秘鑰的加密方式
2.1 DES:
DES(Data Encryption Standard)是1977年美國(guó)聯(lián)邦信息處理標(biāo)準(zhǔn)(FIPS)中所采用的一種對(duì)稱密碼(FIPS46.3)予弧。DES一直以來被美國(guó)以及其他國(guó)家的政府和銀行等廣泛使用刮吧。然而,隨著計(jì)算機(jī)的進(jìn)步掖蛤,現(xiàn)在DES已經(jīng)能夠被暴力破解杀捻,強(qiáng)度大不如前了(不建議使用)
-
DES加密解密
DES是一種將64比特的明文加密成64比特的密文的對(duì)稱密碼算法,==它的密鑰長(zhǎng)度是56比特==蚓庭。盡管從規(guī)格上來說致讥,DES的密鑰長(zhǎng)度是64比特,但由于每隔7比特會(huì)設(shè)置一個(gè)用于錯(cuò)誤檢查的比特器赞,因此實(shí)質(zhì)上其密鑰長(zhǎng)度是56比特垢袱。
DES是以64比特的明文(比特序列)為一個(gè)單位來進(jìn)行加密的,這個(gè)64比特的單位稱為分組拳魁。一般來說惶桐,以分組為單位進(jìn)行處理的密碼算法稱為分組密碼(blockcipher),DES就是分組密碼的一種潘懊。
DES每次只能加密64比特的數(shù)據(jù)姚糊,如果要加密的明文比較長(zhǎng),就需要對(duì)DES加密進(jìn)行迭代(反復(fù))授舟,而迭代的具體方式就稱為模式(mode)救恨。
秘鑰長(zhǎng)度(56bit + 8bit)/8 = 8byte
-
三重DES加密
現(xiàn)在DES已經(jīng)可以在現(xiàn)實(shí)的時(shí)間內(nèi)被暴力破解,三重DES(triple-DES)是為了增加DES的強(qiáng)度释树,==將DES重復(fù)3次所得到的一種密碼算法==肠槽,通常縮寫為3DES
明文經(jīng)過三次DES處理才能變成最后的密文奢啥,由于DES密鑰的長(zhǎng)度實(shí)質(zhì)上是56比特秸仙,因此三重DES的密鑰長(zhǎng)度就是56×3=168比特, 加上用于錯(cuò)誤檢測(cè)的標(biāo)志位8x3, 共192bit。
從上圖我們可以發(fā)現(xiàn)桩盲,三重DES并不是進(jìn)行三次DES加密(加密-->加密-->加密)寂纪,而是加密-->解密-->加密的過程。在加密算法中加人解密操作讓人感覺很不可思議,實(shí)際上這個(gè)方法是IBM公司設(shè)計(jì)出來的捞蛋,目的是為了讓三重DES能夠兼容普通的DES孝冒。
當(dāng)三重DES中所有的密鑰都相同時(shí),三重DES也就等同于普通的DES了拟杉。這是因?yàn)樵谇皟刹郊用?->解密之后庄涡,得到的就是最初的明文。因此搬设,以前用DES加密的密文穴店,就可以通過這種方式用三重DES來進(jìn)行解密。也就是說焕梅,三重DES對(duì)DES具備向下兼容性迹鹅。
如果密鑰1和密鑰3使用相同的密鑰,而密鑰2使用不同的密鑰(也就是只使用兩個(gè)DES密鑰)贞言,這種三重DES就稱為DES-EDE2斜棚。EDE表示的是加密(Encryption) -->解密(Decryption)-->加密(Encryption)這個(gè)流程。
密鑰1该窗、密鑰2弟蚀、密鑰3全部使用不同的比特序列的三重DES稱為DES-EDE3。
盡管三重DES目前還被銀行等機(jī)構(gòu)使用酗失,但其處理速度不高义钉,而且在安全性方面也逐漸顯現(xiàn)出了一些問題
2. Go實(shí)現(xiàn)對(duì)稱加密
2.1 DES 實(shí)現(xiàn):
-
CBC 分組模式:
加密:
- 創(chuàng)建并返回一個(gè)使用DES算法的cipher.Block接口 秘鑰長(zhǎng)度為64bit, 即 64/8 = 8字節(jié)(byte)
- 對(duì)最后一個(gè)明文分組進(jìn)行數(shù)據(jù)填充
DES是以64比特的明文(比特序列)為一個(gè)單位來進(jìn)行加密的
最后一組不夠64bit, 則需要進(jìn)行數(shù)據(jù)填充( 參考第三章)- 創(chuàng)建一個(gè)密碼分組為鏈接模式的, 底層使用DES加密的BlockMode接口
- 加密連續(xù)的數(shù)據(jù)塊
解密:
- 創(chuàng)建并返回一個(gè)使用DES算法的cipher.Block接口
- 創(chuàng)建一個(gè)密碼分組為鏈接模式的, 底層使用DES解密的BlockMode接口
- 數(shù)據(jù)塊解密
- 去掉最后一組的填充數(shù)據(jù)
代碼實(shí)現(xiàn):
1.明文/密文分組填充與移除
// 分組填充--填充對(duì)應(yīng)長(zhǎng)度的相同數(shù)字(1, 22规肴, 333....)
//data: 待分組數(shù)據(jù), blockSize: 每組的長(zhǎng)度
func PKCS7Padding(date []byte, blockSize int)(PaddingResult[]byte){
// 獲取數(shù)據(jù)長(zhǎng)度
length:=len(date)
// 獲取待填充數(shù)據(jù)長(zhǎng)度
count:=length%blockSize
PaddingCount:=blockSize-count
// 在數(shù)據(jù)后填充數(shù)據(jù)
PaddingDate:=bytes.Repeat([]byte{byte(PaddingCount)},PaddingCount)
PaddingResult=append(date,PaddingDate...)
return
}
// 分組移除
func PKCS7Unpadding(date []byte, blockSize int)(UnpaddingResult[]byte){
length:=len(date)
temp:=int(date[length-1])
UnpaddingResult=date[:length-temp]
return
}
- DES加密與解密:
//src: --明文/密文捶闸,需要分組填充,每組8byte
//key: --秘鑰 8byte
//iv: --初始化向量 8byte 長(zhǎng)度必須與key相同
--------------------------------------------------------------
//加密
func Des_CBC_Encrypt(src []byte, key []byte, iv []byte) []byte {
// 創(chuàng)建并返回一個(gè)使用DES算法的cipher.Block接口
block, err := des.NewCipher(key)
// 判斷是否創(chuàng)建成功
if err != nil {
panic(err)
}
// 明文組數(shù)據(jù)填充
paddingText := PKCS7Padding_Unpadding.PKCS7Padding(src, block.BlockSize())
// 創(chuàng)建一個(gè)密碼分組為鏈接模式的, 底層使用DES加密的BlockMode接口
blockMode := cipher.NewCBCEncrypter(block, iv)
// 加密
dst := make([]byte, len(paddingText))
blockMode.CryptBlocks(dst, paddingText)
return dst
}
---------------------------------------------------------
// 解密:
func Des_CBC_Decrypt(src []byte, key []byte, iv []byte) []byte {
// 創(chuàng)建并返回一個(gè)使用DES算法的cipher.Block接口
block, err := des.NewCipher(key)
if err != nil {
panic(err)
}
// 創(chuàng)建一個(gè)密碼分組為鏈接模式的, 底層使用DES解密的BlockMode接口
blockMode := cipher.NewCBCDecrypter(block, iv)
// 解密
dst := make([]byte, len(src))
blockMode.CryptBlocks(dst, src)
// 分組移除
dst = PKCS7Padding_Unpadding.PKCS7Unpadding(dst, block.BlockSize())
return dst
}
-
CTR 分組模式:
加密:
- 創(chuàng)建并返回一個(gè)使用DES算法的cipher.Block接口 秘鑰長(zhǎng)度為64bit, 即 64/8 = 8字節(jié)(byte)
- 創(chuàng)建一個(gè)CTR密碼分組為鏈接模式的, 底層使用DES加密的BlockMode接口
- 加密連續(xù)的數(shù)據(jù)塊
解密:
與加密算法完全一致
代碼實(shí)現(xiàn):
/*
DES CTR 加密解密函數(shù)
參數(shù):
src: --明文/密文 分組不需要填充
key: --秘鑰 8byte
iv: --初始化向量 8byte 長(zhǎng)度必須與key相同
*/
//加密
func Des_CTR_Encrypt(src []byte, key []byte, iv []byte) []byte {
// 創(chuàng)建并返回一個(gè)使用DES算法的cipher.Block接口
block, err := des.NewCipher(key)
// 判斷是否創(chuàng)建成功
if err != nil {
panic(err)
}
// 創(chuàng)建一個(gè)密碼分組為鏈接模式的, 底層使用DES加密的stream接口
stream := cipher.NewCTR(block,iv)
// 加密
dst := make([]byte, len(src))
stream.XORKeyStream(dst,src)
return dst
}
// 解密 直接調(diào)用加密函數(shù)
func Des_CTR_Decrypt(src []byte, key []byte, iv []byte) []byte {
return Des_CTR_Encrypt(src,key,iv)
}
2.2 3DES 實(shí)現(xiàn):
與DES 基本一致拖刃, 唯一不同點(diǎn):
key 長(zhǎng)度:3*8=24byte
代碼實(shí)現(xiàn):
/*
3DES CBC 加密解密函數(shù)
Des3_CBC_Encrypt() --加密
Des3_CBC_Decrypt() --解密
參數(shù):
src: --明文/密文删壮,需要分組填充,每組8byte
key: --秘鑰 3*8=24byte
iv: --初始化向量 8byte
*/
func Des3_CBC_Encrypt(src []byte, key []byte, iv []byte) []byte {
// 創(chuàng)建并返回一個(gè)使用3DES算法的cipher.Block接口
block, err := des.NewTripleDESCipher(key)
// 判斷是否創(chuàng)建成功
if err != nil {
panic(err)
}
// 明文組數(shù)據(jù)填充
paddingText := PKCS7Padding_Unpadding.PKCS7Padding(src, block.BlockSize())
// 創(chuàng)建一個(gè)密碼分組為鏈接模式的, 底層使用DES加密的BlockMode接口
blockMode := cipher.NewCBCEncrypter(block, iv)
// 加密
dst := make([]byte, len(paddingText))
blockMode.CryptBlocks(dst, paddingText)
return dst
}
func Des3_CBC_Decrypt(src []byte, key []byte, iv []byte) []byte {
// 創(chuàng)建并返回一個(gè)使用3DES算法的cipher.Block接口
block, err := des.NewTripleDESCipher(key)
if err != nil {
panic(err)
}
// 創(chuàng)建一個(gè)密碼分組為鏈接模式的, 底層使用3DES解密的BlockMode接口
blockMode := cipher.NewCBCDecrypter(block, iv)
// 解密
dst := make([]byte, len(src))
blockMode.CryptBlocks(dst, src)
// 分組移除
dst = PKCS7Padding_Unpadding.PKCS7Unpadding(dst, block.BlockSize())
return dst
}
--------------------------------------------------------------
/*
3DES CTR 加密解密函數(shù)
Des3_CTR_Encrypt() --加密
Des3_CTR_Decrypt() --解密
參數(shù):
src: --明文/密文 分組不需要填充
key: --秘鑰 3*8=24byte
iv: --初始化向量 8byte
*/
func Des3_CTR_Encrypt(src []byte, key []byte, iv []byte) []byte {
// 創(chuàng)建并返回一個(gè)使用3DES算法的cipher.Block接口
block, err := des.NewTripleDESCipher(key)
// 判斷是否創(chuàng)建成功
if err != nil {
panic(err)
}
// 創(chuàng)建一個(gè)密碼分組為鏈接模式的, 底層使用DES加密的stream接口
stream := cipher.NewCTR(block,iv)
// 加密
dst := make([]byte, len(src))
stream.XORKeyStream(dst,src)
return dst
}
func Des3_CTR_Decrypt(src []byte, key []byte, iv []byte) []byte {
return Des3_CTR_Encrypt(src,key,iv)
}