c對稱加密
#include<stdio.h>
#include<string.h>
voidEncode(chars[],charkey[]){
inti,j,k,t,ch;
chartmp[9];
intlen=strlen(key);
for(i=0,j=0;s[i];++i){
t=key[j];
for(k=0;k<8;++k){
tmp[k]=(s[i]&1)^(t&1);
s[i]>>=1;
t>>=1;
}
ch=0;
for(k=7;k>=0;--k)
ch=2*ch+tmp[k];
s[i]=ch;
j=(j+1)%len;
}
}
intmain(){
chars[]="AbcdXYZ2014";
charkey[]="GodKnow";
printf("明文:%s ",s);
Encode(s,key);
printf("密文: %s ",s);
Encode(s,key);
printf("明文:%s ",s);
return0;
}
『貳』 簡單的對稱數據文件加密c語言程序 課設要用 急求大神
#include <sdtio.h>
int encryption(char byCode)
{
char byTsCode;
__asm xor eax,eax
__asm mov al,byCode
__asm xor al,0xe8
__asm byTsCode,al
return byTsCode
}
int main()
{
char* stDecode[8+1]="password\n";
printf("%s",stDecode);
int i;
for(i=0,i<(8+1),i++)
{stDecode[i]=(char)encryption(stDecode[i]);}
printf("%s",stDecode);
for(i=0,i<(8+1),i++)
{stDecode[i]=(char)encryption(stDecode[i]);}
printf("%s",stDecode);
retrin 0;
}
『叄』 使用c語言實現對稱加密演算法、非對稱加密演算法、HASH演算法,誰來提供個思路阿
網路找找
有RSA演算法,MD5演算法,維尼格演算法
這些演算法都很好找啊,我空間裡面就有一篇RSA的
網路搜索
這些代碼本來就難懂,涉及到數學的東西也很多
據說IBM公司DES加密的源代碼公布了十幾年後才有人弄懂
『肆』 加密:EkM=C 解密:DkC=M是什麼加密演算法
正常來說 都使用P來取代你所給出的關系中的M,除非M是取自漢語「明文」的拼音(Mingwen)
P——明文(Plaintext),表示全體可能出現的明文集合
C——密文(Ciphertext),表示全體可能出現的密文集合
K——密鑰(Key),密鑰是加密演算法中的可變參數
E——加密演算法(Encryption algorithm),由公式、法則或者程序構成
D——解密演算法(Decryption algorithm),它是E的逆演算法。
當給定密鑰K時,
C = Ek(P), 對明文P進行加密(E操作)後得到密文C
P = Dk(C) = Dk(Ek(P)), 對密文C解密(D操作)後得明文P
加密設計主要是確定E,D,K。
根據E和D的對稱與非對稱關系,加密演算法又分為對稱加密演算法和非對稱加密演算法,其代表性演算法分別為DES(Data Encryption Standard)和RSA
『伍』 凱撒加密演算法(最簡單的對稱加密)
凱撒密碼是羅馬擴張時期朱利斯• 凱撒(Julius Caesar)創造的,用於加密通過信使傳遞的作戰命令。它將字母表中的字母移動一定位置而實現加密。例如如果向右移動 2 位,則 字母 A 將變為 C,字母 B 將變為 D,…,字母 X 變成 Z,字母 Y 則變為 A,字母 Z 變為 B。
因此,假如有個明文字元串「Hello」用這種方法加密的話,將變為密文: 「Jgnnq」 。而如果要解密,則只要將字母向相反方向移動同樣位數即可。如密文「Jgnnq」每個字母左移兩位 變為「Hello」 。這里,移動的位數「2」是加密和解密所用的密鑰。
該程序既可用於加密又可用於解密。只要傳入明文和偏移量即可加密,解密需要傳入密文和負的偏移量就可以解密。
輸出的結果:
凱撒密碼由於加解密比較簡單,密鑰總共只有 26 個,攻擊者得到密文後即使不知道密鑰,也可一個一個地試過去,最多試 26 次就可以得到明文。
這里不光根據 offset 偏移進行加密,還加上了字元所在的下標進行混合加密。
輸出的結果:
『陸』 常用的對稱密碼演算法有哪些
對稱加密演算法用來對敏感數據等信息進行加密,常用的演算法包括:
DES(Data Encryption Standard):數據加密標准,速度較快,適用於加密大量數據的場合。
3DES(Triple DES):是基於DES,對一塊數據用三個不同的密鑰進行三次加密,強度更高。
AES(Advanced Encryption Standard):高級加密標准,是下一代的加密演算法標准,速度快,安全級別高;
『柒』 誰幫我介紹下加密對稱演算法
A.對稱加密技術 a. 描述 對稱演算法(symmetric algorithm),有時又叫傳統密碼演算法,就是加密密鑰能夠從解密密鑰中推算出來,同時解密密鑰也可以從加密密鑰中推算出來。而在大多數的對稱演算法中,加密密鑰和解密密鑰是相同的。所以也稱這種加密演算法為秘密密鑰演算法或單密鑰演算法。它要求發送方和接收方在安全通信之前,商定一個密鑰。對稱演算法的安全性依賴於密鑰,泄漏密鑰就意味著任何人都可以對他們發送或接收的消息解密,所以密鑰的保密性對通信性至關重要。 b.特點分析 對稱加密的優點在於演算法實現後的效率高、速度快。 對稱加密的缺點在於密鑰的管理過於復雜。如果任何一對發送方和接收方都有他們各自商議的密鑰的話,那麼很明顯,假設有N個用戶進行對稱加密通信,如果按照上述方法,則他們要產生N(N-1)把密鑰,每一個用戶要記住或保留N-1把密鑰,當N很大時,記住是不可能的,而保留起來又會引起密鑰泄漏可能性的增加。常用的對稱加密演算法有DES,DEA等。 B.非對稱加密技術 a.描述 非對稱加密(dissymmetrical encryption),有時又叫公開密鑰演算法(public key algorithm)。這種加密演算法是這樣設計的:用作加密的密鑰不同於用作解密的密鑰,而且解密密鑰不能根據加密密鑰計算出來(至少在合理假定的長時間內)。之所以又叫做公開密鑰演算法是由於加密密鑰可以公開,即陌生人可以得到它並用來加密信息,但只有用相應的解密密鑰才能解密信息。在這種加密演算法中,加密密鑰被叫做公開密鑰(public key),而解密密鑰被叫做私有密鑰(private key)。 b.特點分析 非對稱加密的缺點在於演算法實現後的效率低、速度慢。 非對稱加密的優點在於用戶不必記憶大量的提前商定好的密鑰,因為發送方和接收方事先根本不必商定密鑰,發放方只要可以得到可靠的接收方的公開密鑰就可以給他發送信息了,而且即使雙方根本互不相識。但為了保證可靠性,非對稱加密演算法需要一種與之相配合使用的公開密鑰管理機制,這種公開密鑰管理機制還要解決其他一些公開密鑰所帶來的問題。常用的非對稱加密演算法有RSA等。 (3) 關於密碼技術 密碼技術包括加密技術和密碼分析技術,也即加密和解密技術兩個方面。在一個新的加密演算法的研發需要有相應的數學理論證明,證明這個演算法的安全性有多高,同時還要從密碼分析的角度對這個演算法進行安全證明,說明這個演算法對於所知的分析方法來說是有防範作用的。 三、對稱加密演算法分析 對稱加密演算法的分類 對稱加密演算法可以分成兩類:一類為序列演算法(stream algorithm):一次只對明文中單個位(有時為位元組)加密或解密運算。另一類為分組演算法(block algorithm):一次明文的一組固定長度的位元組加密或解密運算。 現代計算機密碼演算法一般採用的都是分組演算法,而且一般分組的長度為64位,之所以如此是由於這個長度大到足以防止分析破譯,但又小到足以方便使用。 1.DES加密演算法 (Data Encryption Standard )
(1) 演算法簡介
1973 年 5 月 15 日,美國國家標准局 (NBS) 在「聯邦注冊」上發布了一條通知,徵求密碼演算法,用於在傳輸和存儲期間保護數據。IBM 提交了一個候選演算法,它是 IBM 內部開發的,名為 LUCIFER。在美國國家安全局 (NSA) 的「指導」下完成了演算法評估之後,在 1977 年 7 月 15 日,NBS 採納了 LUCIFER 演算法的修正版作為新的數據加密標准。
原先規定使用10年,但由於新的加密標准還沒有完成,所以DES演算法及其的變形演算法一直廣泛的應用於信息加密方面。 (2) 演算法描述 (包括加密和解密)
Feistel結構(畫圖說明)。
DES 的工作方式:可怕的細節
DES 將消息分成 64 位(即 16 個十六進制數)一組進行加密。DES 使用「密鑰」進行加密,從符號的角度來看,「密鑰」的長度是 16 個十六進制數(或 64 位)。但是,由於某些原因(可能是因為 NSA 給 NBS 的「指引」),DES 演算法中每逢第 8 位就被忽略。這造成密鑰的實際大小變成 56 位。編碼系統對「強行」或「野蠻」攻擊的抵抗力與其密鑰空間或者系統可能有多少密鑰有直接關系。使用的位數越多轉換出的密鑰也越多。密鑰越多,就意味著強行攻擊中計算密鑰空間中可能的密鑰范圍所需的時間就越長。從總長度中切除 8 位就會在很大程度上限制了密鑰空間,這樣系統就更容易受到破壞。
DES 是塊加密演算法。這表示它處理特定大小的純文本塊(通常是 64 位),然後返回相同大小的密碼塊。這樣,64 位(每位不是 0 就是 1)有 264 種可能排列,DES 將生成其中的一種排列。每個 64 位的塊都被分成 L、R 左右兩塊,每塊 32 位。
DES 演算法使用以下步驟:
1. 創建 16 個子密鑰,每個長度是 48 位。根據指定的順序或「表」置換 64 位的密鑰。如果表中的第一項是 "27",這表示原始密鑰 K 中的第 27 位將變成置換後的密鑰 K+ 的第一位。如果表的第二項是 36,則這表示原始密鑰中的第 36 位將變成置換後密鑰的第二位,以此類推。這是一個線性替換方法,它創建了一種線性排列。置換後的密鑰中只出現了原始密鑰中的 56 位。
2. 接著,將這個密鑰分成左右兩半,C0 和 D0,每一半 28 位。定義了 C0 和 D0 之後,創建 16 個 Cn 和 Dn 塊,其中 1<=n<=16。每一對 Cn 和 Dn 塊都通過使用標識「左移位」的表分別從前一對 Cn-1 和 Dn-1 形成,n = 1, 2, ..., 16,而「左移位」表說明了要對哪一位進行操作。在所有情況下,單一左移位表示這些位輪流向左移動一個位置。在一次左移位之後,28 個位置中的這些位分別是以前的第 2、3……28 位。
通過將另一個置換表應用於每一個 CnDn 連接對,從而形成密鑰 Kn,1<=n<=16。每一對有 56 位,而置換表只使用其中的 48 位,因為每逢第 8 位都將被忽略。
3. 編碼每個 64 位的數據塊。
64 位的消息數據 M 有一個初始置換 IP。這將根據置換表重新排列這些位,置換表中的項按這些位的初始順序描述了它們新的排列。我們以前見過這種線性表結構。
使用函數 f 來生成一個 32 位的塊,函數 f 對兩個塊進行操作,一個是 32 位的數據塊,一個是 48 位的密鑰 Kn,連續迭代 16 次,其中 1<=n<=16。用 + 表示 XOR 加法(逐位相加,模除 2)。然後,n 從 1 到 16,計算 Ln = Rn-1 Rn = Ln-1 + f(Rn-1,Kn)。即在每次迭代中,我們用前一結果的右邊 32 位,並使它們成為當前步驟中的左邊 32 位。對於當前步驟中的右邊 32 位,我們用演算法 f XOR 前一步驟中的左邊 32 位。
要計算 f,首先將每一塊 Rn-1 從 32 位擴展到 48 位。可以使用選擇表來重復 Rn-1 中的一些位來完成這一操作。這個選擇表的使用就成了函數 f。因此 f(Rn-1) 的輸入塊是 32 位,輸出塊是 48 位。f 的輸出是 48 位,寫成 8 塊,每塊 6 位,這是通過根據已知表按順序選擇輸入中的位來實現的。
我們已經使用選擇表將 Rn-1 從 32 位擴展成 48 位,並將結果 XOR 密鑰 Kn。現在有 48 位,或者是 8 組,每組 6 位。每組中的 6 位現在將經歷一次變換,該變換是演算法的核心部分:在叫做「S 盒」的表中,我們將這些位當作地址使用。每組 6 位在不同的 S 盒中表示不同的地址。該地址中是一個 4 位數字,它將替換原來的 6 位。最終結果是 8 組,每組 6 位變換成 8 組,每組 4 位(S 盒的 4 位輸出),總共 32 位。
f 計算的最後階段是對 S 盒輸出執行置換 P,以得到 f 的最終值。f 的形式是 f = P(S1(B1)S2(B2)...S8(B8))。置換 P 根據 32 位輸入,在以上的過程中通過置換輸入塊中的位,生成 32 位輸出。
解密只是加密的逆過程,使用以上相同的步驟,但要逆轉應用子密鑰的順序。DES 演算法是可逆的
(2) 演算法的安全性分析
在知道一些明文和密文分組的條件下,從理論上講很容易知道對DES進行一次窮舉攻擊的復雜程度:密鑰的長度是56位,所以會有 種的可能的密鑰。
在1993年的一年一度的世界密碼大會上,加拿大北方電信公司貝爾實驗室的 Michael Wiener 描述了如何構造一台專用的機器破譯DES,該機器利用一種每秒能搜索5000萬個密鑰的專用晶元。而且此機器的擴展性很好,投入的經費越多則效率越高。用100萬美元構造的機器平均3.5小時就可以破譯密碼。
如果不用專用的機器,破譯DES也有其他的方法。在1994年的世界密碼大會上,M.Matsui 提出一種攻克DES的新方法--"線性密碼分析"法。它可使用平均 個明文及其密文,在12台HP9000/735工作站上用此方法的軟體實現,花費50天時間完成對DES的攻擊。
如前所述DES作為加密演算法的標准已經二十多年了,可以說是一個很老的演算法,而在新的加密演算法的國際標准出現之前,許多DES的加固性改進演算法仍有實用價值,在本文的3.4節詳細的描述,同時考慮的以上所述DES的安全性已受到了威脅。
(4) 演算法的變體 三重DES(TDEA),使用3個密鑰,執行3次DES演算法:
加密:C = Ek3[Dk2[Ek1[P]]] 解密:P = Dk1[Ek2[Dk3[C]]]
特點:安全性得到增強,但是速度變慢。
2.AES
自 20 世紀 70 年代以來一直廣泛使用的「數據加密標准」(DES) 日益顯出衰老的痕跡,而一種新的演算法 -- Rijndael -- 正順利地逐漸變成新標准。這里,Larry Loeb 詳細說明了每一種演算法,並提供了關於為什麼會發生這種變化的內幕信息。
DES 演算法是全世界最廣泛使用的加密演算法。最近,就在 2000 年 10 月,它在其初期就取得的硬體方面的優勢已經阻礙了其發展,作為政府加密技術的基礎,它已由「高級加密標准」(AES) 中包含的另一種加密演算法代替了。AES 是指定的標准密碼系統,未來將由政府和銀行業用戶使用。AES 用來實際編碼數據的加密演算法與以前的 DES 標准不同。我們將討論這是如何發生的,以及 AES 中的 Rijndael 演算法是如何取代 DES 的演算法的。
「高級加密標准」成就
但直到 1997 年,美國國家標准技術局 (NIST) 才開始打著 AES 項目的旗幟徵集其接任者。1997 年 4 月的一個 AES 研討會宣布了以下 AES 成就的最初目標:
• 可供政府和商業使用的功能強大的加密演算法
• 支持標准密碼本方式
• 要明顯比 DES 3 有效
• 密鑰大小可變,這樣就可在必要時增加安全性
• 以公正和公開的方式進行選擇
• 可以公開定義
• 可以公開評估
AES 的草案中最低可接受要求和評估標準是:
A.1 AES 應該可以公開定義。
A.2 AES 應該是對稱的塊密碼。
A.3 AES 應該設計成密鑰長度可以根據需要增加。
A.4 AES 應該可以在硬體和軟體中實現。
A.5 AES 應該 a) 可免費獲得。
A.6 將根據以下要素評價符合上述要求的演算法:
1. 安全性(密碼分析所需的努力)
2. 計算效率
3. 內存需求
4. 硬體和軟體可適用性
5. 簡易性
6. 靈活性
7. 許可證需求(見上面的 A5)
Rijndael:AES 演算法獲勝者
1998年8月20日NIST召開了第一次AES侯選會議,並公布了15個AES侯選演算法。經過一年的考察,MARS,RC6,Rijndael,Serpent,Twofish共5種演算法通過了第二輪的選拔。2000 年 10 月,NIST 選擇 Rijndael(發音為 "Rhine dale")作為 AES 演算法。它目前還不會代替 DES 3 成為政府日常加密的方法,因為它還須通過測試過程,「使用者」將在該測試過程後發表他們的看法。但相信它可以順利過關。
Rijndael 是帶有可變塊長和可變密鑰長度的迭代塊密碼。塊長和密鑰長度可以分別指定成 128、192 或 256 位。
Rijndael 中的某些操作是在位元組級上定義的,位元組表示有限欄位 GF(28) 中的元素,一個位元組中有 8 位。其它操作都根據 4 位元組字定義。
加法照例對應於位元組級的簡單逐位 EXOR。
在多項式表示中,GF(28) 的乘法對應於多項式乘法模除階數為 8 的不可約分二進制多項式。(如果一個多項式除了 1 和它本身之外沒有其它約數,則稱它為不可約分的。)對於 Rijndael,這個多項式叫做 m(x),其中:m(x) = (x8 + x4 + x3 + x + 1) 或者十六進製表示為 '11B'。其結果是一個階數低於 8 的二進制多項式。不像加法,它沒有位元組級的簡單操作。
不使用 Feistel 結構!
在大多數加密演算法中,輪回變換都使用著名的 Feistel 結構。在這個結構中,中間 State 的位部分通常不做更改調換到另一個位置。(這種線性結構的示例是我們在 DES 部分中討論的那些表,即使用固定表的形式交換位。)Rijndael 的輪回變換不使用這個古老的 Feistel 結構。輪回變換由三個不同的可逆一致變換組成,叫做層。(「一致」在這里表示以類似方法處理 State 中的位。)
線性混合層保證了在多個輪回後的高度擴散。非線性層使用 S 盒的並行應用,該應用程序有期望的(因此是最佳的)最差非線性特性。S 盒是非線性的。依我看來,這就 DES 和 Rijndael 之間的密鑰概念差異。密鑰加法層是對中間 State 的輪回密鑰 (Round Key) 的簡單 EXOR,如以下所注。
Rijndael演算法
加密演算法
Rijndael演算法是一個由可變數據塊長和可變密鑰長的迭代分組加密演算法,數據塊長和密鑰長可分別為128,192或256比特。
數據塊要經過多次數據變換操作,每一次變換操作產生一個中間結果,這個中間結果叫做狀態。狀態可表示為二維位元組數組,它有4行,Nb列,且Nb等於數據塊長除32。如表2-3所示。
a0,0 a0,1 a0,2 a0,3 a0,4 a0,5
a1,0 a1,1 a1,2 a1,3 a1,4 a1,5
a2,0 a2,1 a2,2 a2,3 a2,4 a2,5
a3,0 a3,1 a3,2 a3,3 a3,4 a3,5
數據塊按a0,0 , a1,0 , a2,0 , a3,0 , a0,1 , a1,1 , a2,1 , a3,1 , a0,2…的順序映射為狀態中的位元組。在加密操作結束時,密文按同樣的順序從狀態中抽取。
密鑰也可類似地表示為二維位元組數組,它有4行,Nk列,且Nk等於密鑰塊長除32。演算法變換的圈數Nr由Nb和Nk共同決定,具體值列在表2-4中。
表3-2 Nb和Nk決定的Nr的值
Nr Nb = 4 Nb = 6 Nb = 8
Nk = 4 10 12 14
Nk = 6 12 12 14
Nk = 8 14 14 14
3.2.1圈變換
加密演算法的圈變換由4個不同的變換組成,定義成:
Round(State,RoundKey)
{
ByteSub(State);
ShiftRow(State);
MixColumn(State);
AddRoundKey(State,RoundKey); (EXORing a Round Key to the State)
}
加密演算法的最後一圈變換與上面的略有不同,定義如下:
FinalRound(State,RoundKey)
{
ByteSub(State);
ShiftRow(State);
AddRoundKey(State,RoundKey);
}
ByteSub變換
ByteSub變換是作用在狀態中每個位元組上的一種非線形位元組變換。這個S盒子是可逆的且由以下兩部分組成:
把位元組的值用它的乘法逆替代,其中『00』的逆就是它自己。
經(1)處理後的位元組值進行如下定義的仿射變換:
y0 1 1 1 1 1 0 0 0 x0 0
y1 0 1 1 1 1 1 0 0 x1 1
y2 0 0 1 1 1 1 1 0 x2 1
y3 0 0 0 1 1 1 1 1 x3 0
y4 = 1 0 0 0 1 1 1 1 x4 + 0
y5 1 1 0 0 0 1 1 1 x5 0
y6 1 1 1 0 0 0 1 1 x6 1
y7 1 1 1 1 0 0 0 1 x7 1
ShiftRow變換
在ShiftRow變換中,狀態的後3行以不同的移位值循環右移,行1移C1位元組,行2移C2位元組,行3移C3位元組。
移位值C1,C2和C3與加密塊長Nb有關,具體列在表2-5中:
表3-3 不同塊長的移位值
Nb C1 C2 C3
4 1 2 3
MixColumn變換
在MixColumn變換中,把狀態中的每一列看作GF(28)上的多項式與一固定多項式c(x)相乘然後模多項式x4+1,其中c(x)為:
c(x) =『03』x3 + 『01』x2 + 『01』x + 『02』
圈密鑰加法
在這個操作中,圈密鑰被簡單地使用異或操作按位應用到狀態中。圈密鑰通過密鑰編製得到,圈密鑰長等於數據塊長Nb。
在這個表示法中,「函數」(Round, ByteSub, ShiftRow,...) 對那些被提供指針 (State, RoundKey) 的數組進行操作。ByteSub 變換是非線性位元組交換,各自作用於每個 State 位元組上。在 ShiftRow 中,State 的行按不同的偏移量循環移位。在 MixColumn 中,將 State 的列視為 GF(28) 多項式,然後乘以固定多項式 c( x ) 並模除 x4 + 1,其中 c( x ) = '03' x3 + '01' x2+ '01' x + '02'。這個多項式與 x4 + 1 互質,因此是可逆的。
輪回密鑰通過密鑰計劃方式從密碼密鑰 (Cipher Key) 派生而出。它有兩個組件:密鑰擴展 (Key Expansion) 和輪回密鑰選擇 (Round Key Selection)。輪回密鑰的總位數等於塊長度乘以輪回次數加 1(例如,塊長度等於 128 位,10 次輪回,那麼就需要 1408 個輪回密鑰位)。
密碼密鑰擴充成擴展密鑰 (Expanded Key)。輪回密鑰是通過以下方法從這個擴展密鑰中派生的:第一個輪回密鑰由前 Nb(Nb = 塊長度)個字組成,第二個由接著的 Nb 個字組成,以此類推。
加密演算法由以下部分組成:初始輪回密鑰加法、Nr-1 個輪回和最後一個輪回。在偽 C 代碼中:
Rijndael(State,CipherKey)
{
KeyExpansion(CipherKey,ExpandedKey);
AddRoundKey(State,ExpandedKey);
For( i=1 ; i<Nr ; i++ ) Round(State,ExpandedKey + Nb*i);
FinalRound(State,ExpandedKey + Nb*Nr).
}
如果已經預先執行了密鑰擴展,則可以根據擴展密鑰指定加密演算法。
Rijndael(State,ExpandedKey)
{
AddRoundKey(State,ExpandedKey);
For( i=1 ; i<Nr ; i++ ) Round(State,ExpandedKey + Nb*i);
FinalRound(State,ExpandedKey + Nb*Nr);
}
由於 Rijndael 是可逆的,解密過程只是顛倒上述的步驟。
最後,開發者將仔細考慮如何集成這種安全性進展,使之成為繼 Rijndael 之後又一個得到廣泛使用的加密演算法。AES 將很快應一般商業團體的要求取代 DES 成為標准,而該領域的發展進步無疑將追隨其後。
3.IDEA加密演算法 (1) 演算法簡介 IDEA演算法是International Data Encryption Algorithmic 的縮寫,意為國際數據加密演算法。是由中國學者朱學嘉博士和著名密碼學家James Massey 於1990年聯合提出的,當時被叫作PES(Proposed Encryption Standard)演算法,後為了加強抵抗差分密碼分,經修改於1992年最後完成,並命名為IDEA演算法。 (2) 演算法描述 這個部分參見論文上的圖 (3) 演算法的安全性分析 安全性:IDEA的密鑰長度是128位,比DES長了2倍多。所以如果用窮舉強行攻擊的話, 么,為了獲得密鑰需要 次搜索,如果可以設計一種每秒能搜索十億把密鑰的晶元,並且 採用十億個晶元來並行處理的話,也要用上 年。而對於其他攻擊方式來說,由於此演算法 比較的新,在設計時已經考慮到了如差分攻擊等密碼分析的威脅,所以還未有關於有誰 發現了能比較成功的攻擊IDEA方法的結果。從這點來看,IDEA還是很安全的。
4.總結
幾種演算法的性能對比
演算法 密鑰長度 分組長度 循環次數
DES 56 64 16
三重DES 112、168 64 48
AES 128、192、256 128 10、12、14
IDEA 128 64 8
速度:在200MHz的奔騰機上的對比。
C++ DJGP(++pgcc101)
AES 30.2Mbps 68.275Mbps
DES(RSAREF) 10.6Mbps 16.7Mbps
3DES 4.4Mbps 7.3Mbps
Celeron 1GHz的機器上AES的速度,加密內存中的數據
128bits密鑰:
C/C++ (Mbps) 匯編(Mbps)
Linux 2.4.7 93 170
Windows2K 107 154
256bits密鑰:
C/C++ (Mbps) 匯編(Mbps)
Linux 2.4.7 76 148
Windows2K 92 135
安全性
1990年以來,特製的"DES Cracker"的機器可在幾個小時內找出一個DES密鑰。換句話說,通過測試所有可能的密鑰值,此硬體可以確定用於加密信息的是哪個密鑰。假設一台一秒內可找出DES密鑰的機器(如,每秒試255個密鑰),如果用它來找出128-bit AES的密鑰,大約需要149萬億年。
四、對稱加密應用 在保密通信中的應用。(保密電話) 附加內容
安全哈希演算法(SHA)
由NIST開發出來的。
此演算法以最大長度不超過264位的消息為輸入,生成160位的消息摘要輸出。主要步驟:
1. 附加填充位
2. 附加長度
3. 初始化MD緩沖區,為160位的數據
A=67452301
B=EFCDAB89
C=89BADCFE
D=10325476
E=C3D2E1F0
4. 處理512位消息塊,將緩沖虛數據和消息塊共同計算出下一個輸出
5. 輸出160位摘要
此外還有其他哈希演算法,如MD5(128位摘要),RIPEMD-160(160位摘要)等。
『捌』 如何用C++實現RSA演算法
RSA演算法介紹及java實現,其實java和c++差不多,參考一下吧
<一>基礎
RSA演算法非常簡單,概述如下:
找兩素數p和q
取n=p*q
取t=(p-1)*(q-1)
取任何一個數e,要求滿足e<t並且e與t互素(就是最大公因數為1)
取d*e%t==1
這樣最終得到三個數: n d e
設消息為數M (M <n)
設c=(M**d)%n就得到了加密後的消息c
設m=(c**e)%n則 m == M,從而完成對c的解密。
註:**表示次方,上面兩式中的d和e可以互換。
在對稱加密中:
n d兩個數構成公鑰,可以告訴別人;
n e兩個數構成私鑰,e自己保留,不讓任何人知道。
給別人發送的信息使用e加密,只要別人能用d解開就證明信息是由你發送的,構成了簽名機制。
別人給你發送信息時使用d加密,這樣只有擁有e的你能夠對其解密。
rsa的安全性在於對於一個大數n,沒有有效的方法能夠將其分解
從而在已知n d的情況下無法獲得e;同樣在已知n e的情況下無法
求得d。
<二>實踐
接下來我們來一個實踐,看看實際的操作:
找兩個素數:
p=47
q=59
這樣
n=p*q=2773
t=(p-1)*(q-1)=2668
取e=63,滿足e<t並且e和t互素
用perl簡單窮舉可以獲得滿主 e*d%t ==1的數d:
C:\Temp>perl -e "foreach $i (1..9999){ print($i),last if $i*63%2668==1 }"
847
即d=847
最終我們獲得關鍵的
n=2773
d=847
e=63
取消息M=244我們看看
加密:
c=M**d%n = 244**847%2773
用perl的大數計算來算一下:
C:\Temp>perl -Mbigint -e "print 244**847%2773"
465
即用d對M加密後獲得加密信息c=465
解密:
我們可以用e來對加密後的c進行解密,還原M:
m=c**e%n=465**63%2773 :
C:\Temp>perl -Mbigint -e "print 465**63%2773"
244
即用e對c解密後獲得m=244 , 該值和原始信息M相等。
<三>字元串加密
把上面的過程集成一下我們就能實現一個對字元串加密解密的示例了。
每次取字元串中的一個字元的ascii值作為M進行計算,其輸出為加密後16進制
的數的字元串形式,按3位元組表示,如01F
代碼如下:
#!/usr/bin/perl -w
#RSA 計算過程學習程序編寫的測試程序
#watercloud 2003-8-12
#
use strict;
use Math::BigInt;
my %RSA_CORE = (n=>2773,e=>63,d=>847); #p=47,q=59
my $N=new Math::BigInt($RSA_CORE{n});
my $E=new Math::BigInt($RSA_CORE{e});
my $D=new Math::BigInt($RSA_CORE{d});
print "N=$N D=$D E=$E\n";
sub RSA_ENCRYPT
{
my $r_mess = shift @_;
my ($c,$i,$M,$C,$cmess);
for($i=0;$i < length($$r_mess);$i++)
{
$c=ord(substr($$r_mess,$i,1));
$M=Math::BigInt->new($c);
$C=$M->(); $C->bmodpow($D,$N);
$c=sprintf "%03X",$C;
$cmess.=$c;
}
return \$cmess;
}
sub RSA_DECRYPT
{
my $r_mess = shift @_;
my ($c,$i,$M,$C,$dmess);
for($i=0;$i < length($$r_mess);$i+=3)
{
$c=substr($$r_mess,$i,3);
$c=hex($c);
$M=Math::BigInt->new($c);
$C=$M->(); $C->bmodpow($E,$N);
$c=chr($C);
$dmess.=$c;
}
return \$dmess;
}
my $mess="RSA 娃哈哈哈~~~";
$mess=$ARGV[0] if @ARGV >= 1;
print "原始串:",$mess,"\n";
my $r_cmess = RSA_ENCRYPT(\$mess);
print "加密串:",$$r_cmess,"\n";
my $r_dmess = RSA_DECRYPT($r_cmess);
print "解密串:",$$r_dmess,"\n";
#EOF
測試一下:
C:\Temp>perl rsa-test.pl
N=2773 D=847 E=63
原始串:RSA 娃哈哈哈~~~
加密串:
解密串:RSA 娃哈哈哈~~~
C:\Temp>perl rsa-test.pl 安全焦點(xfocus)
N=2773 D=847 E=63
原始串:安全焦點(xfocus)
加密串:
解密串:安全焦點(xfocus)
<四>提高
前面已經提到,rsa的安全來源於n足夠大,我們測試中使用的n是非常小的,根本不能保障安全性,
我們可以通過RSAKit、RSATool之類的工具獲得足夠大的N 及D E。
通過工具,我們獲得1024位的N及D E來測試一下:
n=EC3A85F5005D
4C2013433B383B
A50E114705D7E2
BC511951
d=0x10001
e=DD28C523C2995
47B77324E66AFF2
789BD782A592D2B
1965
設原始信息
M=
完成這么大數字的計算依賴於大數運算庫,用perl來運算非常簡單:
A) 用d對M進行加密如下:
c=M**d%n :
C:\Temp>perl -Mbigint -e " $x=Math::BigInt->bmodpow(0x11111111111122222222222233
333333333, 0x10001,
D55EDBC4F0
6E37108DD6
);print $x->as_hex"
b73d2576bd
47715caa6b
d59ea89b91
f1834580c3f6d90898
即用d對M加密後信息為:
c=b73d2576bd
47715caa6b
d59ea89b91
f1834580c3f6d90898
B) 用e對c進行解密如下:
m=c**e%n :
C:\Temp>perl -Mbigint -e " $x=Math::BigInt->bmodpow(0x17b287be418c69ecd7c39227ab
5aa1d99ef3
0cb4764414
, 0xE760A
3C29954C5D
7324E66AFF
2789BD782A
592D2B1965, CD15F90
4F017F9CCF
DD60438941
);print $x->as_hex"
(我的P4 1.6G的機器上計算了約5秒鍾)
得到用e解密後的m= == M
C) RSA通常的實現
RSA簡潔幽雅,但計算速度比較慢,通常加密中並不是直接使用RSA 來對所有的信息進行加密,
最常見的情況是隨機產生一個對稱加密的密鑰,然後使用對稱加密演算法對信息加密,之後用
RSA對剛才的加密密鑰進行加密。
最後需要說明的是,當前小於1024位的N已經被證明是不安全的
自己使用中不要使用小於1024位的RSA,最好使用2048位的。
----------------------------------------------------------
一個簡單的RSA演算法實現JAVA源代碼:
filename:RSA.java
/*
* Created on Mar 3, 2005
*
* TODO To change the template for this generated file go to
* Window - Preferences - Java - Code Style - Code Templates
*/
import java.math.BigInteger;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.FileWriter;
import java.io.FileReader;
import java.io.BufferedReader;
import java.util.StringTokenizer;
/**
* @author Steve
*
* TODO To change the template for this generated type comment go to
* Window - Preferences - Java - Code Style - Code Templates
*/
public class RSA {
/**
* BigInteger.ZERO
*/
private static final BigInteger ZERO = BigInteger.ZERO;
/**
* BigInteger.ONE
*/
private static final BigInteger ONE = BigInteger.ONE;
/**
* Pseudo BigInteger.TWO
*/
private static final BigInteger TWO = new BigInteger("2");
private BigInteger myKey;
private BigInteger myMod;
private int blockSize;
public RSA (BigInteger key, BigInteger n, int b) {
myKey = key;
myMod = n;
blockSize = b;
}
public void encodeFile (String filename) {
byte[] bytes = new byte[blockSize / 8 + 1];
byte[] temp;
int tempLen;
InputStream is = null;
FileWriter writer = null;
try {
is = new FileInputStream(filename);
writer = new FileWriter(filename + ".enc");
}
catch (FileNotFoundException e1){
System.out.println("File not found: " + filename);
}
catch (IOException e1){
System.out.println("File not found: " + filename + ".enc");
}
/**
* Write encoded message to 'filename'.enc
*/
try {
while ((tempLen = is.read(bytes, 1, blockSize / 8)) > 0) {
for (int i = tempLen + 1; i < bytes.length; ++i) {
bytes[i] = 0;
}
writer.write(encodeDecode(new BigInteger(bytes)) + " ");
}
}
catch (IOException e1) {
System.out.println("error writing to file");
}
/**
* Close input stream and file writer
*/
try {
is.close();
writer.close();
}
catch (IOException e1) {
System.out.println("Error closing file.");
}
}
public void decodeFile (String filename) {
FileReader reader = null;
OutputStream os = null;
try {
reader = new FileReader(filename);
os = new FileOutputStream(filename.replaceAll(".enc", ".dec"));
}
catch (FileNotFoundException e1) {
if (reader == null)
System.out.println("File not found: " + filename);
else
System.out.println("File not found: " + filename.replaceAll(".enc", "dec"));
}
BufferedReader br = new BufferedReader(reader);
int offset;
byte[] temp, toFile;
StringTokenizer st = null;
try {
while (br.ready()) {
st = new StringTokenizer(br.readLine());
while (st.hasMoreTokens()){
toFile = encodeDecode(new BigInteger(st.nextToken())).toByteArray();
System.out.println(toFile.length + " x " + (blockSize / 8));
if (toFile[0] == 0 && toFile.length != (blockSize / 8)) {
temp = new byte[blockSize / 8];
offset = temp.length - toFile.length;
for (int i = toFile.length - 1; (i <= 0) && ((i + offset) <= 0); --i) {
temp[i + offset] = toFile[i];
}
toFile = temp;
}
/*if (toFile.length != ((blockSize / 8) + 1)){
temp = new byte[(blockSize / 8) + 1];
System.out.println(toFile.length + " x " + temp.length);
for (int i = 1; i < temp.length; i++) {
temp[i] = toFile[i - 1];
}
toFile = temp;
}
else
System.out.println(toFile.length + " " + ((blockSize / 8) + 1));*/
os.write(toFile);
}
}
}
catch (IOException e1) {
System.out.println("Something went wrong");
}
/**
* close data streams
*/
try {
os.close();
reader.close();
}
catch (IOException e1) {
System.out.println("Error closing file.");
}
}
/**
* Performs <tt>base</tt>^<sup><tt>pow</tt></sup> within the molar
* domain of <tt>mod</tt>.
*
* @param base the base to be raised
* @param pow the power to which the base will be raisded
* @param mod the molar domain over which to perform this operation
* @return <tt>base</tt>^<sup><tt>pow</tt></sup> within the molar
* domain of <tt>mod</tt>.
*/
public BigInteger encodeDecode(BigInteger base) {
BigInteger a = ONE;
BigInteger s = base;
BigInteger n = myKey;
while (!n.equals(ZERO)) {
if(!n.mod(TWO).equals(ZERO))
a = a.multiply(s).mod(myMod);
s = s.pow(2).mod(myMod);
n = n.divide(TWO);
}
return a;
}
}
『玖』 用C語言編寫一個對稱加密演算法,對字元串加密
/*本問題的關鍵是如何交換ASCII的二進制位,下面提供簡短演算法,並附上VC++6.0環境下的運行結果截圖。
*/
#include<stdio.h>
charswapbit(charc){
chari,num=0,ch[8];
for(i=0;i<8;i++){
ch[i]=c&1;
c=(c>>1);
}
for(i=0;i<8;i++){
num=2*num+ch[i];
}
returnnum;
}
intmain(){
charch;
for(ch='A';ch<='Z';ch++){
printf("%c=%X:%X ",ch,ch,0XFF&swapbit(ch));
}
return0;
}