des加密演算法
⑴ 對稱加密演算法中,des演算法的密鑰長度是多少,採用什麼進行加密
DES使用56位密鑰對64位的數據塊進行加密,並對64位的數據塊進行16輪編碼。與每輪編碼時,一個48位的「每輪」密鑰值由56位的完整密鑰得出來。DES用軟體進行解碼需要用很長時間,而用硬體解碼速度非常快,但幸運的是當時大多數黑客並沒有足夠的設備製造出這種硬體設備。在1977年,人們估計要耗資兩千萬美元才能建成一個專門計算機用於DES的解密,而且需要12個小時的破解才能得到結果。所以,當時DES被認為是一種十分強壯的加密方法。
但是,當今的計算機速度越來越快了,製造一台這樣特殊的機器的花費已經降到了十萬美元左右,所以用它來保護十億美元的銀行間線纜時,就會仔細考慮了。另一個方面,如果只用它來保護一台伺服器,那麼DES確實是一種好的辦法,因為黑客絕不會僅僅為入侵一個伺服器而花那麼多的錢破解DES密文。由於現在已經能用二十萬美圓製造一台破譯DES的特殊的計算機,所以現在再對要求「強壯」加密的場合已經不再適用了。
三重DES
因為確定一種新的加密法是否真的安全是極為困難的,而且DES的唯一密碼學缺點,就是密鑰長度相對比較短,所以人們並沒有放棄使用DES,而是想出了一個解決其長度問題的方法,即採用三重DES。這種方法用兩個密鑰對明文進行三次加密,假設兩個密鑰是K1和K2,其演算法的步驟如圖5.9所示:
1. 用密鑰K1進行DEA加密。
2. 用K2對步驟1的結果進行DES解密。
3. 用步驟2的結果使用密鑰K1進行DES加密。
這種方法的缺點,是要花費原來三倍時間,從另一方面來看,三重DES的112位密鑰長度是很「強壯」的加密方式了
⑵ DES加密演算法
特點
分組比較短、密鑰太短、密碼生命周期短、運算速度較慢。
編輯本段基本原理
入口參數有三個:key、data、mode。 key為加密解密使用的密鑰,data為加密解密的數據,mode為其工作模式。當模式為加密模式時,明文按照64位進行分組,形成明文組,key用於對數據加密,當模式為解密模式時,key用於對數據解密。實際運用中,密鑰只用到了64位中的56位,這樣才具有高的安全性。 DES( Data Encryption Standard)演算法,於1977年得到美國政府的正式許可,是一種用56位密鑰來加密64位數據的方法。雖然56位密鑰的DES演算法已經風光不在,而且常有用Des加密的明文被破譯的報道,但是了解一下昔日美國的標准加密演算法總是有益的,而且目前DES演算法得到了廣泛的應用,在某些場合,仍然發揮著余熱。
編輯本段密鑰生成
取得密鑰
從用戶處取得一個64位(本文如未特指,均指二進制位))長的密碼key ,去除64位密碼中作為奇偶校驗位的第8、16、24、32、40、48、56、64位,剩下的56位作為有效輸入密鑰.
等分密鑰
表1. DES加密演算法
57 49 41 33 25 17 9 1 58 50 42 34 26 18 10 2 59 51 43 35 27 19 11 3 60 50 44 36 表2. 63 55 47 39 31 23 15 7 62 54 46 38 30 22 14 6 61 53 45 37 29 21 13 5 28 20 12 4 把在1步中生成的56位輸入密鑰分成均等的A,B兩部分,每部分為28位,參照表1和表2把輸入密鑰的位值填入相應的位置. 按照表1所示A的第一位為輸入的64位密鑰的第57位,A的第2位為64位密鑰的第49位,...,依此類推,A的最後一位最後一位是64位密鑰的第36位。
密鑰移位
表3. i 1 2 3 4 5 6 7 8 DES加密演算法
ǿ 1 1 2 2 2 2 2 2 i 9 10 11 12 13 14 15 16 ǿ 1 2 2 2 2 2 2 1 DES演算法的密鑰是經過16次迭代得到一組密鑰的,把在1.1.2步中生成的A,B視為迭代的起始密鑰,表3顯示在第i次迭代時密鑰循環左移的位數. 比如在第1次迭代時密鑰循環左移1位,第3次迭代時密鑰循環左移2位. 第9次迭代時密鑰循環左移1位,第14次迭代時密鑰循環左移2位. 第一次迭代: A(1) = ǿ(1) A B(1) = ǿ(1) B DES加密演算法
第i次迭代: A(i) = ǿ(i) A(i-1) B(i) = ǿ(i) B(i-1)
實現介面函數的介紹
1 int des(char *data, char *key,int readlen) 參數: 1.存放待加密明文的內存指針(長度為readlen,可能經過填充; 2.存放用戶輸入的密鑰內存的指針 3.待加密明文的長度(8位元組的倍數) 功能: 生成加密密鑰,把待加密的明文數據分割成64位的塊,逐塊完成16次迭代加密,密文存放在data所指向的內存中. 2 int Ddes(char *data, char *key,int readlen) 參數: 1.存放待解密文的內存指針(長度為readlen,可能經過填充; 2.存放用戶輸入的密鑰內存的指針 3.待解密文的長度( 8位元組的倍數) 功能: 生成解密密鑰,把待解密文分割成64位的塊,逐塊完成16次迭代解密,解密後的明文存放在data所指向的內存中. 3 int des3(char *data, char *key, int n ,int readlen) 參數: 1.存放待加密明文的內存指針(長度為readlen,可能經過填充; 2.存放用戶輸入的密鑰內存的指針 DES加密演算法
3.用戶指定進行多少層加密 4.待加密明文的長度(8位元組的倍數) 功能: 生成加密密鑰,把待加密的明文分割成64位的塊,把第i-1層加密後的密文作為第i層加密的明文輸入,根據用戶指定的加密層數進行n層加密,最終生成的密文存放在data所指向的內存中. 說明: 用戶僅僅輸入一條密鑰,所有的加密密鑰都是由這條密鑰生成. 4 int Ddes3(char *data, char*key, int n ,int readlen) 參數: 1.存放待解密文的內存指針(長度為readlen,可能經過填充; 2.存放用戶輸入的密鑰內存的指針 3.用戶指定進行多少層解密 4.待解密文的長度(8位元組的倍數) 功能: 生成解密密鑰,把待解密文分割成64位的塊,把第i-1層解密後的"明文"作為第i層解密的密文輸入,根據用戶指定的解密層數進行n層解密,最終生成的明文存放在data所指向的內存中. 說明: 用戶僅僅輸入一條密鑰,所有的解密密鑰都是由這條密鑰生成. 5 int desN(char*data,char**key,int n_key,int readlen) 參數: 1.存放待加密明文的內存指針(長度為readlen,可能經過填充; 2.存放用戶輸入的密鑰內存的指針 3.用戶指定了多少條密鑰 4.待加密明文的長度(8位元組的倍數) 功能: DES加密演算法生成加密密鑰,把待加密的明文分割成64位的塊,把第i-1層加密後的密文作為第i層加密的明文輸入,根據用戶指定的加密層數進行n層加密,最終生成的密文存放在data所指向的內存中. 說明: 這里用戶通過輸入的密鑰條數決定加密的層數,每輪16次迭代加密所使用的加密密鑰是由用戶自定的對應密鑰生成. 6 int DdesN(char*data,char**key,intn_key,int readlen) 參數: 1.存放待解密文的內存指針(長度為readlen,可能經過填充; 2.存放用戶輸入的密鑰內存的指針 3.用戶指定了多少條密鑰 4.待解密文的長度(8位元組的倍數) 功能: 生成解密密鑰,把待解密文分割成64位的塊,把第i-1層解密後的」明文」作為第i層解密的密文輸入,根據用戶指定的解密層數進行n層解密,最終生成的明文存放在data所指向的內存中. 說明: 這里用戶通過輸入的密鑰條數決定解密的層數,每輪16次迭代加密所使用的解密密鑰是由用戶自定的對應密鑰生成. DES加密演算法-實現的介紹 利用演算法核心代碼封裝的介面函數編寫了一個針對文本文件的加密解密工具。選擇把密文以16進制的形式寫入文件的方法.當然也可以直接寫入文件. 例: DES加密演算法
密文為:12345678 在內存中顯示為: 31 32 33 34 35 36 37 38 那麼就把以3132333435363738的形式寫入文件. 為了解密的方便,密文中的每個位元組用兩個位元組表示,也即在內存中顯示為0x9A的內容,就以9A的形式寫入文件中.當內存中顯示的內容為0x0?(?代表0~F)形式時,需要以0?的形式寫入文件. 這樣可以避開前面提及的問題,只是在解密時先按照兩兩組合的原則,順序把從文件中讀取的數據轉換成待解的密文. 例: 讀出的數據是: 3132333435363738 那麼復原的過程: 31->1 32->2 33->3 …. 38->8 最終得真正的密文12345678,這樣就可以調用DES演算法解密函數從密文得到明文. DES演算法是對固定大小(64位)的數據塊進行加密解密操作的,對於那些不夠64位的數據塊需要採用填充機制補位到64位長,為了方便使用,數據位的填充是對用戶而言是透明的,利用該工具進行加密解密操作時,用戶只需輸入操作的類型、讀取數據的文件名、寫入操作結果的文件名、密鑰等信息.
編輯本段操作思路
#define READFILESIZE 512 步驟: 1.從文件中讀取READFILESIZE個位元組的數據 2.,如果從文件中讀出的數據少於READFILESIZE個,以0補足,然後根據用戶指定的類型對這READFILESIZE個位元組的數據進行操作. 3.判斷文件是否結束,沒有則執行步驟1 4.把加密後的文件實際長度添加到密文的末尾 5.結束 採用一次只從文件讀取READFILESIZE個位元組是在為了防止由於需要加密或解密的文件太大導致內存不夠的情況出現。 DES加密演算法-注意事項 DES演算法的加密密鑰是根據用戶輸入的密碼生成的,該演算法把64位密碼中的第8位、第16位、第24位、第32位、第40位、第48位、第56位、第64位作為奇偶校驗位,在計算密鑰時要忽略這8位.如果輸入的密碼只是在這8位上有區別的話,那麼操作後的結果將是一樣的. 例: 輸入的密碼為wuzhenll,密鑰的16進製表示為77 75 7A 68 65 6E 6C 6C 任意改變這64位數據的奇偶校驗位,可以得到16個不同的密碼, 把8個奇偶檢驗位全取反後: w->v u->t z->{ h->i e->d n->o l->m 形成新密碼:vt{idomm 表面上新密碼和原密碼迥然不同,但是由於他們僅在奇偶校驗位上有區別,所以用這兩個密碼進行加密解密操作得到的結果是一樣的. 筆者建議使用安全系數較高的多密鑰加密解密方案. 此外用戶輸入的密碼的長度不受限制,當輸入的密碼長度為0時,使用預設64位密碼;當輸入的密碼長度大於8位元組時,輸入密碼的前8個位元組為有效密碼. 該工具提供6種不同的操作類型: 1:一層加密; 2:一層解密; 3:N層單密鑰加密; 4:N層單密鑰解密; 5:N層多密鑰加密; 6:N層多密鑰解密; 這六種操作是對稱使用的,例如:加密明文時選擇一層加密,解密時對密文使用一層解密
⑶ 什麼是DES對稱加密演算法
數據加密的基本過程就是對原來為明文的文件或數據按某種演算法進行處理,使其成為不可讀的一段代碼,通常稱為「密文」,一般來說,是需要仔細的酸,才可以算的出來的,
⑷ DES演算法是屬於對稱加密演算法嗎
是的,
最著名的保密密鑰或對稱密鑰加密演算法DES(Data Encryption Standard)是由IBM公司在70年代發展起來的,並經過政府的加密標准篩選後,於1976年11月被美國政府採用,DES隨後被美國國家標准局和美國國家標准協會(American National Standard Institute, ANSI) 承認。
DES使用56位密鑰對64位的數據塊進行加密,並對64位的數據塊進行16輪編碼。與每輪編碼時,一個48位的「每輪」密鑰值由56位的完整密鑰得出來。DES用軟體進行解碼需要用很長時間,而用硬體解碼速度非常快,但幸運的是當時大多數黑客並沒有足夠的設備製造出這種硬體設備。在1977年,人們估計要耗資兩千萬美元才能建成一個專門計算機用於DES的解密,而且需要12個小時的破解才能得到結果。所以,當時DES被認為是一種十分強壯的加密方法。
但是,當今的計算機速度越來越快了,製造一台這樣特殊的機器的花費已經降到了十萬美元左右,所以用它來保護十億美元的銀行間線纜時,就會仔細考慮了。另一個方面,如果只用它來保護一台伺服器,那麼DES確實是一種好的辦法,因為黑客絕不會僅僅為入侵一個伺服器而花那麼多的錢破解DES密文。由於現在已經能用二十萬美圓製造一台破譯DES的特殊的計算機,所以現在再對要求「強壯」加密的場合已經不再適用了。
三重DES
因為確定一種新的加密法是否真的安全是極為困難的,而且DES的唯一密碼學缺點,就是密鑰長度相對比較短,所以人們並沒有放棄使用DES,而是想出了一個解決其長度問題的方法,即採用三重DES。這種方法用兩個密鑰對明文進行三次加密,假設兩個密鑰是K1和K2,其演算法的步驟如圖5.9所示:
1. 用密鑰K1進行DEA加密。
2. 用K2對步驟1的結果進行DES解密。
3. 用步驟2的結果使用密鑰K1進行DES加密。
這種方法的缺點,是要花費原來三倍時間,從另一方面來看,三重DES的112位密鑰長度是很「強壯」的加密方式了
⑸ des加密演算法流程圖
DES(Data Encryption Standard)滿足了國家標准局欲達到的4個目的:提供高質量的數據保護,防止數據未經授權的泄露和未被察覺的修改;具有相當高的復雜性,使得破譯的開銷超過可能獲得的利益,同時又要便於理解和掌握;
DES演算法把64位的明文輸入塊變為64位的密文輸出塊,它所使用的密鑰也是64位,首先,DES把輸入的64位數據塊按位重新組合,並把輸出分為L0、R0兩部分,每部分各長32位,並進行前後置換(輸入的第58位換到第一位,第50位換到第2位,依此類推,最後一位是原來的第7位),最終由L0輸出左32位,R0輸出右32位,根據這個法則經過16次迭代運算後,得到L16、R16,將此作為輸入,進行與初始置換相反的逆置換,即得到密文輸出。
DES演算法的入口參數有三個:Key、Data、Mode。其中Key為8個位元組共64位,是DES演算法的工作密鑰;Data也為8個位元組64位,是要被加密或被解密的數據;Mode為DES的工作方式,有兩種:加密或解密,如果Mode為加密,則用Key去把數據Data進行加密,生成Data的密碼形式作為DES的輸出結果;如Mode為解密,則用Key去把密碼形式的數據Data解密,還原為Data的明碼形式作為DES的輸出結果。在使用DES時,雙方預先約定使用的」密碼」即Key,然後用Key去加密數據;接收方得到密文後使用同樣的Key解密得到原數據,這樣便實現了安全性較高的數據傳輸。
⑹ des加密演算法的問題
我加你了。
⑺ des加密演算法(c/c++)
des.h文件:
#ifndefCRYPTOPP_DES_H
#defineCRYPTOPP_DES_H
#include"cryptlib.h"
#include"misc.h"
NAMESPACE_BEGIN(CryptoPP)
classDES:publicBlockTransformation
{
public:
DES(constbyte*userKey,CipherDir);
voidProcessBlock(constbyte*inBlock,byte*outBlock)const;
voidProcessBlock(byte*inoutBlock)const
{DES::ProcessBlock(inoutBlock,inoutBlock);}
enum{KEYLENGTH=8,BLOCKSIZE=8};
unsignedintBlockSize()const{returnBLOCKSIZE;}
protected:
staticconstword32Spbox[8][64];
SecBlock<word32>k;
};
classDESEncryption:publicDES
{
public:
DESEncryption(constbyte*userKey)
:DES(userKey,ENCRYPTION){}
};
classDESDecryption:publicDES
{
public:
DESDecryption(constbyte*userKey)
:DES(userKey,DECRYPTION){}
};
classDES_EDE_Encryption:publicBlockTransformation
{
public:
DES_EDE_Encryption(constbyte*userKey)
:e(userKey,ENCRYPTION),d(userKey+DES::KEYLENGTH,DECRYPTION){}
voidProcessBlock(constbyte*inBlock,byte*outBlock)const;
voidProcessBlock(byte*inoutBlock)const;
enum{KEYLENGTH=16,BLOCKSIZE=8};
unsignedintBlockSize()const{returnBLOCKSIZE;}
private:
DESe,d;
};
classDES_EDE_Decryption:publicBlockTransformation
{
public:
DES_EDE_Decryption(constbyte*userKey)
:d(userKey,DECRYPTION),e(userKey+DES::KEYLENGTH,ENCRYPTION){}
voidProcessBlock(constbyte*inBlock,byte*outBlock)const;
voidProcessBlock(byte*inoutBlock)const;
enum{KEYLENGTH=16,BLOCKSIZE=8};
unsignedintBlockSize()const{returnBLOCKSIZE;}
private:
DESd,e;
};
classTripleDES_Encryption:publicBlockTransformation
{
public:
TripleDES_Encryption(constbyte*userKey)
:e1(userKey,ENCRYPTION),d(userKey+DES::KEYLENGTH,DECRYPTION),
e2(userKey+2*DES::KEYLENGTH,ENCRYPTION){}
voidProcessBlock(constbyte*inBlock,byte*outBlock)const;
voidProcessBlock(byte*inoutBlock)const;
enum{KEYLENGTH=24,BLOCKSIZE=8};
unsignedintBlockSize()const{returnBLOCKSIZE;}
private:
DESe1,d,e2;
};
classTripleDES_Decryption:publicBlockTransformation
{
public:
TripleDES_Decryption(constbyte*userKey)
:d1(userKey+2*DES::KEYLENGTH,DECRYPTION),e(userKey+DES::KEYLENGTH,ENCRYPTION),
d2(userKey,DECRYPTION){}
voidProcessBlock(constbyte*inBlock,byte*outBlock)const;
voidProcessBlock(byte*inoutBlock)const;
enum{KEYLENGTH=24,BLOCKSIZE=8};
unsignedintBlockSize()const{returnBLOCKSIZE;}
private:
DESd1,e,d2;
};
NAMESPACE_END
#endif
des.cpp文件:
//des.cpp-modifiedbyWeiDaifrom:
/*
*
*circa1987,'s1977
*publicdomaincode.,but
*theactualencrypt/
*Outerbridge'sDEScodeasprintedinSchneier's"AppliedCryptography."
*
*Thiscodeisinthepublicdomain.Iwouldappreciatebugreportsand
*enhancements.
*
*PhilKarnKA9Q,[email protected],August1994.
*/
#include"pch.h"
#include"misc.h"
#include"des.h"
NAMESPACE_BEGIN(CryptoPP)
/*
*Threeofthesetables,theinitialpermutation,thefinal
*,areregularenoughthat
*forspeed,wehard-codethem.They'rehereforreferenceonly.
*Also,,gensp.c,
*tobuildthecombinedSPbox,Spbox[].They'realsoherejust
*forreference.
*/
#ifdefnotdef
/*initialpermutationIP*/
staticbyteip[]={
58,50,42,34,26,18,10,2,
60,52,44,36,28,20,12,4,
62,54,46,38,30,22,14,6,
64,56,48,40,32,24,16,8,
57,49,41,33,25,17,9,1,
59,51,43,35,27,19,11,3,
61,53,45,37,29,21,13,5,
63,55,47,39,31,23,15,7
};
/*finalpermutationIP^-1*/
staticbytefp[]={
40,8,48,16,56,24,64,32,
39,7,47,15,55,23,63,31,
38,6,46,14,54,22,62,30,
37,5,45,13,53,21,61,29,
36,4,44,12,52,20,60,28,
35,3,43,11,51,19,59,27,
34,2,42,10,50,18,58,26,
33,1,41,9,49,17,57,25
};
/*expansionoperationmatrix*/
staticbyteei[]={
32,1,2,3,4,5,
4,5,6,7,8,9,
8,9,10,11,12,13,
12,13,14,15,16,17,
16,17,18,19,20,21,
20,21,22,23,24,25,
24,25,26,27,28,29,
28,29,30,31,32,1
};
/*The(in)famousS-boxes*/
staticbytesbox[8][64]={
/*S1*/
14,4,13,1,2,15,11,8,3,10,6,12,5,9,0,7,
0,15,7,4,14,2,13,1,10,6,12,11,9,5,3,8,
4,1,14,8,13,6,2,11,15,12,9,7,3,10,5,0,
15,12,8,2,4,9,1,7,5,11,3,14,10,0,6,13,
/*S2*/
15,1,8,14,6,11,3,4,9,7,2,13,12,0,5,10,
3,13,4,7,15,2,8,14,12,0,1,10,6,9,11,5,
0,14,7,11,10,4,13,1,5,8,12,6,9,3,2,15,
13,8,10,1,3,15,4,2,11,6,7,12,0,5,14,9,
/*S3*/
10,0,9,14,6,3,15,5,1,13,12,7,11,4,2,8,
13,7,0,9,3,4,6,10,2,8,5,14,12,11,15,1,
13,6,4,9,8,15,3,0,11,1,2,12,5,10,14,7,
1,10,13,0,6,9,8,7,4,15,14,3,11,5,2,12,
/*S4*/
7,13,14,3,0,6,9,10,1,2,8,5,11,12,4,15,
13,8,11,5,6,15,0,3,4,7,2,12,1,10,14,9,
10,6,9,0,12,11,7,13,15,1,3,14,5,2,8,4,
3,15,0,6,10,1,13,8,9,4,5,11,12,7,2,14,
/*S5*/
2,12,4,1,7,10,11,6,8,5,3,15,13,0,14,9,
14,11,2,12,4,7,13,1,5,0,15,10,3,9,8,6,
4,2,1,11,10,13,7,8,15,9,12,5,6,3,0,14,
11,8,12,7,1,14,2,13,6,15,0,9,10,4,5,3,
/*S6*/
12,1,10,15,9,2,6,8,0,13,3,4,14,7,5,11,
10,15,4,2,7,12,9,5,6,1,13,14,0,11,3,8,
9,14,15,5,2,8,12,3,7,0,4,10,1,13,11,6,
4,3,2,12,9,5,15,10,11,14,1,7,6,0,8,13,
/*S7*/
4,11,2,14,15,0,8,13,3,12,9,7,5,10,6,1,
13,0,11,7,4,9,1,10,14,3,5,12,2,15,8,6,
1,4,11,13,12,3,7,14,10,15,6,8,0,5,9,2,
6,11,13,8,1,4,10,7,9,5,0,15,14,2,3,12,
/*S8*/
13,2,8,4,6,15,11,1,10,9,3,14,5,0,12,7,
1,15,13,8,10,3,7,4,12,5,6,11,0,14,9,2,
7,11,4,1,9,12,14,2,0,6,10,13,15,3,5,8,
2,1,14,7,4,10,8,13,15,12,9,0,3,5,6,11
};
/*32--boxes*/
staticbytep32i[]={
16,7,20,21,
29,12,28,17,
1,15,23,26,
5,18,31,10,
2,8,24,14,
32,27,3,9,
19,13,30,6,
22,11,4,25
};
#endif
/*permutedchoicetable(key)*/
staticconstbytepc1[]={
57,49,41,33,25,17,9,
1,58,50,42,34,26,18,
10,2,59,51,43,35,27,
19,11,3,60,52,44,36,
63,55,47,39,31,23,15,
7,62,54,46,38,30,22,
14,6,61,53,45,37,29,
21,13,5,28,20,12,4
};
/*numberleftrotationsofpc1*/
staticconstbytetotrot[]={
1,2,4,6,8,10,12,14,15,17,19,21,23,25,27,28
};
/*permutedchoicekey(table)*/
staticconstbytepc2[]={
14,17,11,24,1,5,
3,28,15,6,21,10,
23,19,12,4,26,8,
16,7,27,20,13,2,
41,52,31,37,47,55,
30,40,51,45,33,48,
44,49,39,56,34,53,
46,42,50,36,29,32
};
/*EndofDES-definedtables*/
/*bit0isleft-mostinbyte*/
staticconstintbytebit[]={
0200,0100,040,020,010,04,02,01
};
/*Setkey(initializekeyschelearray)*/
DES::DES(constbyte*key,CipherDirdir)
:k(32)
{
SecByteBlockbuffer(56+56+8);
byte*constpc1m=buffer;/*placetomodifypc1into*/
byte*constpcr=pc1m+56;/*placetorotatepc1into*/
byte*constks=pcr+56;
registerinti,j,l;
intm;
for(j=0;j<56;j++){/*convertpc1tobitsofkey*/
l=pc1[j]-1;/*integerbitlocation*/
m=l&07;/*findbit*/
pc1m[j]=(key[l>>3]&/*findwhichkeybytelisin*/
bytebit[m])/*andwhichbitofthatbyte*/
?1:0;/*andstore1-bitresult*/
}
for(i=0;i<16;i++){/*keychunkforeachiteration*/
memset(ks,0,8);/*Clearkeyschele*/
for(j=0;j<56;j++)/*rotatepc1therightamount*/
pcr[j]=pc1m[(l=j+totrot[i])<(j<28?28:56)?l:l-28];
/**/
for(j=0;j<48;j++){/*selectbitsindivially*/
/*checkbitthatgoestoks[j]*/
if(pcr[pc2[j]-1]){
/*maskitinifit'sthere*/
l=j%6;
ks[j/6]|=bytebit[l]>>2;
}
}
/*Nowconverttoodd/eveninterleavedformforuseinF*/
k[2*i]=((word32)ks[0]<<24)
|((word32)ks[2]<<16)
|((word32)ks[4]<<8)
|((word32)ks[6]);
k[2*i+1]=((word32)ks[1]<<24)
|((word32)ks[3]<<16)
|((word32)ks[5]<<8)
|((word32)ks[7]);
}
if(dir==DECRYPTION)//reversekeyscheleorder
for(i=0;i<16;i+=2)
{
std::swap(k[i],k[32-2-i]);
std::swap(k[i+1],k[32-1-i]);
}
}
/**/
/*Ccodeonlyinportableversion*/
//RichardOuterbridge'sinitialpermutationalgorithm
/*
inlinevoidIPERM(word32&left,word32&right)
{
word32work;
work=((left>>4)^right)&0x0f0f0f0f;
right^=work;
left^=work<<4;
work=((left>>16)^right)&0xffff;
right^=work;
left^=work<<16;
work=((right>>2)^left)&0x33333333;
left^=work;
right^=(work<<2);
work=((right>>8)^left)&0xff00ff;
left^=work;
right^=(work<<8);
right=rotl(right,1);
work=(left^right)&0xaaaaaaaa;
left^=work;
right^=work;
left=rotl(left,1);
}
inlinevoidFPERM(word32&left,word32&right)
{
word32work;
right=rotr(right,1);
work=(left^right)&0xaaaaaaaa;
left^=work;
right^=work;
left=rotr(left,1);
work=((left>>8)^right)&0xff00ff;
right^=work;
left^=work<<8;
work=((left>>2)^right)&0x33333333;
right^=work;
left^=work<<2;
work=((right>>16)^left)&0xffff;
left^=work;
right^=work<<16;
work=((right>>4)^left)&0x0f0f0f0f;
left^=work;
right^=work<<4;
}
*/
//WeiDai''sinitialpermutation
//algorithm,
//(likeinMSVC)
inlinevoidIPERM(word32&left,word32&right)
{
word32work;
right=rotl(right,4U);
work=(left^right)&0xf0f0f0f0;
left^=work;
right=rotr(right^work,20U);
work=(left^right)&0xffff0000;
left^=work;
right=rotr(right^work,18U);
work=(left^right)&0x33333333;
left^=work;
right=rotr(right^work,6U);
work=(left^right)&0x00ff00ff;
left^=work;
right=rotl(right^work,9U);
work=(left^right)&0xaaaaaaaa;
left=rotl(left^work,1U);
right^=work;
}
inlinevoidFPERM(word32&left,word32&right)
{
word32work;
right=rotr(right,1U);
work=(left^right)&0xaaaaaaaa;
right^=work;
left=rotr(left^work,9U);
work=(left^right)&0x00ff00ff;
right^=work;
left=rotl(left^work,6U);
work=(left^right)&0x33333333;
right^=work;
left=rotl(left^work,18U);
work=(left^right)&0xffff0000;
right^=work;
left=rotl(left^work,20U);
work=(left^right)&0xf0f0f0f0;
right^=work;
left=rotr(left^work,4U);
}
//
voidDES::ProcessBlock(constbyte*inBlock,byte*outBlock)const
{
word32l,r,work;
#ifdefIS_LITTLE_ENDIAN
l=byteReverse(*(word32*)inBlock);
r=byteReverse(*(word32*)(inBlock+4));
#else
l=*(word32*)inBlock;
r=*(word32*)(inBlock+4);
#endif
IPERM(l,r);
constword32*kptr=k;
for(unsignedi=0;i<8;i++)
{
work=rotr(r,4U)^kptr[4*i+0];
l^=Spbox[6][(work)&0x3f]
^Spbox[4][(work>>8)&0x3f]
^Spbox[2][(work>>16)&0x3f]
^Spbox[0][(work>>24)&0x3f];
work=r^kptr[4*i+1];
l^=Spbox[7][(work)&0x3f]
^Spbox[5][(work>>8)&0x3f]
^Spbox[3][(work>>16)&0x3f]
^Spbox[1][(work>>24)&0x3f];
work=rotr(l,4U)^kptr[4*i+2];
r^=Spbox[6][(work)&0x3f]
^Spbox[4][(work>>8)&0x3f]
^Spbox[2][(work>>16)&0x3f]
^Spbox[0][(work>>24)&0x3f];
work=l^kptr[4*i+3];
r^=Spbox[7][(work)&0x3f]
^Spbox[5][(work>>8)&0x3f]
^Spbox[3][(work>>16)&0x3f]
^Spbox[1][(work>>24)&0x3f];
}
FPERM(l,r);
#ifdefIS_LITTLE_ENDIAN
*(word32*)outBlock=byteReverse(r);
*(word32*)(outBlock+4)=byteReverse(l);
#else
*(word32*)outBlock=r;
*(word32*)(outBlock+4)=l;
#endif
}
voidDES_EDE_Encryption::ProcessBlock(byte*inoutBlock)const
{
e.ProcessBlock(inoutBlock);
d.ProcessBlock(inoutBlock);
e.ProcessBlock(inoutBlock);
}
voidDES_EDE_Encryption::ProcessBlock(constbyte*inBlock,byte*outBlock)const
{
e.ProcessBlock(inBlock,outBlock);
d.ProcessBlock(outBlock);
e.ProcessBlock(outBlock);
}
voidDES_EDE_Decryption::ProcessBlock(byte*inoutBlock)const
{
d.ProcessBlock(inoutBlock);
e.ProcessBlock(inoutBlock);
d.ProcessBlock(inoutBlock);
}
voidDES_EDE_Decryption::ProcessBlock(constbyte*inBlock,byte*outBlock)const
{
d.ProcessBlock(inBlock,outBlock);
e.ProcessBlock(outBlock);
d.ProcessBlock(outBlock);
}
voidTripleDES_Encryption::ProcessBlock(byte*inoutBlock)const
{
e1.ProcessBlock(inoutBlock);
d.ProcessBlock(inoutBlock);
e2.ProcessBlock(inoutBlock);
}
voidTripleDES_Encryption::ProcessBlock(constbyte*inBlock,byte*outBlock)const
{
e1.ProcessBlock(inBlock,outBlock);
d.ProcessBlock(outBlock);
e2.ProcessBlock(outBlock);
}
voidTripleDES_Decryption::ProcessBlock(byte*inoutBlock)const
{
d1.ProcessBlock(inoutBlock);
e.ProcessBlock(inoutBlock);
d2.ProcessBlock(inoutBlock);
}
voidTripleDES_Decryption::ProcessBlock(constbyte*inBlock,byte*outBlock)const
{
d1.ProcessBlock(inBlock,outBlock);
e.ProcessBlock(outBlock);
d2.ProcessBlock(outBlock);
}
NAMESPACE_END
程序運行如下:
⑻ 關於DES加密演算法
數據加密演算法
數據加密演算法DES
數據加密演算法(Data Encryption Algorithm,DEA)的數據加密標准(Data Encryption Standard,DES)是規范的描述,它出自 IBM 的研究工作,並在 1997 年被美國政府正式採納。它很可能是使用最廣泛的秘鑰系統,特別是在保護金融數據的安全中,最初開發的 DES 是嵌入硬 件中的。通常,自動取款機(Automated Teller Machine,ATM)都使用 DES。
DES 使用一個 56 位的密鑰以及附加的 8 位奇偶校驗位,產生最大 64 位的分組大小。這是一個迭代的分組密碼,使用稱為 Feistel 的技術,其中將加密的文本塊分成兩半。使用子密鑰對其中一半應用循環功能,然後將輸出與另一半進行「異或」運算;接著交換這兩半,這一過程會繼續下去,但最後一個循環不交換。DES 使用 16 個循環。
攻擊 DES 的主要形式被稱為蠻力的或徹底密鑰搜索,即重復嘗試各種密鑰直到有一個符合為止。如果 DES 使用 56 位的密鑰,則可能的密鑰數量是 2 的 56 次方個。隨著計算機系統能力的不斷發展,DES 的安全性比它剛出現時會弱得多,然而從非關鍵性質的實際出發,仍可以認為它是足夠的。不過 ,DES 現在僅用於舊系統的鑒定,而更多地選擇新的加密標准 — 高級加密標准(Advanced Encryption Standard,AES)。
DES 的常見變體是三重 DES,使用 168 位的密鑰對資料進行三次加密的一種機制;它通常(但非始終)提供極其強大的安全性。如果三個 56 位的子元素都相同,則三重 DES 向後兼容 DES。
IBM 曾對 DES 擁有幾年的專利權,但是在 1983 年已到期,並且處於公有范圍中,允許在特定條件下可以免除專利使用費而使用。
⑼ DES加密演算法的測試數據示例
其實你只要再寫個解密的過程看看加密完能不能還原回去就好了。。解密過程和加密過程基本一樣,就是使用子密鑰時的順序是倒著的。
明文是 testdata,密鑰是mydeskey 正確的des加密後二進制密文:
用base64編碼形成的密文是:4wynQOzDaiA=
解密後:
⑽ DES加密演算法C語言實現
#include<iostream.h>
class SubKey{ //定義子密鑰為一個類
public:
int key[8][6];
}subkey[16]; //定義子密鑰對象數組
class DES{
int encipher_decipher; //判斷加密還是解密
int key_in[8][8]; //用戶原始輸入的64位二進制數
int key_out[8][7]; //除去每行的最後一位校驗位
int c0_d0[8][7]; //存儲經PC-1轉換後的56位數據
int c0[4][7],d0[4][7]; //分別存儲c0,d0
int text[8][8]; //64位明文
int text_ip[8][8]; //經IP轉換過後的明文
int A[4][8],B[4][8]; //A,B分別存儲經IP轉換過後明文的兩部分,便於交換
int temp[8][6]; //存儲經擴展置換後的48位二進制值
int temp1[8][6]; //存儲和子密鑰異或後的結果
int s_result[8][4]; //存儲經S變換後的32位值
int text_p[8][4]; //經P置換後的32位結果
int secret_ip[8][8]; //經逆IP轉換後的密文
public:
void Key_Putting();
void PC_1();
int function(int,int); //異或
void SubKey_Proction();
void IP_Convert();
void f();
void _IP_Convert();
void Out_secret();
};
void DES::Key_Putting() //得到密鑰中對演算法有用的56位
{
cout<<"請輸入64位的密鑰(8行8列且每行都得有奇數個1):\n";
for(int i=0;i<8;i++)
for(int j=0;j<8;j++){
cin>>key_in[i][j];
if(j!=7) key_out[i][j]=key_in[i][j];
}
}
void DES::PC_1() //PC-1置換函數
{
int pc_1[8][7]={ //PC-1
{57, 49, 41, 33, 25, 17, 9},
{1, 58, 50, 42, 34, 26, 18},
{10, 2, 59, 51, 43, 35, 27},
{19, 11, 3, 60, 52, 44, 36},
{63, 55, 47, 39, 31, 23, 15},
{7, 62, 54, 46, 38, 30, 22},
{14, 6, 61, 53, 45, 37, 29},
{21, 13, 5, 28, 20, 12, 4}
};
int i,j;
for(i=0;i<8;i++)
for(j=0;j<7;j++)
c0_d0[i][j]=key_out[ (pc_1[i][j]-1)/8 ][ (pc_1[i][j]-1)%8 ];
}
int DES::function(int a,int b) //模擬二進制數的異或運算,a和b為整型的0和1,返回值為整型的0或1
{
if(a!=b)return 1;
else return 0;
}
void DES::SubKey_Proction() //生成子密鑰
{
int move[16][2]={ //循環左移的位數
1 , 1 , 2 , 1 ,
3 , 2 , 4 , 2 ,
5 , 2 , 6 , 2 ,
7 , 2 , 8 , 2 ,
9 , 1, 10 , 2,
11 , 2, 12 , 2,
13 , 2, 14 , 2,
15 , 2, 16 , 1
};
int pc_2[8][6]={ //PC-2
14, 17 ,11 ,24 , 1 , 5,
3 ,28 ,15 , 6 ,21 ,10,
23, 19, 12, 4, 26, 8,
16, 7, 27, 20 ,13 , 2,
41, 52, 31, 37, 47, 55,
30, 40, 51, 45, 33, 48,
44, 49, 39, 56, 34, 53,
46, 42, 50, 36, 29, 32
};
for(int i=0;i<16;i++) //生成子密鑰
{
int j,k;
int a[2],b[2];
int bb[28],cc[28];
for(j=0;j<4;j++)
for(k=0;k<7;k++)
c0[j][k]=c0_d0[j][k];
for(j=4;j<8;j++)
for(k=0;k<7;k++)
d0[j-4][k]=c0_d0[j][k];
for(j=0;j<4;j++)
for(k=0;k<7;k++){
bb[7*j+k]=c0[j][k];
cc[7*j+k]=d0[j][k];
}
for(j=0;j<move[i][1];j++){
a[j]=bb[j];
b[j]=cc[j];
}
for(j=0;j<28-move[i][1];j++){
bb[j]=bb[j+1];
cc[j]=cc[j+1];
}
for(j=0;j<move[i][1];j++){
bb[27-j]=a[j];
cc[27-j]=b[j];
}
for(j=0;j<28;j++){
c0[j/7][j%7]=bb[j];
d0[j/7][j%7]=cc[j];
}
for(j=0;j<4;j++) //L123--L128是把c0,d0合並成c0_d0
for(k=0;k<7;k++)
c0_d0[j][k]=c0[j][k];
for(j=4;j<8;j++)
for(k=0;k<7;k++)
c0_d0[j][k]=d0[j-4][k];
for(j=0;j<8;j++) //對Ci,Di進行PC-2置換
for(k=0;k<6;k++)
subkey[i].key[j][k]=c0_d0[ (pc_2[j][k]-1)/7 ][ (pc_2[j][k]-1)%7 ];
}
}
void DES::IP_Convert()
{
int IP[8][8]={ //初始置換IP矩陣
58, 50, 42, 34, 26, 18, 10, 2,
60, 52, 44, 36, 28, 20, 12, 4,
62, 54, 46, 38, 30, 22, 14, 6,
64, 56, 48, 40, 32, 24, 16, 8,
57, 49, 41, 33, 25, 17, 9, 1,
59, 51, 43, 35, 27, 19, 11, 3,
61, 53, 45, 37, 29, 21, 13, 5,
63, 55, 47, 39, 31, 23, 15, 7
};
cout<<"你好,你要加密還是解密?加密請按1號鍵(輸入1),解密請按2號鍵,並確定."<<'\n';
cin>>encipher_decipher;
char * s;
if(encipher_decipher==1) s="明文";
else s="密文";
cout<<"請輸入64位"<<s<<"(二進制):\n";
int i,j;
for(i=0;i<8;i++)
for(j=0;j<8;j++)
cin>>text[i][j];
for(i=0;i<8;i++) //進行IP變換
for(j=0;j<8;j++)
text_ip[i][j]=text[ (IP[i][j]-1)/8 ][ (IP[i][j]-1)%8 ];
}