導航:首頁 > 文檔加密 > 加密字元串補位

加密字元串補位

發布時間:2023-01-07 15:04:43

❶ 什麼是安全散列演算法SHA256

安全散列演算法SHA(Secure Hash Algorithm)是美國國家安全局 (NSA) 設計,美國國家標准與技術研究院(NIST) 發布的一系列密碼散列函數,包括 SHA-1、SHA-224、SHA-256、SHA-384 和 SHA-512 等變體。主要適用於數字簽名標准(DigitalSignature Standard DSS)裡面定義的數字簽名演算法(Digital Signature Algorithm DSA)。下面以 SHA-1為例,介紹該演算法計算消息摘要的原理。
對於長度小於2^64位的消息,SHA1會產生一個160位的消息摘要。當接收到消息的時候,這個消息摘要可以用來驗證數據的完整性。在傳輸的過程中,數據很可能會發生變化,那麼這時候就會產生不同的消息摘要。
SHA1有如下特性:不可以從消息摘要中復原信息;兩個不同的消息不會產生同樣的消息摘要。
一、術語和概念
(一)位(Bit),位元組(Byte)和字(Word)
SHA1始終把消息當成一個位(bit)字元串來處理。本文中,一個「字」(Word)是32位,而一個「位元組」(Byte)是8位。比如,字元串「abc」可以被轉換成一個位字元串:01100001 01100010 01100011。它也可以被表示成16進制字元串:0x616263.
(二)運算符和符號
下面的邏輯運算符都被運用於「字」(Word)
X^Y = X,Y邏輯與
X \/ Y = X,Y邏輯或
X XOR Y= X,Y邏輯異或
~X = X邏輯取反
X+Y定義如下:
字 X 和Y 代表兩個整數 x 和y, 其中0 <= x < 2^32 且 0 <= y < 2^32. 令整數z= (x + y) mod 2^32. 這時候 0 <= z < 2^32. 將z轉換成字Z,那麼就是 Z = X + Y.
循環左移位操作符Sn(X)。X是一個字,n是一個整數,0<=n<=32。Sn(X)= (X<>32-n)
X<定義如下:拋棄最左邊的n位數字,將各個位依次向左移動n位,然後用0填補右邊的n位(最後結果還是32位)。X>>n是拋棄右邊的n位,將各個位依次向右移動n位,然後在左邊的n位填0。因此可以叫Sn(X)位循環移位運算
二、SHA1演算法描述
在SHA1演算法中,我們必須把原始消息(字元串,文件等)轉換成位字元串。SHA1演算法只接受位作為輸入。假設我們對字元串「abc」產生消息摘要。首先,我們將它轉換成位字元串如下:
01100001 0110001001100011
―――――――――――――
『a』=97 『b』=98『c』=99
這個位字元串的長度為24。下面我們需要5個步驟來計算MD5。
(一)補位
消息必須進行補位,以使其長度在對512取模以後的余數是448。也就是說,(補位後的消息長度)%512 = 448。即使長度已經滿足對512取模後余數是448,補位也必須要進行。
補位是這樣進行的:先補一個1,然後再補0,直到長度滿足對512取模後余數是448。總而言之,補位是至少補一位,最多補512位。還是以前面的「abc」為例顯示補位的過程。
原始信息:01100001 01100010 01100011
補位第一步:0110000101100010 01100011 1
首先補一個「1」
補位第二步:0110000101100010 01100011 10…..0
然後補423個「0」
我們可以把最後補位完成後的數據用16進制寫成下面的樣子
61626380 0000000000000000 00000000
00000000 0000000000000000 00000000
00000000 0000000000000000 00000000
00000000 00000000
現在,數據的長度是448了,我們可以進行下一步操作。
(二)補長度
所謂的補長度是將原始數據的長度補到已經進行了補位操作的消息後面。通常用一個64位的數據來表示原始消息的長度。如果消息長度不大於2^64,那麼第一個字就是0。在進行了補長度的操作以後,整個消息就變成下面這樣了(16進制格式)
61626380 0000000000000000 00000000
00000000 0000000000000000 00000000
00000000 0000000000000000 00000000
00000000 0000000000000000 00000018
如果原始的消息長度超過了512,我們需要將它補成512的倍數。然後我們把整個消息分成一個一個512位的數據塊,分別處理每一個數據塊,從而得到消息摘要。
(三)使用的常量
一系列的常量字K(0),K(1), ... , K(79),如果以16進制給出。它們如下:
Kt = 0x5A827999 (0<= t <= 19)
Kt = 0x6ED9EBA1 (20<= t <= 39)
Kt = 0x8F1BBCDC (40<= t <= 59)
Kt = 0xCA62C1D6 (60<= t <= 79).
(四)需要使用的函數
在SHA1中我們需要一系列的函數。每個函數ft (0 <= t <= 79)都操作32位字B,C,D並且產生32位字作為輸出。ft(B,C,D)可以如下定義
ft(B,C,D) = (B ANDC) or ((NOT B) AND D) ( 0 <= t <= 19)
ft(B,C,D) = B XOR CXOR D (20 <= t <= 39)
ft(B,C,D) = (B ANDC) or (B AND D) or (C AND D) (40 <= t <= 59)
ft(B,C,D) = B XOR CXOR D (60 <= t <= 79).
(五)計算消息摘要
必須使用進行了補位和補長度後的消息來計算消息摘要。計算需要兩個緩沖區,每個都由5個32位的字組成,還需要一個80個32位字的緩沖區。第一個5個字的緩沖區被標識為A,B,C,D,E。第二個5個字的緩沖區被標識為H0,H1, H2, H3, H4。80個字的緩沖區被標識為W0,W1,..., W79
另外還需要一個一個字的TEMP緩沖區。
為了產生消息摘要,在第4部分中定義的16個字的數據塊M1,M2,..., Mn
會依次進行處理,處理每個數據塊Mi 包含80個步驟。
在處理每個數據塊之前,緩沖區{Hi} 被初始化為下面的值(16進制)
H0 = 0x67452301
H1 = 0xEFCDAB89
H2 = 0x98BADCFE
H3 = 0x10325476
H4 = 0xC3D2E1F0.
現在開始處理M1, M2,... , Mn。為了處理 Mi,需要進行下面的步驟
(1). 將Mi 分成 16 個字 W0, W1, ... , W15,W0 是最左邊的字
(2). 對於t = 16 到 79 令 Wt = S1(Wt-3 XOR Wt-8XOR Wt- 14 XOR Wt-16).
(3). 令A = H0, B = H1, C = H2, D = H3, E = H4.
(4) 對於t = 0 到 79,執行下面的循環
TEMP = S5(A) +ft(B,C,D) + E + Wt + Kt;
E = D; D = C; C =S30(B); B = A; A = TEMP;
(5). 令H0 = H0 + A, H1 = H1 + B, H2 = H2 + C, H3 = H3 + D, H4 = H4 + E.
在處理完所有的 Mn, 後,消息摘要是一個160位的字元串,以下面的順序標識
H0 H1 H2 H3 H4.
對於SHA256、SHA384、SHA512。你也可以用相似的辦法來計算消息摘要。對消息進行補位的演算法完全是一樣的。
三、SHA演算法被破解了嗎?
2013年9月10日美國約翰霍普金斯大學的計算機科學教授,知名的加密演算法專家,Matthew Green被NSA要求刪除他的一份關於破解加密演算法的與NSA有關的博客。 同時約翰霍普金斯大學伺服器上的該博客鏡像也被要求刪除。

加密演算法專家,美國約翰霍普金斯大學教授Matthew Green
但當記者向該大學求證時,該校稱從未收到來自NSA的要求要刪除博客或鏡像的資料,但記者卻無法在原網址再找到該博客。幸運的是,從谷歌的緩存可以找到該博客。該博客提到NSA每年花費2.5億美元來為自己在解密信息方面獲取優勢,並列舉了NSA的一系列見不得人的做法。

在BitcoinTalk上,已經掀起了一輪爭論:到底SHA-2是否安全?
部分認為不安全的觀點包括:
NSA製造了sha-2, 我們不相信NSA,他們不可能不留後門。
棱鏡事件已經明白的告訴我們,政府會用一切可能的手段來監視與解密。
雖然有很多人會研究SHA-2,且目前沒有公開的證據表明有漏洞。但沒有公開這並不能代表就沒有,因為發現漏洞的人一定更傾向於保留這個秘密來自己利用,而不是公布。
部分認為安全的觀點包括:
SHA-2是應用廣泛的演算法,應該已經經歷了實踐的檢驗。
美國的對頭中國和俄國都有很多傑出的數學家,如果有問題的話,他們肯定已經發現了。
如果真的不安全,世界上安全的東西就太少了,我不能生活在提心吊膽里,所以我選擇相信安全。

❷ 誰能通俗易懂地講講MD5加密原理

MD5演算法的原理可簡要的敘述為:MD5碼以512位分組來處理輸入的信息,且每一分組又被劃分為16個32位子分組,經過了一系列的處理後,演算法的輸出由四個32位分組組成,將這四個32位分組級聯後將生成一個128位散列值。

在MD5演算法中,首先需要對信息進行填充,這個數據按位(bit)補充,要求最終的位數對512求模的結果為448。也就是說數據補位後,其位數長度只差64位(bit)就是512的整數倍。

即便是這個數據的位數對512求模的結果正好是448也必須進行補位。

補位的實現過程:首先在數據後補一個1 bit; 接著在後面補上一堆0 bit, 直到整個數據的位數對512求模的結果正好為448。總之,至少補1位,而最多可能補512位。

(2)加密字元串補位擴展閱讀

當需要保存某些密碼信息以用於身份確認時,如果直接將密碼信息以明碼方式保存在資料庫中,不使用任何保密措施,系統管理員就很容易能得到原來的密碼信息,這些信息一旦泄露, 密碼也很容易被破譯。為了增加安全性,有必要對資料庫中需要保密的信息進行加密,這樣,即使有人得到了整個資料庫,如果沒有解密演算法,也不能得到原來的密碼信息。

MD5演算法可以很好地解決這個問題,因為它可以將任意長度的輸入串經過計算得到固定長度的輸出,而且只有在明文相同的情況下,才能等到相同的密文,並且這個演算法是不可逆的,即便得到了加密以後的密文,也不可能通過解密演算法反算出明文。

這樣就可以把用戶的密碼以MD5值(或類似的其它演算法)的方式保存起來,用戶注冊的時候,系統是把用戶輸入的密碼計算成 MD5 值,然後再去和系統中保存的 MD5 值進行比較,如果密文相同,就可以認定密碼是正確的,否則密碼錯誤。

通過這樣的步驟,系統在並不知道用戶密碼明碼的情況下就可以確定用戶登錄系統的合法性。這樣不但可以避免用戶的密碼被具有系統管理員許可權的用戶知道,而且還在一定程度上增加了密碼被破解的難度。

MD5 演算法還可以作為一種電子簽名的方法來使用,使用 MD5演算法就可以為任何文件(不管其大小、格式、數量)產生一個獨一無二的「數字指紋」,藉助這個「數字指紋」,通過檢查文件前後 MD5 值是否發生了改變,就可以知道源文件是否被改動。

❸ 對稱加密演算法以及使用方法

加密的原因:保證數據安全

加密必備要素:1、明文/密文    2、秘鑰    3、演算法

秘鑰:在密碼學中是一個定長的字元串、需要根據加密演算法確定其長度

加密演算法解密演算法一般互逆、也可能相同

常用的兩種加密方式:

對稱加密:秘鑰:加密解密使用同一個密鑰、數據的機密性雙向保證、加密效率高、適合加密於大數據大文件、加密強度不高(相對於非對稱加密)

非對稱加密:秘鑰:加密解密使用的不同秘鑰、有兩個密鑰、需要使用密鑰生成演算法生成兩個秘鑰、數據的機密性只能單向加密、如果想解決這個問題、雙向都需要各自有一對秘鑰、加密效率低、加密強度高

                    公鑰:可以公開出來的密鑰、公鑰加密私鑰解密

                    私鑰:需要自己妥善保管、不能公開、私鑰加密公鑰解密

安全程度高:多次加密

按位異或運算

凱撒密碼:加密方式    通過將銘文所使用的字母表按照一定的字數平移來進行加密

mod:取余

加密三要素:明文/密文(字母)、秘鑰(3)、演算法(向右平移3/-3)

安全常識:不要使用自己研發的演算法、不要鑽牛角尖、沒必要研究底層實現、了解怎麼應用;低強度的密碼比不進行任何加密更危險;任何密碼都會被破解;密碼只是信息安全的一部分

保證數據的機密性、完整性、認證、不可否認性

計算機操作對象不是文字、而是由0或1排列而成的比特序列、程序存儲在磁碟是二進制的字元串、為比特序列、將現實的東西映射為比特序列的操作稱為編碼、加密又稱之為編碼、解密稱之為解碼、根據ASCII對照表找到對應的數字、轉換成二進制

三種對稱加密演算法:DES\3DES\ AES  

DES:已經被破解、除了用它來解密以前的明文、不再使用

密鑰長度為56bit/8、為7byte、每隔7個bit會設置一個用於錯誤檢查的比特、因此實際上是64bit

分組密碼(以組為單位進行處理):加密時是按照一個單位進行加密(8個位元組/64bit為一組)、每一組結合秘鑰通過加密演算法得到密文、加密後的長度不變

3DES:三重DES為了增加DES的強度、將DES重復三次所得到的一種加密演算法   密鑰長度24byte、分成三份  加密--解密--加密 目的:為了兼容DES、秘鑰1秘鑰2相同==三個秘鑰相同  ---加密一次        密鑰1秘鑰3相同--加密三次    三個密鑰不相同最好、此時解密相當於加密、中間的一次解密是為了有三個密鑰相同的情況

此時的解密操作與加密操作互逆,安全、效率低

數據先解密後加密可以么?可以、解密相當於加密、加密解密說的是演算法

AES:(首選推薦)底層演算法為Rijndael   分組長度為128bit、密鑰長度為128bit到256bit范圍內就可以   但是在AES中、密鑰長度只有128bit\192bit\256bit     在go提供的介面中、只能是16位元組(128bit)、其他語言中秘鑰可以選擇

目前為止最安全的、效率高

底層演算法

分組密碼的模式:

按位異或、對數據進行位運算、先將數據轉換成二進制、按位異或操作符^、相同為真、不同為假、非0為假    按位異或一次為加密操作、按位異或兩次為解密操作:a和b按位異或一次、結果再和b按位異或

ECB : 如果明文有規律、加密後的密文有規律不安全、go里不提供該介面、明文分組分成固定大小的塊、如果最後一個分組不滿足分組長度、則需要補位

CBC:密碼鏈

問題:如何對字元串進行按位異或?解決了ECB的規律可查缺點、但是他不能並行處理、最後一個明文分組也需要填充 、初始化向量長度與分組長度相同

CFB:密文反饋模式

不需要填充最後一個分組、對密文進行加密

OFB:

不需要對最後一組進行填充

CTR計數器:

不需要對最後一組進行填充、不需要初始化向量     

Go中的實現

官方文檔中:

在創建aes或者是des介面時都是調用如下的方法、返回的block為一個介面

func NewCipher(key [] byte ) ( cipher . Block , error )

type Block interface {

    // 返回加密位元組塊的大小

    BlockSize() int

    // 加密src的第一塊數據並寫入dst,src和dst可指向同一內存地址

    Encrypt(dst, src []byte)

    // 解密src的第一塊數據並寫入dst,src和dst可指向同一內存地址

    Decrypt(dst, src []byte)

}

Block介面代表一個使用特定密鑰的底層塊加/解密器。它提供了加密和解密獨立數據塊的能力。

Block的Encrypt/Decrypt也能進行加密、但是只能加密第一組、因為aes的密鑰長度為16、所以進行操作的第一組數據長度也是16

如果分組模式選擇的是cbc

func NewCBCEncrypter(b Block, iv []byte) BlockMode    加密

func NewCBCDecrypter(b Block, iv []byte) BlockMode    解密

加密解密都調用同一個方法CryptBlocks()

並且cbc分組模式都會遇到明文最後一個分組的補充、所以會用到加密位元組的大小

返回一個密碼分組鏈接模式的、底層用b加密的BlockMode介面,初始向量iv的長度必須等於b的塊尺寸。iv自己定義

返回的BlockMode同樣也是一個介面類型

type BlockMode interface {

    // 返回加密位元組塊的大小

    BlockSize() int

    // 加密或解密連續的數據塊,src的尺寸必須是塊大小的整數倍,src和dst可指向同一內存地址

    CryptBlocks(dst, src []byte)

}

BlockMode介面代表一個工作在塊模式(如CBC、ECB等)的加/解密器

返回的BlockMode其實是一個cbc的指針類型中的b和iv

# 加密流程: 

1. 創建一個底層使用des/3des/aes的密碼介面 "crypto/des" func NewCipher(key []byte) (cipher.Block, error) # -- des func NewTripleDESCipher(key []byte) (cipher.Block, error) # -- 3des "crypto/aes" func NewCipher(key []byte) (cipher.Block, error) # == aes 

2. 如果使用的是cbc/ecb分組模式需要對明文分組進行填充

3. 創建一個密碼分組模式的介面對象 - cbc func NewCBCEncrypter(b Block, iv []byte) BlockMode # 加密 - cfb func NewCFBEncrypter(block Block, iv []byte) Stream # 加密 - ofb - ctr

 4. 加密, 得到密文

流程:

填充明文:

先求出最後一組中的位元組數、創建新切片、長度為新切片、值也為切片的長度、然後利用bytes.Reapet將長度換成位元組切片、追加到原明文中

//明文補充

func padPlaintText(plaintText []byte,blockSize int)[]byte{

    //1、求出需要填充的個數

    padNum := blockSize-len(plaintText) % blockSize

    //2、對填充的個數進行操作、與原明文進行合並

    newPadding := []byte{byte(padNum)}

    newPlain := bytes.Repeat(newPadding,padNum)

    plaintText = append(plaintText,newPlain...)

    return plaintText

}

去掉填充數據:

拿去切片中的最後一個位元組、得到尾部填充的位元組個數、截取返回

//解密後的明文曲調補充的地方

func createPlaintText(plaintText []byte,blockSize int)[]byte{

    //1、得到最後一個位元組、並將位元組轉換成數字、去掉明文中此數字大小的位元組

    padNum := int(plaintText[len(plaintText)-1])

    newPadding := plaintText[:len(plaintText)-padNum]

    return newPadding

}

des加密:

1、創建一個底層使用des的密碼介面、參數為秘鑰、返回一個介面

2、對明文進行填充

3、創建一個cbc模式的介面、需要創建iv初始化向量、返回一個blockmode對象

4、加密、調用blockmode中的cryptBlock函數進行加密、參數為目標參數和源參數

//des利用分組模式cbc進行加密

func EncryptoText(plaintText []byte,key []byte)[]byte{

    //1、創建des對象

    cipherBlock,err := des.NewCipher(key)

    if err != nil {

        panic(err)

    }

    //2、對明文進行填充

    newText := padPlaintText(plaintText,cipherBlock.BlockSize())

    //3、選擇分組模式、其中向量的長度必須與分組長度相同

    iv := make([]byte,cipherBlock.BlockSize())

    blockMode := cipher.NewCBCEncrypter(cipherBlock,iv)

    //4、加密

    blockMode.CryptBlocks(newText,newText)

    return newText

}

des解密:

1、創建一個底層使用des的密碼介面、參數為秘鑰、返回一個介面

2、創建一個cbc模式的介面、需要創建iv初始化向量,返回一個blockmode對象

3、加密、調用blockmode中的cryptBlock函數進行解密、參數為目標參數和源參數

4、調用去掉填充數據的方法

//des利用分組模式cbc進行解密

func DecryptoText(cipherText []byte, key []byte)[]byte{

    //1、創建des對象

    cipherBlock,err := des.NewCipher(key)

    if err != nil {

        panic(err)

    }

    //2、創建cbc分組模式介面

    iv := []byte("12345678")

    blockMode := cipher.NewCBCDecrypter(cipherBlock,iv)

    //3、解密

    blockMode.CryptBlocks(cipherText,cipherText)

    //4、將解密後的數據進行去除填充的數據

    newText := clearPlaintText(cipherText,cipherBlock.BlockSize())

    return newText

}

Main函數調用

func main(){

    //需要進行加密的明文

    plaintText := []byte("CBC--密文沒有規律、經常使用的加密方式,最後一個分組需要填充,需要初始化向量" +

        "(一個數組、數組的長度與明文分組相等、數據來源:負責加密的人提供,加解密使用的初始化向量必須相同)")

    //密鑰Key的長度需要與分組長度相同、且加密解密的密鑰相同

    key := []byte("1234abcd")

    //調用加密函數

    cipherText := EncryptoText(plaintText,key)

    newPlaintText := DecryptoText(cipherText,key)

    fmt.Println(string(newPlaintText))

}

AES加密解密相同、所以只需要調用一次方法就可以加密、調用兩次則解密

推薦是用分組模式:cbc、ctr

aes利用分組模式cbc進行加密

//對明文進行補充

func paddingPlaintText(plaintText []byte , blockSize int ) []byte {

    //1、求出分組余數

    padNum := blockSize - len(plaintText) % blockSize

    //2、將余數轉換為位元組切片、然後利用bytes.Repeat得出有該余數的大小的位元組切片

    padByte := bytes.Repeat([]byte{byte(padNum)},padNum)

    //3、將補充的位元組切片添加到原明文中

    plaintText = append(plaintText,padByte...)

    return plaintText

}

//aes加密

func encryptionText(plaintText []byte, key []byte) []byte {

    //1、創建aes對象

    block,err := aes.NewCipher(key)

    if err != nil {

        panic(err)

    }

    //2、明文補充

    newText := paddingPlaintText(plaintText,block.BlockSize())

    //3、創建cbc對象

    iv := []byte("12345678abcdefgh")

    blockMode := cipher.NewCBCEncrypter(block,iv)

    //4、加密

    blockMode.CryptBlocks(newText,newText)

    return newText

}

//解密後的去尾

func clearplaintText(plaintText []byte, blockSize int) []byte {

    //1、得到最後一個位元組、並轉換成整型數據

    padNum := int(plaintText[len(plaintText)-1])

    //2、截取明文位元組中去掉得到的整型數據之前的數據、此處出錯、沒有用len-padNum

    newText := plaintText[:len(plaintText)-padNum]

    return newText

}

//aes解密

func deCryptionText(crypherText []byte, key []byte ) []byte {

    //1、創建aes對象

    block, err := aes.NewCipher(key)

    if err != nil {

        panic(err)

    }

    //2、創建cbc對象

    iv := []byte("12345678abcdefgh")

    blockMode := cipher.NewCBCDecrypter(block,iv)

    //3、解密

    blockMode.CryptBlocks(crypherText,crypherText)

    //4、去尾

    newText := clearplaintText(crypherText,block.BlockSize())

    return newText

}

func main(){

    //需要進行加密的明文

    plaintText := []byte("CBC--密文沒有規律、經常使用的加密方式,最後一個分組需要填充,需要初始化向量")

    //密鑰Key的長度需要與分組長度相同、且加密解密的密鑰相同

    key := []byte("12345678abcdefgh")

    //調用加密函數

    cipherText := encryptionText(plaintText,key)

    //調用解密函數

    newPlaintText := deCryptionText(cipherText,key)

    fmt.Println("解密後",string(newPlaintText))

}

//aes--ctr加密

func encryptionCtrText(plaintText []byte, key []byte) []byte {

    //1、創建aes對象

    block,err := aes.NewCipher(key)

    if err != nil {

        panic(err)

    }

    //2、創建ctr對象,雖然ctr模式不需要iv,但是go中使用ctr時還是需要iv

    iv := []byte("12345678abcdefgh")

    stream := cipher.NewCTR(block,iv)

    stream.XORKeyStream(plaintText,plaintText)

    return plaintText

}

func main() {

//aes--ctr加密解密、調用兩次即為解密、因為加密解密函數相同stream.XORKeyStream

    ctrcipherText := encryptionCtrText(plaintText, key)

    ctrPlaintText := encryptionCtrText(ctrcipherText,key)

    fmt.Println("aes解密後", string(ctrPlaintText))

}

英文單詞:

明文:plaintext     密文:ciphertext   填充:padding/fill    去掉clear  加密Encryption  解密Decryption

❹ 什麼是3DES對稱加密演算法

DES加密經過下面的步驟
1、提供明文和密鑰,將明文按照64bit分塊(對應8個位元組),不足8個位元組的可以進行填充(填充方式多種),密鑰必須為8個位元組共64bit
填充方式:

當明文長度不為分組長度的整數倍時,需要在最後一個分組中填充一些數據使其湊滿一個分組長度。
* NoPadding
API或演算法本身不對數據進行處理,加密數據由加密雙方約定填補演算法。例如若對字元串數據進行加解密,可以補充\0或者空格,然後trim

* PKCS5Padding
加密前:數據位元組長度對8取余,余數為m,若m>0,則補足8-m個位元組,位元組數值為8-m,即差幾個位元組就補幾個位元組,位元組數值即為補充的位元組數,若為0則補充8個位元組的8
解密後:取最後一個位元組,值為m,則從數據尾部刪除m個位元組,剩餘數據即為加密前的原文。
例如:加密字元串為為AAA,則補位為AAA55555;加密字元串為BBBBBB,則補位為BBBBBB22;加密字元串為CCCCCCCC,則補位為CCCCCCCC88888888。

* PKCS7Padding
PKCS7Padding 的填充方式和PKCS5Padding 填充方式一樣。只是加密塊的位元組數不同。PKCS5Padding明確定義了加密塊是8位元組,PKCS7Padding加密快可以是1-255之間。
2、選擇加密模式

**ECB模式** 全稱Electronic Codebook模式,譯為電子密碼本模式
**CBC模式** 全稱Cipher Block Chaining模式,譯為密文分組鏈接模式
**CFB模式** 全稱Cipher FeedBack模式,譯為密文反饋模式
**OFB模式** 全稱Output Feedback模式,譯為輸出反饋模式。
**CTR模式** 全稱Counter模式,譯為計數器模式。
3、開始加密明文(內部原理--加密步驟,加密演算法實現不做講解)

image
1、將分塊的64bit一組組加密,示列其中一組:將此組進行初始置換(IP置換),目的是將輸入的64位數據塊按位重新組合,並把輸出分為L0、R0兩部分,每部分各長32位。
2、開始Feistel結構的16次轉換,第一次轉換為:右側數據R0和子密鑰經過輪函數f生成用於加密左側數據的比特序列,與左側數據L0異或運算,
運算結果輸出為加密後的左側L0,右側數據則直接輸出為右側R0。由於一次Feistel輪並不會加密右側,因此需要將上一輪輸出後的左右兩側對調後才正式完成一次Feistel加密,
3、DES演算法共計進行16次Feistel輪,最後一輪輸出後左右兩側無需對調,每次加密的子密鑰不相同,子密鑰是通過秘鑰計算得到的。
4、末置換是初始置換的逆過程,DES最後一輪後,左、右兩半部分並未進行交換,而是兩部分合並形成一個分組做為末置換的輸入
DES解密經過下面的步驟
1、拿到密文和加密的密鑰
2、解密:DES加密和解密的過程一致,均使用Feistel網路實現,區別僅在於解密時,密文作為輸入,並逆序使用子密鑰。
3、講解密後的明文去填充 (padding)得到的即為明文
Golang實現DES加密解密
package main

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

func main() {
var miwen,_= DESEncode([]byte("hello world"),[]byte("12345678"))
fmt.Println(miwen) // [11 42 146 232 31 180 156 225 164 50 102 170 202 234 123 129],密文:最後5位是補碼
var txt,_ = DESDecode(miwen,[]byte("12345678"))
fmt.Println(txt) // [104 101 108 108 111 32 119 111 114 108 100]明碼
fmt.Printf("%s",txt) // hello world
}
// 加密函數
func DESEncode(orignData, key []byte)([]byte,error){

// 建立密碼塊
block ,err:=des.NewCipher(key)
if err!=nil{ return nil,err}

// 明文分組,不足的部分加padding
txt := PKCS5Padding(orignData,block.BlockSize())

// 設定加密模式,為了方便,初始向量直接使用key充當了(實際項目中,最好別這么做)
blockMode := cipher.NewCBCEncrypter(block,key)

// 創建密文長度的切片,用來存放密文位元組
crypted :=make([]byte,len(txt))

// 開始加密,將txt作為源,crypted作為目的切片輸入
blockMode.CryptBlocks(crypted,txt)

// 將加密後的切片返回
return crypted,nil
}
// 加密所需padding
func PKCS5Padding(ciphertext []byte,size int)[]byte{
padding := size - len(ciphertext)%size
padTex := bytes.Repeat([]byte{byte(padding)},padding)
return append(ciphertext,padTex...)
}
// 解密函數
func DESDecode(cripter, key []byte) ([]byte,error) {
// 建立密碼塊
block ,err:=des.NewCipher(key)
if err!=nil{ return nil,err}

// 設置解密模式,加密模式和解密模式要一樣
blockMode := cipher.NewCBCDecrypter(block,key)

// 設置切片長度,用來存放明文位元組
originData := make([]byte,len(cripter))

// 使用解密模式解密,將解密後的明文位元組放入originData 切片中
blockMode.CryptBlocks(originData,cripter)

// 去除加密的padding部分
strByt := UnPKCS5Padding(origenData)

return strByt,nil
}
// 解密所需要的Unpadding
func UnPKCS5Padding(origin []byte) []byte{
// 獲取最後一位轉為整型,然後根據這個整型截取掉整型數量的長度
// 若此數為5,則減掉轉換明文後的最後5位,即為我們輸入的明文
var last = int(origin[len(origin)-1])
return origin[:len(origin)-last]
}
注意:在設置加密模式為CBC的時候,我們需要設置一個初始化向量,這個量的意思 在對稱加密演算法中,如果只有一個密鑰來加密數據的話,明文中的相同文字就會也會被加密成相同的密文,這樣密文和明文就有完全相同的結構,容易破解,如果給一個初始化向量,第一個明文使用初始化向量混合並加密,第二個明文用第一個明文的加密後的密文與第二個明文混合加密,這樣加密出來的密文的結構則完全與明文不同,更加安全可靠。CBC模式圖如下

CBC
3DES
DES 的常見變體是三重 DES,使用 168 位的密鑰對資料進行三次加密的一種機制;它通常(但非始終)提供極其強大的安全性。如果三個 56 位的子元素都相同,則三重 DES 向後兼容 DES。
對比DES,發現只是換了NewTripleDESCipher。不過,需要注意的是,密鑰長度必須24byte,否則直接返回錯誤。關於這一點,PHP中卻不是這樣的,只要是8byte以上就行;而java中,要求必須是24byte以上,內部會取前24byte(相當於就是24byte)。另外,初始化向量長度是8byte(目前各個語言都是如此,不是8byte會有問題)

❺ JAVA和.NET使用DES對稱加密的區別

如果我說沒有區別你會信嗎?
但答案還真是這樣,兩者沒有任何區別的,只不過實現的語言代碼不同而已。
那麼java與dot net之間的DES是否可以通用?答案也是完全通用。無論是Java的DES加密還是dot net的DES回密,均可以使用另一種語言且不限於Java或dot net解密。夠明白嗎?
DES其實只是一個演算法,加密與解密我們都知道演算法與密碼是分離的。演算法是公開的,都可以用,而密碼是獨立於演算法的。所以DES在不同的語言中實現的演算法根本就是一樣的——也正是因為如此不管何種語言都是通用的(除非偽DES,要知道DES演算法網上本身能搜到而且是一個標准,最先是由美國安全部門公開的)
再說一下,為什麼有人「通」用不起來的原因。DES其實有CBC之類的參數的,也就是針對加密塊選用的不同的加密手段。正是這個參數的原因,不同的語言中使用不同的參數做為默認值,所以使用默認的方式進行讓兩個串進行加解密肯定是不同的。DES使用一種模式(方法)加密,用另一種模式(方法)進行解密能得到正確的結果嗎?一些人不怪自己的學藝不精,反說是兩種語言的DES不通用(這也就是為什麼網路上會出現諸多說java和dot net的DES加密方法不通用的原因)。
即便是自己使用的DES加密的代碼也是通用的(前提你要遵守DES分開演算法),但不要「重復實現已經實現的東西(專業術語叫造輪子)」。
附:
DES.Model屬性取值
CBC 密碼塊鏈 (CBC) 模式引入了反饋。每個純文本塊在加密前,通過按位「異或」操作與前一個塊的密碼文本結合。這樣確保了即使純文本包含許多相同的塊,這些塊中的每一個也會加密為不同的密碼文本塊。在加密塊之前,初始化向量通過按位「異或」操作與第一個純文本塊結合。如果密碼文本塊中有一個位出錯,相應的純文本塊也將出錯。此外,後面的塊中與原出錯位的位置相同的位也將出錯。
ECB 電子密碼本 (ECB) 模式分別加密每個塊。這意味著任何純文本塊只要相同並且在同一消息中,或者在用相同的密鑰加密的不同消息中,都將被轉換成同樣的密碼文本塊。如果要加密的純文本包含大量重復的塊,則逐塊破解密碼文本是可行的。另外,隨時准備攻擊的對手可能在您沒有察覺的情況下替代和交換個別的塊。如果密碼文本塊中有一個位出錯,相應的整個純文本塊也將出錯。
OFB 輸出反饋 (OFB) 模式將少量遞增的純文本處理成密碼文本,而不是一次處理整個塊。此模式與 CFB 相似;這兩種模式的唯一差別是移位寄存器的填充方式不同。如果密碼文本中有一個位出錯,純文本中相應的位也將出錯。但是,如果密碼文本中有多餘或者缺少的位,則那個位之後的純文本都將出錯。
CFB 密碼反饋 (CFB) 模式將少量遞增的純文本處理成密碼文本,而不是一次處理整個塊。該模式使用在長度上為一個塊且被分為幾部分的移位寄存器。例如,如果塊大小為 8 個位元組,並且每次處理一個位元組,則移位寄存器被分為 8 個部分。如果密碼文本中有一個位出錯,則一個純文本位出錯,並且移位寄存器損壞。這將導致接下來若干次遞增的純文本出錯,直到出錯位從移位寄存器中移出為止。
CTS 密碼文本竊用 (CTS) 模式處理任何長度的純文本並產生長度與純文本長度匹配的密碼文本。除了最後兩個純文本塊外,對於所有其他塊,此模式與 CBC 模式的行為相同。

DES.Padding屬性的取值
None 不填充。
PKCS7 PKCS #7 填充字元串由一個位元組序列組成,每個位元組填充該位元組序列的長度。
Zeros 填充字元串由設置為零的位元組組成。
ANSIX923 ANSIX923 填充字元串由一個位元組序列組成,此位元組序列的最後一個位元組填充位元組序列的長度,其餘位元組均填充數字零。
ISO10126 ISO10126 填充字元串由一個位元組序列組成,此位元組序列的最後一個位元組填充位元組序列的長度,其餘位元組填充隨機數據。

當Mode不同時,解密的內密內容能與相同嗎?PaddingMode不同時,解密的內容的結尾部分能相同嗎(填充結果只涉及到最後的一個塊).所以當不管何種語言使用相同的Mode及PaddingMode時,加解密的結果是相同的(當然不排除部分語言不實現全部的Mode和PaddingMode)但,基本的都是實現了的,所以基本上任何兩種語言之間的DES都可以實現相同的加解密結果!而java和dot net中的DES顯然指的是演算法,兩者是相同的,可以隨意使用(Java中dot net中的Mode默認值是不同的,一定要設置相同的Mode和PaddingMode才可以的,不要雙方都採用默認值,那樣真的通不起來)

閱讀全文

與加密字元串補位相關的資料

熱點內容
如何截獲手機app連接的ip 瀏覽:330
冰箱壓縮機是否需要電容 瀏覽:344
python列表每一行數據求和 瀏覽:274
自己有一台伺服器可以玩什麼 瀏覽:656
社會學波普諾pdf 瀏覽:584
解壓做食物的小視頻 瀏覽:758
pdf怎麼單獨設置文件夾 瀏覽:474
業務邏輯程序員 瀏覽:659
addto新建文件夾什麼意思 瀏覽:160
有伺服器地址怎麼安裝軟體 瀏覽:659
安卓如何完全清除數據 瀏覽:690
安卓安卓證書怎麼信任 瀏覽:53
伺服器被攻擊如何解決 瀏覽:221
學霸變成程序員 瀏覽:881
c語言編譯錯誤fatalerror 瀏覽:441
ipv4內部伺服器地址怎麼分配 瀏覽:463
java線程安全的方法 瀏覽:951
重復命令畫梯形 瀏覽:164
在疫情就是命令 瀏覽:328
自己搭建一個什麼伺服器好玩 瀏覽:253