由于計(jì)算機(jī)軟件的非法復(fù)制威创,通信的泄密落午、數(shù)據(jù)安全受到威脅,解密及盜版問(wèn)題日益嚴(yán)重肚豺,甚至引發(fā)國(guó)際爭(zhēng)端板甘,所以在信息安全技術(shù)中,加密技術(shù)占有不可替代的位置详炬,因此對(duì)信息加密技術(shù)和加密手段的研究與開(kāi)發(fā)盐类,受到各國(guó)計(jì)算機(jī)界的重視,發(fā)展日新月異∏好眨現(xiàn)在就給大家介紹幾種常用的加密算法在跳。
1.密碼中常用的術(shù)語(yǔ)
2.密碼分類(lèi)
3.OSI和TCP/IP安全體系
4.Java安全組成
5.Base64加密算法
6.消息摘要算法
6.1.消息摘要算法-MD家族
6.2.消息摘要算法-SHA家族
6.3.消息摘要算法-MAC家族
1.加密中常用的術(shù)語(yǔ):
<b>明文</b>:待加密的信息
<b>密文</b>:加密后的明文
<b>加密</b>:明文轉(zhuǎn)密文的過(guò)程
<b>加密算法</b>:明文轉(zhuǎn)密文的轉(zhuǎn)換算法
<b>密鑰</b>:密鑰是一種參數(shù),它是在明文轉(zhuǎn)換為密文或?qū)⒚芪霓D(zhuǎn)換為明文的算法中輸入的參數(shù)隐岛。密鑰分為對(duì)稱(chēng)密鑰與非對(duì)稱(chēng)密鑰猫妙。
<b>加密密鑰</b>:通過(guò)加密算法進(jìn)行加密過(guò)程中用的密鑰
<b>解密</b>:將密文轉(zhuǎn)名文的過(guò)程
<b>解密算法</b>:密文轉(zhuǎn)明文的轉(zhuǎn)換算法
<b>解密密鑰</b>:通過(guò)解密算法進(jìn)行解密過(guò)程中用的密鑰
<b>密碼分析</b>:截獲密文這試圖通過(guò)分析截獲的密文從而推斷出原來(lái)的明文或密鑰的過(guò)程
<b>主動(dòng)攻擊</b>:攻擊者非法入侵密碼系統(tǒng),采用偽造聚凹、修改割坠、刪除等手段向系統(tǒng)注入假消息進(jìn)行欺騙(對(duì)密文有破壞作用)
<b>被動(dòng)攻擊</b>:對(duì)一個(gè)保密系統(tǒng)采取截獲密文并對(duì)其進(jìn)行分析和攻擊(對(duì)密文沒(méi)有破壞作用)
<b>密碼體系</b>:由明文空間,密文空間妒牙,密鑰空間彼哼,加密算法和解密算法五部分組成
<b>密碼協(xié)議</b>:也稱(chēng)安全協(xié)議,指以密碼學(xué)為基礎(chǔ)的消息交換的通信協(xié)議湘今,目的是在網(wǎng)絡(luò)環(huán)境中提供安全的服務(wù)敢朱。
<b>密碼系統(tǒng)</b>:用于加密和解密的系統(tǒng)
<b>柯克霍夫原則</b>:數(shù)據(jù)的安全基于密鑰而不是算法的保密。即系統(tǒng)的安全取決于密鑰摩瞎,對(duì)密鑰保密拴签,對(duì)算法公開(kāi)。-----現(xiàn)在密碼學(xué)設(shè)計(jì)的基本原則
2.密碼分類(lèi)
- 按時(shí)間分:
- 古典密碼:以字符為基本的加密單元
- 現(xiàn)代密碼:以信息塊為基本的加密單元
- 按保密內(nèi)容分:
- 受限制算法:算法的保密基于保持算法的密碼旗们,常用語(yǔ)軍事領(lǐng)域
- 基于密鑰算法:算法的保密基于對(duì)密鑰的保密
- 按密碼體系分:
- 對(duì)稱(chēng)密碼:別名單鑰密碼或私鑰密碼蚓哩;指加密密鑰和解密密鑰相同
- 非對(duì)稱(chēng)密碼:別名雙鑰密碼或公鑰密碼;指加密密鑰和解密密鑰不同上渴,密鑰分為公鑰和私鑰
- 按明文的處理方法:
- 分組密碼:指加密時(shí)將明文分成固定長(zhǎng)度的組岸梨,用同一密鑰和算法對(duì)每一組進(jìn)行加密喜颁,輸出也是固定長(zhǎng)度的密文。多用于網(wǎng)絡(luò)加密盛嘿。
- 流密碼:也稱(chēng)序列密碼洛巢。指加密時(shí)每次加密一位或者一個(gè)字節(jié)明文括袒。
3.OSI和TCP/IP安全體系
4.Java安全組成
Java 安全體系內(nèi)核:它包括:字節(jié)碼驗(yàn)證器次兆、類(lèi)加載器、安全管理器锹锰、訪(fǎng)問(wèn)控制器芥炭、訪(fǎng)問(wèn)權(quán)限管理器和策略描述工具等
Java代碼在Java安全體系內(nèi)核組件中的執(zhí)行過(guò)程
- 字節(jié)碼驗(yàn)證器分析字節(jié)碼的順序
- 字節(jié)碼驗(yàn)證器檢查對(duì)其它類(lèi)的引用
例如,如果一個(gè)類(lèi)要訪(fǎng)問(wèn)另一個(gè)類(lèi)的方法恃慧,字節(jié)碼驗(yàn)證器就要檢查該方法是否為public.字節(jié)碼驗(yàn)證器的典型操作包括:檢查字節(jié)碼的順序是否以0XCAFEBABE開(kāi)始园蝠,是否丟失字節(jié),最后的類(lèi)是否包含子類(lèi)(它們不應(yīng)該包括)痢士,方法的參數(shù)類(lèi)型是什么等彪薛。如果一切正常,接下來(lái)類(lèi)加載器將字節(jié)碼翻譯成java類(lèi)怠蹂,然后由java虛擬機(jī)(JVM)執(zhí)行善延。如果需要加載一個(gè)特別的類(lèi)可以定義不同的策略加以說(shuō)明。通過(guò)委托給安全管理器的方式如果某個(gè)類(lèi)可以訪(fǎng)問(wèn)特別的系統(tǒng)資源城侧,那么類(lèi)加載器和
java標(biāo)準(zhǔn)類(lèi)也可以定義決策權(quán)易遣。
- 安全管理器:是一個(gè)可有開(kāi)發(fā)人員實(shí)現(xiàn)的特殊類(lèi),用于指明一個(gè)類(lèi)是否可以訪(fǎng)問(wèn)指定的資源(例如嫌佑,文件訪(fǎng)問(wèn)或網(wǎng)絡(luò)連接)豆茫。為了做出決策,安全管理器需要分析請(qǐng)求來(lái)源屋摇。如果訪(fǎng)問(wèn)被拒絕揩魂,將會(huì)拋出一個(gè)java.lang.SecurityExceptin異常,否則的話(huà)炮温,將會(huì)以通常的方式處理該調(diào)用肤京。
JCA
- 它提供了Java平臺(tái)上執(zhí)行主要加密服務(wù)的基礎(chǔ)設(shè)施,包括數(shù)字簽名茅特,信息摘要忘分,密碼,信息認(rèn)證碼密鑰生成器和密鑰生成器白修。同時(shí)JCA還保證了數(shù)據(jù)完整性并提供了顯示全部特性的APIs妒峦。
- JCA僅僅是一個(gè)接口,可以有很多該接口的實(shí)現(xiàn)兵睛,它支持很大范圍的標(biāo)準(zhǔn)算法包括RSA肯骇、DSA窥浪、三重DES、SHA、PKCS#5、RC2以及RC4.JCA是可擴(kuò)展的瞎疼,豐富的API可用于構(gòu)建安全的應(yīng)用乔妈,而其它還是算法與實(shí)現(xiàn)相互獨(dú)立的,使用基于提供(可插拔)的體系結(jié)構(gòu)翔曲。
其他體系結(jié)構(gòu)
JCE
這是Sun微系統(tǒng)公司對(duì)數(shù)據(jù)塊加密與解密的擴(kuò)展,也是JCA實(shí)現(xiàn)的一部分。JCE是根據(jù)美國(guó)加密技術(shù)出口于第三方國(guó)家的條件對(duì)Java的擴(kuò)展
JSSE
安全套接層(SSL)已經(jīng)成為應(yīng)用最為廣泛的通過(guò)加密保證數(shù)據(jù)完整性的數(shù)據(jù)協(xié)議坦冠。JSSE是一個(gè)標(biāo)準(zhǔn)接口和對(duì)SSL協(xié)議的實(shí)現(xiàn)。開(kāi)發(fā)人員可以使用另外一個(gè)商業(yè)化的SSL實(shí)現(xiàn)哥桥,而且通用JSSE接口仍舊可以使用辙浑。最新的Java平臺(tái)包含了其它的安全套接協(xié)議,如傳輸層安全(TLS)拟糕、Kerberos和簡(jiǎn)單認(rèn)證與安全層(SASL)判呕。同時(shí)JSSE還包括SSL/TLS上的HTTPS支持。
JAAS
JAAS實(shí)現(xiàn)了基于用戶(hù)認(rèn)證的訪(fǎng)問(wèn)限制送滞。和訪(fǎng)問(wèn)控制一起侠草,它們提供了抽象的認(rèn)證APIs函數(shù),這些函數(shù)通過(guò)可插拔體系結(jié)構(gòu)集成了各種登錄機(jī)制累澡。同時(shí)還提供了全面的策略與許可API梦抢,使用這些API允許開(kāi)發(fā)人員創(chuàng)建和管理對(duì)安全敏感資源具有良好的訪(fǎng)問(wèn)控制的應(yīng)用。 JAAS的一個(gè)重要特點(diǎn)是可以根據(jù)用戶(hù)身份或代碼簽名實(shí)現(xiàn)多種認(rèn)證機(jī)制單一登錄服務(wù)和良好的資源訪(fǎng)問(wèn)控制愧哟。近來(lái)對(duì)于時(shí)間戳簽名(始于Java5)的支持使得實(shí)施代碼簽名更加容易奥吩,避免了當(dāng)簽名證書(shū)過(guò)期時(shí)需要重簽的麻煩。
java中安全服務(wù)都是從java.security.Provider類(lèi)中的類(lèi)似MessageDigestSpi 的子類(lèi)提供的.XXXSpi是抽象父類(lèi)
1)MessageDigest:對(duì)消息進(jìn)行hash算法生成消息摘要(digest)蕊梧。
2)Signature:對(duì)數(shù)據(jù)進(jìn)行簽名霞赫、驗(yàn)證數(shù)字簽名。
3)KeyPairGenerator:根據(jù)指定的算法生成配對(duì)的公鑰肥矢、私鑰端衰。
4)KeyFactory:根據(jù)Key說(shuō)明(KeySpec)生成公鑰或者私鑰。
5)CertificateFactory:創(chuàng)建公鑰證書(shū)和證書(shū)吊銷(xiāo)列表(CRLs)甘改。
6)KeyStore:keystore是一個(gè)keys的數(shù)據(jù)庫(kù)旅东。Keystore中的私鑰會(huì)有一個(gè)相關(guān)聯(lián)的證書(shū)鏈,證書(shū)用于鑒定對(duì)應(yīng)的公鑰十艾。一個(gè)keystore也包含其它的信任的實(shí)體抵代。
7)AlgorithmParameters:管理算法參數(shù)。KeyPairGenerator就是使用算法參數(shù)忘嫉,進(jìn)行算法相關(guān)的運(yùn)算荤牍,生成KeyPair的案腺。生成Signature時(shí)也會(huì)用到。
8)AlgorithmParametersGenerator:用于生成AlgorithmParameters康吵。
9)SecureRandom:用于生成隨機(jī)數(shù)或者偽隨機(jī)數(shù)劈榨。
10)CertPathBuilder:用于構(gòu)建證書(shū)鏈。
11)CertPathValidator:用于校驗(yàn)證書(shū)鏈晦嵌。
12)CertStore:存儲(chǔ)同辣、獲取證書(shū)鏈、CRLs到(從)CertStore中耍铜。
Provider 是jre1.5.0_16\lib\security文件中定義的:
security.provider.1=sun.security.provider.Sun
security.provider.2=sun.security.rsa.SunRsaSign
security.provider.3=com.sun.net.ssl.internal.ssl.Provider
security.provider.4=com.sun.crypto.provider.SunJCE
security.provider.5=sun.security.jgss.SunProvider
security.provider.6=com.sun.security.sasl.Provider
當(dāng)然我們也可以實(shí)現(xiàn)自己的Provider,或者使用三方的邑闺,然后在該配置文件中配置一下即可跌前。
Provider三方擴(kuò)展
Base64加密算法
1.產(chǎn)生:郵件的“歷史問(wèn)題”
因?yàn)橛行┚W(wǎng)絡(luò)傳送渠道并不支持所有的字節(jié)棕兼,例如傳統(tǒng)的郵件只支持可見(jiàn)字符的傳送,像ASCII碼的控制字符就不能通過(guò)郵件傳送抵乓。這樣用途就受到了很大的限制伴挚,比如圖片二進(jìn)制流的每個(gè)字節(jié)不可能全部是可見(jiàn)字符,所以就傳送不了灾炭。最好的方法就是在不改變傳統(tǒng)協(xié)議的情況下茎芋,做一種擴(kuò)展方案來(lái)支持二進(jìn)制文件的傳送。把不可打印的字符也能用可打印字符來(lái)表示蜈出,問(wèn)題就解決了田弥。Base64編碼應(yīng)運(yùn)而生
2.定義:Base64就是一種基于64個(gè)可打印字符來(lái)表示二進(jìn)制數(shù)據(jù)的表示方法。
3.衍生:Base16铡原、Base32偷厦、Url Base64
4.Base64代碼實(shí)現(xiàn)
JDK實(shí)現(xiàn)
/**
* 使用JDK提供的api實(shí)現(xiàn)Base64
* @param src : 明文
*/
public static void jdkBase64(String src){
try {
//加密編碼
BASE64Encoder encoder = new BASE64Encoder();
String encode = encoder.encode(src.getBytes());
System.out.println("jdk encoder:" + encode);
//解碼
BASE64Decoder decoder = new BASE64Decoder();
String decode = new String(decoder.decodeBuffer(encode));
System.out.println("jdk decoder:" + decode);
} catch (IOException e) {
e.printStackTrace();
}
}
三方-Commons Codes實(shí)現(xiàn)
/**
* 使用三方-Commons Codes實(shí)現(xiàn)Base64
* @param src :明文
*/
public static void commonsCodesBase64(String src) {
//加密編碼
byte[] encodeBytes = Base64.encodeBase64(src.getBytes());
System.out.println("cc encoder Base64:" + new String(encodeBytes));
//解碼
byte[] decodeBytes = Base64.decodeBase64(encodeBytes);
System.out.println("cc decoder Base64:" + new String(decodeBytes));
}
三方-Bouncy Castle實(shí)現(xiàn)
/**
* 使用三方-Bouncy Castle實(shí)現(xiàn)Base64
* @param src :明文
*/
public static void bouncyCastleBase64(String src) {
//加密編碼
byte[] encodeBytes = org.bouncycastle.util.encoders.Base64.encode(src.getBytes());
System.out.println("bc encoder Base64:" + new String(encodeBytes));
//解碼
byte[] decodeBytes = org.bouncycastle.util.encoders.Base64.decode(encodeBytes);
System.out.println("bc decoder Base64:" + new String(decodeBytes));
}
總結(jié)
Base64:屬于加密算法,是可逆的燕刻,經(jīng)過(guò)encode后只泼,可以將decode得到原文。在開(kāi)發(fā)中卵洗,有的公司上傳圖片采用的是將圖片轉(zhuǎn)換成Base64字符串请唱,再上傳。在做加密相關(guān)的功能時(shí)过蹂,通常會(huì)將數(shù)據(jù)進(jìn)行Base64加密/解密十绑。其他的應(yīng)用場(chǎng)景:郵件,證書(shū)等酷勺。
6.消息摘要算法
消息摘要(Message Digest)又稱(chēng)為數(shù)字摘要本橙。它是一個(gè)唯一對(duì)應(yīng)一個(gè)消息或文本的固定長(zhǎng)度的值,它由一個(gè)單向Hash加密函數(shù)對(duì)消息進(jìn)行作用而產(chǎn)生鸥印。如果消息在途中改變了勋功,則接收者通過(guò)對(duì)收到消息的新產(chǎn)生的摘要與原摘要比較坦报,就可知道消息是否被改變了。因此消息摘要保證了消息的完整性狂鞋,常用于驗(yàn)證數(shù)據(jù)的完整性片择。
6.1.消息摘要算法-MD家族
MD5:是一種不可逆的摘要算法,用于生成摘要骚揍,無(wú)法逆破解到原文,用于驗(yàn)證數(shù)據(jù)的有效性字管。比如,在網(wǎng)絡(luò)請(qǐng)求接口中信不,通過(guò)將所有的參數(shù)生成摘要嘲叔,客戶(hù)端和服務(wù)端采用同樣的規(guī)則生成摘要,這樣可以防止篡改抽活。又如硫戈,下載文件時(shí),通過(guò)生成文件的摘要下硕,用于驗(yàn)證文件是否損壞丁逝。
JDK實(shí)現(xiàn)
/**
* 使用JDK實(shí)現(xiàn)MD5加密
* @param src:消息
*/
public static void jdkMD5(String src) {
try {
MessageDigest md = MessageDigest.getInstance("MD5");
byte[] md5Bytes = md.digest(src.getBytes());
//轉(zhuǎn)化為16進(jìn)制字符串輸出
System.out.println(Hex.encodeHexString(md5Bytes));
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
}
}
如果想是想MD2等加密,只需要將MessageDigest.getInstance("MD2");參數(shù)換成對(duì)應(yīng)的算法名稱(chēng)即可梭姓。
三方Bouncy Castle實(shí)現(xiàn)
/**
* 使用三方Bouncy Castle實(shí)現(xiàn)MD5加密
* @param src:消息
*/
public static void bouncyCastleMD5(String src) {
try {
Digest digest = new MD5Digest();
digest.update(src.getBytes(),0,src.getBytes().length);
byte[] md5Bytes = new byte[digest.getDigestSize()];
digest.doFinal(md5Bytes, 0);
//轉(zhuǎn)化為16進(jìn)制字符串輸出
System.out.println(org.bouncycastle.util.encoders.Hex.toHexString(md5Bytes));
} catch (Exception e) {
e.printStackTrace();
}
}
三方-Commons Codes實(shí)現(xiàn)
/**
* 使用三方Commons Codes實(shí)現(xiàn)MD5加密
* @param src:消息
*/
public static void commonsCodesMD5(String src) {
byte[] md5Bytes = DigestUtils.md5(src);
System.out.println(Hex.encodeHexString(md5Bytes));
}
MD應(yīng)用
6.2.消息摘要算法-SHA家族
SHA算法分為一代和二代霜幼,這個(gè)是美國(guó)安全局發(fā)布的一系列的密碼散列算法
除了SHA-1以外其他的也統(tǒng)稱(chēng)為SHA-2(二代)
JDK實(shí)現(xiàn)
/**
* 使用JDK實(shí)現(xiàn)SHA-1加密
* @param src
*/
public static void jdkSHA1(String src) {
try {
MessageDigest digest = MessageDigest.getInstance("SHA");
digest.update(src.getBytes());
System.out.println(Hex.encodeHexString(digest.digest()));
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
}
}
三方-Commons Codes實(shí)現(xiàn)
/**
* 使用三方Commons Codes實(shí)現(xiàn)SHA-1加密
* @param src:消息
*/
public static void commonsCodesSHA1(String src) {
String sha1Hex = DigestUtils.sha1Hex(src.getBytes());
System.out.println(sha1Hex);
}
三方-Bouncy Castle實(shí)現(xiàn)
/**
* 使用三方Bouncy Castle實(shí)現(xiàn)SHA-1加密
* @param src:消息
*/
public static void bouncyCastleSHA1(String src) {
Digest digest = new SHA1Digest();
digest.update(src.getBytes(), 0, src.getBytes().length);
byte[] sha1Bytes = new byte[digest.getDigestSize()];
digest.doFinal(sha1Bytes, 0);
System.out.println(org.bouncycastle.util.encoders.Hex.toHexString(sha1Bytes));
}
應(yīng)用
6.3.消息摘要算法-MAC家族
MAC(Message Authentication Code,消息認(rèn)證碼算法)是含有密鑰散列函數(shù)算法誉尖,兼容了MD和SHA算法的特性罪既,并在此基礎(chǔ)上加上了密鑰。因此MAC算法也經(jīng)常被稱(chēng)作HMAC算法
使用JDK實(shí)現(xiàn)
/**
* 使用JDK實(shí)現(xiàn)HmacMD5(MAC)加密
* @param src
*/
public static void jdkHmacMD5(String src) {
try {
KeyGenerator keyGenerator = KeyGenerator.getInstance("HmacMD5");//初始化密鑰生成器
SecretKey secretKey = keyGenerator.generateKey();//產(chǎn)生密鑰
byte[] encoded = secretKey.getEncoded();//獲取密鑰
SecretKey restoreSecretKey = new SecretKeySpec(encoded, "HmacMD5");//還原密鑰
Mac mac = Mac.getInstance(restoreSecretKey.getAlgorithm());//實(shí)例化MAC
mac.init(restoreSecretKey);//初始化MAC
byte[] hmacmd5Bytes = mac.doFinal(src.getBytes());//執(zhí)行摘要
System.out.println(Hex.encodeHexString(hmacmd5Bytes));
} catch (Exception e) {
e.printStackTrace();
}
}
使用Bouncy Castle實(shí)現(xiàn)
/**
* 使用三方Bouncy Castle實(shí)現(xiàn)MAC加密
* @param src:消息
*/
public static void bouncyCastleHmacMD5(String src) {
HMac hMac = new HMac(new MD5Digest());
hMac.init(new KeyParameter(org.bouncycastle.util.encoders.Hex.decode("gfdgfdgfdgfd")));
hMac.update(src.getBytes(),0,src.getBytes().length);
byte[] hmacmd5Bytes = new byte[hMac.getMacSize()];//執(zhí)行摘要
hMac.doFinal(hmacmd5Bytes, 0);
System.out.println(org.bouncycastle.util.encoders.Hex.toHexString(hmacmd5Bytes));
}