加密演算法使用
在安全領域,利用密鑰加密演算法來對通信的過程進行加密是一種常見的安全手段。利用該手段能夠保障數據安全通信的三個目標:
而常見的密鑰加密演算法類型大體可以分為三類:對稱加密、非對稱加密、單向加密。下面我們來了解下相關的演算法原理及其常見的演算法。
對稱加密演算法採用單密鑰加密,在通信過程中,數據發送方將原始數據分割成固定大小的塊,經過密鑰和加密演算法逐個加密後,發送給接收方;接收方收到加密後的報文後,結合密鑰和解密演算法解密組合後得出原始數據。由於加解密演算法是公開的,因此在這過程中,密鑰的安全傳遞就成為了至關重要的事了。而密鑰通常來說是通過雙方協商,以物理的方式傳遞給對方,或者利用第三方平台傳遞給對方,一旦這過程出現了密鑰泄露,不懷好意的人就能結合相應的演算法攔截解密出其加密傳輸的內容。
對稱加密演算法擁有著演算法公開、計算量小、加密速度和效率高得特定,但是也有著密鑰單一、密鑰管理困難等缺點。
常見的對稱加密演算法有:
DES:分組式加密演算法,以64位為分組對數據加密,加解密使用同一個演算法。
3DES:三重數據加密演算法,對每個數據塊應用三次DES加密演算法。
AES:高級加密標准演算法,是美國聯邦政府採用的一種區塊加密標准,用於替代原先的DES,目前已被廣泛應用。
Blowfish:Blowfish演算法是一個64位分組及可變密鑰長度的對稱密鑰分組密碼演算法,可用來加密64比特長度的字元串。
非對稱加密演算法採用公鑰和私鑰兩種不同的密碼來進行加解密。公鑰和私鑰是成對存在,公鑰是從私鑰中提取產生公開給所有人的,如果使用公鑰對數據進行加密,那麼只有對應的私鑰才能解密,反之亦然。
下圖為簡單非對稱加密演算法的常見流程:
發送方Bob從接收方Alice獲取其對應的公鑰,並結合相應的非對稱演算法將明文加密後發送給Alice;Alice接收到加密的密文後,結合自己的私鑰和非對稱演算法解密得到明文。這種簡單的非對稱加密演算法的應用其安全性比對稱加密演算法來說要高,但是其不足之處在於無法確認公鑰的來源合法性以及數據的完整性。
非對稱加密演算法具有安全性高、演算法強度負復雜的優點,其缺點為加解密耗時長、速度慢,只適合對少量數據進行加密,其常見演算法包括:
RSA :RSA演算法基於一個十分簡單的數論事實:將兩個大素數相乘十分容易,但那時想要對其乘積進行因式分解卻極其困難,因此可以將乘積公開作為加密密鑰,可用於加密,也能用於簽名。
DSA :數字簽名演算法,僅能用於簽名,不能用於加解密。
DSS :數字簽名標准,技能用於簽名,也可以用於加解密。
ELGamal :利用離散對數的原理對數據進行加解密或數據簽名,其速度是最慢的。
單向加密演算法常用於提取數據指紋,驗證數據的完整性。發送者將明文通過單向加密演算法加密生成定長的密文串,然後傳遞給接收方。接收方在收到加密的報文後進行解密,將解密獲取到的明文使用相同的單向加密演算法進行加密,得出加密後的密文串。隨後將之與發送者發送過來的密文串進行對比,若發送前和發送後的密文串相一致,則說明傳輸過程中數據沒有損壞;若不一致,說明傳輸過程中數據丟失了。單向加密演算法只能用於對數據的加密,無法被解密,其特點為定長輸出、雪崩效應。常見的演算法包括:MD5、sha1、sha224等等,其常見用途包括:數字摘要、數字簽名等等。
密鑰交換IKE(Internet Key Exchange)通常是指雙方通過交換密鑰來實現數據加密和解密,常見的密鑰交換方式有下面兩種:
1、公鑰加密,將公鑰加密後通過網路傳輸到對方進行解密,這種方式缺點在於具有很大的可能性被攔截破解,因此不常用;
2、Diffie-Hellman,DH演算法是一種密鑰交換演算法,其既不用於加密,也不產生數字簽名。DH演算法的巧妙在於需要安全通信的雙方可以用這個方法確定對稱密鑰。然後可以用這個密鑰進行加密和解密。但是注意,這個密鑰交換協議/演算法只能用於密鑰的交換,而不能進行消息的加密和解密。雙方確定要用的密鑰後,要使用其他對稱密鑰操作加密演算法實際加密和解密消息。DH演算法通過雙方共有的參數、私有參數和演算法信息來進行加密,然後雙方將計算後的結果進行交換,交換完成後再和屬於自己私有的參數進行特殊演算法,經過雙方計算後的結果是相同的,此結果即為密鑰。
如:
在整個過程中,第三方人員只能獲取p、g兩個值,AB雙方交換的是計算後的結果,因此這種方式是很安全的。
公鑰基礎設施是一個包括硬體、軟體、人員、策略和規程的集合,用於實現基於公鑰密碼機制的密鑰和證書的生成、管理、存儲、分發和撤銷的功能,其組成包括:簽證機構CA、注冊機構RA、證書吊銷列表CRL和證書存取庫CB。
PKI採用證書管理公鑰,通過第三方可信任CA中心,把用戶的公鑰和其他用戶信息組生成證書,用於驗證用戶的身份。
公鑰證書是以數字簽名的方式聲明,它將公鑰的值綁定到持有對應私鑰的個人、設備或服務身份。公鑰證書的生成遵循X.509協議的規定,其內容包括:證書名稱、證書版本、序列號、演算法標識、頒發者、有效期、有效起始日期、有效終止日期、公鑰 、證書簽名等等的內容。
CA證書認證的流程如下圖,Bob為了向Alice證明自己是Bob和某個公鑰是自己的,她便向一個Bob和Alice都信任的CA機構申請證書,Bob先自己生成了一對密鑰對(私鑰和公鑰),把自己的私鑰保存在自己電腦上,然後把公鑰給CA申請證書,CA接受申請於是給Bob頒發了一個數字證書,證書中包含了Bob的那個公鑰以及其它身份信息,當然,CA會計算這些信息的消息摘要並用自己的私鑰加密消息摘要(數字簽名)一並附在Bob的證書上,以此來證明這個證書就是CA自己頒發的。Alice得到Bob的證書後用CA的證書(自簽署的)中的公鑰來解密消息摘要,隨後將摘要和Bob的公鑰發送到CA伺服器上進行核對。CA在接收到Alice的核對請求後,會根據Alice提供的信息核對Bob的證書是否合法,如果確認合法則回復Alice證書合法。Alice收到CA的確認回復後,再去使用從證書中獲取的Bob的公鑰加密郵件然後發送給Bob,Bob接收後再以自己的私鑰進行解密。
⑵ 對稱加密演算法的原理應用
對稱加密演算法的優點在於加解密的高速度和使用長密鑰時的難破解性。假設兩個用戶需要使用對稱加密方法加密然後交換數據,則用戶最少需要2個密鑰並交換使用,如果企業內用戶有n個,則整個企業共需要n×(n-1) 個密鑰,密鑰的生成和分發將成為企業信息部門的惡夢。對稱加密演算法的安全性取決於加密密鑰的保存情況,但要求企業中每一個持有密鑰的人都保守秘密是不可能的,他們通常會有意無意的把密鑰泄漏出去——如果一個用戶使用的密鑰被入侵者所獲得,入侵者便可以讀取該用戶密鑰加密的所有文檔,如果整個企業共用一個加密密鑰,那整個企業文檔的保密性便無從談起。DESCryptoServiceProvider
RC2CryptoServiceProvider
RijndaelManaged
//例加密文本文件(RijndaelManaged )
byte[] key = { 24, 55, 102,24, 98, 26, 67, 29, 84, 19, 37, 118, 104, 85, 121, 27, 93, 86, 24, 55, 102, 24,98, 26, 67, 29, 9, 2, 49, 69, 73, 92 };
byte[] IV ={ 22, 56, 82, 77, 84, 31, 74, 24,55, 102, 24, 98, 26, 67, 29, 99 };
RijndaelManaged myRijndael = new RijndaelManaged();
FileStream fsOut = File.Open(strOutName, FileMode.Create,FileAccess.Write);//strOutName文件名及路徑 FileStream fsIn = File.Open(strPath, FileMode.Open,FileAccess.Read);
CryptoStream csDecrypt=new CryptoStream(fsOut,myRijndael.CreateEncryptor(key, IV),CryptoStreamMode.Write);//讀加密文本
BinaryReader br = new BinaryReader(fsIn);
csDecrypt.Write(br.ReadBytes((int)fsIn.Length),0, (int)fsIn.Length);
csDecrypt.FlushFinalBlock();
csDecrypt.Close();
fsIn.Close();
fsOut.Close();
//解密文件
byte[] key = { 24, 55, 102, 24, 98, 26, 67, 29, 84, 19, 37, 118,104, 85, 121, 27, 93, 86, 24, 55, 102, 24, 98, 26, 67, 29, 9, 2, 49, 69, 73, 92};
byte[] IV ={ 22, 56, 82, 77, 84, 31, 74, 24, 55, 102, 24, 98, 26,67, 29, 99 };
RijndaelManaged myRijndael = new RijndaelManaged();
FileStream fsOut = File.Open(strPath, FileMode.Open, FileAccess.Read);
CryptoStream csDecrypt = new CryptoStream(fsOut, myRijndael.CreateDecryptor(key,IV), CryptoStreamMode.Read);
StreamReader sr = new StreamReader(csDecrypt);//把文件讀出來
StreamWriter sw = new StreamWriter(strInName);//解密後文件寫入一個新的文件
sw.Write(sr.ReadToEnd());
sw.Flush();
sw.Close();
sr.Close();f
sOut.Close();
用圖片加密(RC2CryptoServiceProvider )
FileStreamfsPic = new FileStream(pictureBox1.ImageLocation,FileMode.Open, FileAccess.Read);
//加密文件流(textBox1.Text是文件名及路徑)
FileStream fsText = new FileStream(textBox1.Text, FileMode.Open,FileAccess.Read);
byte[] bykey = new byte[16]; //初始化
Key IVbyte[] byIv = new byte[8];
fsPic.Read(bykey, 0, 16);
fsPic.Read(byIv, 0, 8);
RC2CryptoServiceProvider desc = newRC2CryptoServiceProvider();//desc進行加密
BinaryReader br = new BinaryReader(fsText);//從要加密的文件中讀出文件內容
FileStream fsOut = File.Open(strLinPath,FileMode.Create, FileAccess.Write); // strLinPath臨時加密文件路徑CryptoStream cs = new CryptoStream(fsOut, desc.CreateEncryptor(bykey,byIv), CryptoStreamMode.Write);//寫入臨時加密文件
cs.Write(br.ReadBytes((int)fsText.Length),0, (int)fsText.Length);//寫入加密流
cs.FlushFinalBlock();
cs.Flush();
cs.Close();
fsPic.Close();
fsText.Close();
fsOut.Close();
用圖片解密
FileStream fsPic = new FileStream(pictureBox1.ImageLocation, FileMode.Open, FileAccess.Read); //圖片流FileStream fsOut = File.Open(textBox1.Text,FileMode.Open, FileAccess.Read);//解密文件流
byte[] bykey = new byte[16]; //初始化
Key IVbyte[] byIv = new byte[8];
fsPic.Read(bykey, 0, 16);
fsPic.Read(byIv, 0, 8);
string strPath = textBox1.Text;//加密文件的路徑
int intLent = strPath.LastIndexOf("\")+ 1;
int intLong = strPath.Length;
string strName = strPath.Substring(intLent, intLong - intLent);//要加密的文件名稱
string strLinPath = "C:\"+ strName;//臨時解密文件路徑
FileStream fs = new FileStream(strLinPath, FileMode.Create,FileAccess.Write);
RC2CryptoServiceProvider desc = newRC2CryptoServiceProvider();//desc進行解密
CryptoStream csDecrypt = new CryptoStream(fsOut, desc.CreateDecryptor(bykey,byIv), CryptoStreamMode.Read);
//讀出加密文件
BinaryReader sr = new BinaryReader(csDecrypt);//從要加密流中讀出文件內容
BinaryWriter sw = new BinaryWriter(fs);//寫入解密流
sw.Write(sr.ReadBytes(Convert.ToInt32(fsOut.Length)));
//sw.Flush();
sw.Close();
sr.Close();
fs.Close();
fsOut.Close();
fsPic.Close();
csDecrypt.Flush();
File.Delete(textBox1.Text.TrimEnd());//刪除原文件
File.Copy(strLinPath, textBox1.Text);//復制加密文件
File.Delete(strLinPath);//刪除臨時文件
⑶ 介紹iOS中MD5加密演算法的使用
前言
軟體開發過程中,對數據進行加密是保證數據安全的重要手段,常見的加密有Base64加密和MD5加密。Base64加密是可逆的,MD5加密目前來說一般是不可逆的。
MD5生成的是固定的128bit,即128個0和1的二進制位,而在實際應用開發中,通常是以16進制輸出的,所以正好就是32位的16進制,說白了也就是32個16進制的數字。
MD5主要特點是 不可逆,相同數據的MD5值肯定一樣,不同數據的MD5值不一樣(也不是絕對的,但基本是不能一樣的)。
MD5演算法還具有以下性質:
1、壓縮性:任意長度的數據,算出的MD5值長度都是固定的。
2、容易計算:從原數據計算出MD5值很容易。
3、抗修改性:對原數據進行任何改動,哪怕只修改1個位元組,所得到的MD5值都有很大區別。
4、弱抗碰撞:已知原數據和其MD5值,想找到一個具有相同MD5值的數據(即偽造數據)是非常困難的。
5、強抗碰撞:想找到兩個不同的數據,使它們具有相同的MD5值,是非常困難的。
6、MD5加密是不可解密的,但是網上有一些解析MD5的,那個相當於一個大型的資料庫,通過匹配MD5去找到原密碼。所以,只要在要加密的字元串前面加上一些字母數字元號或者多次MD5加密,這樣出來的結果一般是解析不出來的。
MD5的應用:
由於MD5加密演算法具有較好的安全性,而且免費,因此該加密演算法被廣泛使用
大多數的'登錄功能向後台提交密碼時都會使用到這種演算法
注意點:
(1)一定要和後台開發人員約定好,MD5加密的位數是16位還是32位(大多數都是32位的),16位的可以通過32位的轉換得到。
(2)MD5加密區分 大小寫,使用時要和後台約定好。
MD5解密:
解密網站:http://www.cmd5.com/
為了讓MD5碼更加安全 涌現了很多其他方法 如加鹽。 鹽要足夠長足夠亂 得到的MD5碼就很難查到。
終端代碼:$ echo -n abc|openssl md5 給字元串abc加密、
蘋果包裝了MD5加密的方法,使用起來十分的方便。
#import@interface MD5Encrypt : NSObject// MD5加密/**由於MD5加密是不可逆的,多用來進行驗證*/// 32位小寫+(NSString *)MD5ForLower32Bate:(NSString *)str;// 32位大寫+(NSString *)MD5ForUpper32Bate:(NSString *)str;// 16為大寫+(NSString *)MD5ForUpper16Bate:(NSString *)str;// 16位小寫+(NSString *)MD5ForLower16Bate:(NSString *)str;@end
#import "MD5Encrypt.h"#import@implementation MD5Encrypt#pragma mark - 32位 小寫+(NSString *)MD5ForLower32Bate:(NSString *)str{ //要進行UTF8的轉碼 const char* input = [str UTF8String]; unsigned char result[CC_MD5_DIGEST_LENGTH]; CC_MD5(input, (CC_LONG)strlen(input), result); NSMutableString *digest = [NSMutableString stringWithCapacity:CC_MD5_DIGEST_LENGTH * 2]; for (NSInteger i = 0; i < CC_MD5_DIGEST_LENGTH; i++) { [digest appendFormat:@"%02x", result[i]]; } return digest;}#pragma mark - 32位 大寫+(NSString *)MD5ForUpper32Bate:(NSString *)str{ //要進行UTF8的轉碼 const char* input = [str UTF8String]; unsigned char result[CC_MD5_DIGEST_LENGTH]; CC_MD5(input, (CC_LONG)strlen(input), result); NSMutableString *digest = [NSMutableString stringWithCapacity:CC_MD5_DIGEST_LENGTH * 2]; for (NSInteger i = 0; i < CC_MD5_DIGEST_LENGTH; i++) { [digest appendFormat:@"%02X", result[i]]; } return digest;}#pragma mark - 16位 大寫+(NSString *)MD5ForUpper16Bate:(NSString *)str{ NSString *md5Str = [self MD5ForUpper32Bate:str]; NSString *string; for (int i=0; i<24; i++) { string=[md5Str substringWithRange:NSMakeRange(8, 16)]; } return string;}#pragma mark - 16位 小寫+(NSString *)MD5ForLower16Bate:(NSString *)str{ NSString *md5Str = [self MD5ForLower32Bate:str]; NSString *string; for (int i=0; i<24; i++) { string=[md5Str substringWithRange:NSMakeRange(8, 16)]; } return string;}@end
⑷ 對稱加密演算法以及使用方法
加密的原因:保證數據安全
加密必備要素: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
⑸ 十大常見密碼加密方式
一、密鑰散列
採用MD5或者SHA1等散列演算法,對明文進行加密。嚴格來說,MD5不算一種加密演算法,而是一種摘要演算法。無論多長的輸入,MD5都會輸出一個128位(16位元組)的散列值。而SHA1也是流行的消息摘要演算法,它可以生成一個被稱為消息摘要的160位(20位元組)散列值。MD5相對SHA1來說,安全性較低,但是速度快;SHA1和MD5相比安全性高,但是速度慢。
二、對稱加密
採用單鑰密碼系統的加密方法,同一個密鑰可以同時用作信息的加密和解密,這種加密方法稱為對稱加密。對稱加密演算法中常用的演算法有:DES、3DES、TDEA、Blowfish、RC2、RC4、RC5、IDEA、SKIPJACK等。
三、非對稱加密
非對稱加密演算法是一種密鑰的保密方法,它需要兩個密鑰來進行加密和解密,這兩個密鑰是公開密鑰和私有密鑰。公鑰與私鑰是一對,如果用公鑰對數據進行加密,只有用對應的私鑰才能解密。非對稱加密演算法有:RSA、Elgamal、背包演算法、Rabin、D-H、ECC(橢圓曲線加密演算法)。
四、數字簽名
數字簽名(又稱公鑰數字簽名)是只有信息的發送者才能產生的別人無法偽造的一段數字串,這段數字串同時也是對信息的發送者發送信息真實性的一個有效證明。它是一種類似寫在紙上的普通的物理簽名,但是在使用了公鑰加密領域的技術來實現的,用於鑒別數字信息的方法。
五、直接明文保存
早期很多這樣的做法,比如用戶設置的密碼是「123」,直接就將「123」保存到資料庫中,這種是最簡單的保存方式,也是最不安全的方式。但實際上不少互聯網公司,都可能採取的是這種方式。
六、使用MD5、SHA1等單向HASH演算法保護密碼
使用這些演算法後,無法通過計算還原出原始密碼,而且實現比較簡單,因此很多互聯網公司都採用這種方式保存用戶密碼,曾經這種方式也是比較安全的方式,但隨著彩虹表技術的興起,可以建立彩虹表進行查表破解,目前這種方式已經很不安全了。
七、特殊的單向HASH演算法
由於單向HASH演算法在保護密碼方面不再安全,於是有些公司在單向HASH演算法基礎上進行了加鹽、多次HASH等擴展,這些方式可以在一定程度上增加破解難度,對於加了「固定鹽」的HASH演算法,需要保護「鹽」不能泄露,這就會遇到「保護對稱密鑰」一樣的問題,一旦「鹽」泄露,根據「鹽」重新建立彩虹表可以進行破解,對於多次HASH,也只是增加了破解的時間,並沒有本質上的提升。
八、PBKDF2
該演算法原理大致相當於在HASH演算法基礎上增加隨機鹽,並進行多次HASH運算,隨機鹽使得彩虹表的建表難度大幅增加,而多次HASH也使得建表和破解的難度都大幅增加。
九、BCrypt
BCrypt 在1999年就產生了,並且在對抗 GPU/ASIC 方面要優於 PBKDF2,但是我還是不建議你在新系統中使用它,因為它在離線破解的威脅模型分析中表現並不突出。
十、SCrypt
SCrypt 在如今是一個更好的選擇:比 BCrypt設計得更好(尤其是關於內存方面)並且已經在該領域工作了 10 年。另一方面,它也被用於許多加密貨幣,並且我們有一些硬體(包括 FPGA 和 ASIC)能實現它。 盡管它們專門用於采礦,也可以將其重新用於破解。
⑹ 常見的加密演算法、原理、優缺點、用途
在安全領域,利用密鑰加密演算法來對通信的過程進行加密是一種常見的安全手段。利用該手段能夠保障數據安全通信的三個目標:
而常見的密鑰加密演算法類型大體可以分為三類:對稱加密、非對稱加密、單向加密。下面我們來了解下相關的演算法原理及其常見的演算法。
在加密傳輸中最初是採用對稱密鑰方式,也就是加密和解密都用相同的密鑰。
1.對稱加密演算法採用單密鑰加密,在通信過程中,數據發送方將原始數據分割成固定大小的塊,經過密鑰和加密演算法逐個加密後,發送給接收方
2.接收方收到加密後的報文後,結合解密演算法使用相同密鑰解密組合後得出原始數據。
圖示:
非對稱加密演算法採用公鑰和私鑰兩種不同的密碼來進行加解密。公鑰和私鑰是成對存在,公鑰是從私鑰中提取產生公開給所有人的,如果使用公鑰對數據進行加密,那麼只有對應的私鑰(不能公開)才能解密,反之亦然。N 個用戶通信,需要2N個密鑰。
非對稱密鑰加密適合對密鑰或身份信息等敏感信息加密,從而在安全性上滿足用戶的需求。
1.甲使用乙的公鑰並結合相應的非對稱演算法將明文加密後發送給乙,並將密文發送給乙。
2.乙收到密文後,結合自己的私鑰和非對稱演算法解密得到明文,得到最初的明文。
圖示:
單向加密演算法只能用於對數據的加密,無法被解密,其特點為定長輸出、雪崩效應(少量消息位的變化會引起信息摘要的許多位變化)。
單向加密演算法常用於提取數據指紋,驗證數據的完整性、數字摘要、數字簽名等等。
1.發送者將明文通過單向加密演算法加密生成定長的密文串,然後傳遞給接收方。
2.接收方將用於比對驗證的明文使用相同的單向加密演算法進行加密,得出加密後的密文串。
3.將之與發送者發送過來的密文串進行對比,若發送前和發送後的密文串相一致,則說明傳輸過程中數據沒有損壞;若不一致,說明傳輸過程中數據丟失了。
圖示:
MD5、sha1、sha224等等
密鑰交換IKE(Internet Key Exchange)通常是指雙方通過交換密鑰來實現數據加密和解密
常見的密鑰交換方式有下面兩種:
將公鑰加密後通過網路傳輸到對方進行解密,這種方式缺點在於具有很大的可能性被攔截破解,因此不常用
DH演算法是一種密鑰交換演算法,其既不用於加密,也不產生數字簽名。
DH演算法通過雙方共有的參數、私有參數和演算法信息來進行加密,然後雙方將計算後的結果進行交換,交換完成後再和屬於自己私有的參數進行特殊演算法,經過雙方計算後的結果是相同的,此結果即為密鑰。
如:
安全性
在整個過程中,第三方人員只能獲取p、g兩個值,AB雙方交換的是計算後的結果,因此這種方式是很安全的。
答案:使用公鑰證書
公鑰基礎設施是一個包括硬體、軟體、人員、策略和規程的集合
用於實現基於公鑰密碼機制的密鑰和證書的生成、管理、存儲、分發和撤銷的功能
簽證機構CA、注冊機構RA、證書吊銷列表CRL和證書存取庫CB。
公鑰證書是以數字簽名的方式聲明,它將公鑰的值綁定到持有對應私鑰的個人、設備或服務身份。公鑰證書的生成遵循X.509協議的規定,其內容包括:證書名稱、證書版本、序列號、演算法標識、頒發者、有效期、有效起始日期、有效終止日期、公鑰 、證書簽名等等的內容。
1.客戶A准備好要傳送的數字信息(明文)。(准備明文)
2.客戶A對數字信息進行哈希(hash)運算,得到一個信息摘要。(准備摘要)
3.客戶A用CA的私鑰(SK)對信息摘要進行加密得到客戶A的數字簽名,並將其附在數字信息上。(用私鑰對數字信息進行數字簽名)
4.客戶A隨機產生一個加密密鑰(DES密鑰),並用此密鑰對要發送的信息進行加密,形成密文。 (生成密文)
5.客戶A用雙方共有的公鑰(PK)對剛才隨機產生的加密密鑰進行加密,將加密後的DES密鑰連同密文一起傳送給乙。(非對稱加密,用公鑰對DES密鑰進行加密)
6.銀行B收到客戶A傳送過來的密文和加過密的DES密鑰,先用自己的私鑰(SK)對加密的DES密鑰進行解密,得到DES密鑰。(用私鑰對DES密鑰解密)
7.銀行B然後用DES密鑰對收到的密文進行解密,得到明文的數字信息,然後將DES密鑰拋棄(即DES密鑰作廢)。(解密文)
8.銀行B用雙方共有的公鑰(PK)對客戶A的數字簽名進行解密,得到信息摘要。銀行B用相同的hash演算法對收到的明文再進行一次hash運算,得到一個新的信息摘要。(用公鑰解密數字簽名)
9.銀行B將收到的信息摘要和新產生的信息摘要進行比較,如果一致,說明收到的信息沒有被修改過。(對比信息摘要和信息)
答案是沒法保證CA的公鑰沒有被篡改。通常操作系統和瀏覽器會預制一些CA證書在本地。所以發送方應該去那些通過認證的CA處申請數字證書。這樣是有保障的。
但是如果系統中被插入了惡意的CA證書,依然可以通過假冒的數字證書發送假冒的發送方公鑰來驗證假冒的正文信息。所以安全的前提是系統中不能被人插入非法的CA證書。
END
⑺ 幾種加密演算法在java中的應用
簡單的Java加密演算法有:
第一種. BASE
Base是網路上最常見的用於傳輸Bit位元組代碼的編碼方式之一,大家可以查看RFC~RFC,上面有MIME的詳細規范。Base編碼可用於在HTTP環境下傳遞較長的標識信息。例如,在Java Persistence系統Hibernate中,就採用了Base來將一個較長的唯一標識符(一般為-bit的UUID)編碼為一個字元串,用作HTTP表單和HTTP GET URL中的參數。在其他應用程序中,也常常需要把二進制數據編碼為適合放在URL(包括隱藏表單域)中的形式。此時,採用Base編碼具有不可讀性,即所編碼的數據不會被人用肉眼所直接看到。
第二種. MD
MD即Message-Digest Algorithm (信息-摘要演算法),用於確保信息傳輸完整一致。是計算機廣泛使用的雜湊演算法之一(又譯摘要演算法、哈希演算法),主流編程語言普遍已有MD實現。將數據(如漢字)運算為另一固定長度值,是雜湊演算法的基礎原理,MD的前身有MD、MD和MD。廣泛用於加密和解密技術,常用於文件校驗。校驗?不管文件多大,經過MD後都能生成唯一的MD值。好比現在的ISO校驗,都是MD校驗。怎麼用?當然是把ISO經過MD後產生MD的值。一般下載linux-ISO的朋友都見過下載鏈接旁邊放著MD的串。就是用來驗證文件是否一致的。
MD演算法具有以下特點:
壓縮性:任意長度的數據,算出的MD值長度都是固定的。
容易計算:從原數據計算出MD值很容易。
抗修改性:對原數據進行任何改動,哪怕只修改個位元組,所得到的MD值都有很大區別。
弱抗碰撞:已知原數據和其MD值,想找到一個具有相同MD值的數據(即偽造數據)是非常困難的。
強抗碰撞:想找到兩個不同的數據,使它們具有相同的MD值,是非常困難的。
MD的作用是讓大容量信息在用數字簽名軟體簽署私人密鑰前被」壓縮」成一種保密的格式(就是把一個任意長度的位元組串變換成一定長的十六進制數字串)。除了MD以外,其中比較有名的還有sha-、RIPEMD以及Haval等。
第三種.SHA
安全哈希演算法(Secure Hash Algorithm)主要適用於數字簽名標准(Digital Signature Standard DSS)裡面定義的數字簽名演算法(Digital Signature Algorithm DSA)。對於長度小於^位的消息,SHA會產生一個位的消息摘要。該演算法經過加密專家多年來的發展和改進已日益完善,並被廣泛使用。該演算法的思想是接收一段明文,然後以一種不可逆的方式將它轉換成一段(通常更小)密文,也可以簡單的理解為取一串輸入碼(稱為預映射或信息),並把它們轉化為長度較短、位數固定的輸出序列即散列值(也稱為信息摘要或信息認證代碼)的過程。散列函數值可以說是對明文的一種「指紋」或是「摘要」所以對散列值的數字簽名就可以視為對此明文的數字簽名。
SHA-與MD的比較
因為二者均由MD導出,SHA-和MD彼此很相似。相應的,他們的強度和其他特性也是相似,但還有以下幾點不同:
對強行攻擊的安全性:最顯著和最重要的區別是SHA-摘要比MD摘要長 位。使用強行技術,產生任何一個報文使其摘要等於給定報摘要的難度對MD是^數量級的操作,而對SHA-則是^數量級的操作。這樣,SHA-對強行攻擊有更大的強度。
對密碼分析的安全性:由於MD的設計,易受密碼分析的攻擊,SHA-顯得不易受這樣的攻擊。
速度:在相同的硬體上,SHA-的運行速度比MD慢。
第四種.HMAC
HMAC(Hash Message Authentication Code,散列消息鑒別碼,基於密鑰的Hash演算法的認證協議。消息鑒別碼實現鑒別的原理是,用公開函數和密鑰產生一個固定長度的值作為認證標識,用這個標識鑒別消息的完整性。使用一個密鑰生成一個固定大小的小數據塊,即MAC,並將其加入到消息中,然後傳輸。接收方利用與發送方共享的密鑰進行鑒別認證等。