Java中的加密算法(一)

由于計算機軟件的非法復制,通信的泄密、數據安全受到威脅,解密及盜版問題日益嚴重,甚至引發國際爭端,所以在信息安全技術中,加密技術占有不可替代的位置,因此對信息加密技術和加密手段的研究與開發,受到各國計算機界的重視,發展日新月異。現在就給大家介紹幾種常用的加密算法。
1.密碼中常用的術語
2.密碼分類
3.OSI和TCP/IP安全體系
4.Java安全組成
5.Base64加密算法
6.消息摘要算法
6.1.消息摘要算法-MD家族
6.2.消息摘要算法-SHA家族
6.3.消息摘要算法-MAC家族

1.加密中常用的術語:

<b>明文</b>:待加密的信息
<b>密文</b>:加密后的明文
<b>加密</b>:明文轉密文的過程
<b>加密算法</b>:明文轉密文的轉換算法
<b>密鑰</b>:密鑰是一種參數,它是在明文轉換為密文或將密文轉換為明文的算法中輸入的參數。密鑰分為對稱密鑰與非對稱密鑰。
<b>加密密鑰</b>:通過加密算法進行加密過程中用的密鑰
<b>解密</b>:將密文轉名文的過程
<b>解密算法</b>:密文轉明文的轉換算法
<b>解密密鑰</b>:通過解密算法進行解密過程中用的密鑰
<b>密碼分析</b>:截獲密文這試圖通過分析截獲的密文從而推斷出原來的明文或密鑰的過程
<b>主動攻擊</b>:攻擊者非法入侵密碼系統,采用偽造、修改、刪除等手段向系統注入假消息進行欺騙(對密文有破壞作用)
<b>被動攻擊</b>:對一個保密系統采取截獲密文并對其進行分析和攻擊(對密文沒有破壞作用)
<b>密碼體系</b>:由明文空間,密文空間,密鑰空間,加密算法和解密算法五部分組成
<b>密碼協議</b>:也稱安全協議,指以密碼學為基礎的消息交換的通信協議,目的是在網絡環境中提供安全的服務。
<b>密碼系統</b>:用于加密和解密的系統
<b>柯克霍夫原則</b>:數據的安全基于密鑰而不是算法的保密。即系統的安全取決于密鑰,對密鑰保密,對算法公開。-----現在密碼學設計的基本原則

2.密碼分類

  • 按時間分:
    • 古典密碼:以字符為基本的加密單元
    • 現代密碼:以信息塊為基本的加密單元
  • 按保密內容分:
    • 受限制算法:算法的保密基于保持算法的密碼,常用語軍事領域
    • 基于密鑰算法:算法的保密基于對密鑰的保密
  • 按密碼體系分:
    • 對稱密碼:別名單鑰密碼或私鑰密碼;指加密密鑰和解密密鑰相同
    • 非對稱密碼:別名雙鑰密碼或公鑰密碼;指加密密鑰和解密密鑰不同,密鑰分為公鑰和私鑰
  • 按明文的處理方法:
    • 分組密碼:指加密時將明文分成固定長度的組,用同一密鑰和算法對每一組進行加密,輸出也是固定長度的密文。多用于網絡加密。
    • 流密碼:也稱序列密碼。指加密時每次加密一位或者一個字節明文。

3.OSI和TCP/IP安全體系

OSI安全體系.png
TCP安全體系01.png
TCP安全體系02.png

4.Java安全組成

Java安全平臺.png
Java 安全體系內核:它包括:字節碼驗證器、類加載器、安全管理器、訪問控制器、訪問權限管理器和策略描述工具等
Java代碼在Java安全體系內核組件中的執行過程
  • 字節碼驗證器分析字節碼的順序
  • 字節碼驗證器檢查對其它類的引用

例如,如果一個類要訪問另一個類的方法,字節碼驗證器就要檢查該方法是否為public.字節碼驗證器的典型操作包括:檢查字節碼的順序是否以0XCAFEBABE開始,是否丟失字節,最后的類是否包含子類(它們不應該包括),方法的參數類型是什么等。如果一切正常,接下來類加載器將字節碼翻譯成java類,然后由java虛擬機(JVM)執行。如果需要加載一個特別的類可以定義不同的策略加以說明。通過委托給安全管理器的方式如果某個類可以訪問特別的系統資源,那么類加載器和
java標準類也可以定義決策權。

  • 安全管理器:是一個可有開發人員實現的特殊類,用于指明一個類是否可以訪問指定的資源(例如,文件訪問或網絡連接)。為了做出決策,安全管理器需要分析請求來源。如果訪問被拒絕,將會拋出一個java.lang.SecurityExceptin異常,否則的話,將會以通常的方式處理該調用。
JCA
  • 它提供了Java平臺上執行主要加密服務的基礎設施,包括數字簽名,信息摘要,密碼,信息認證碼密鑰生成器和密鑰生成器。同時JCA還保證了數據完整性并提供了顯示全部特性的APIs。
  • JCA僅僅是一個接口,可以有很多該接口的實現,它支持很大范圍的標準算法包括RSA、DSA、三重DES、SHA、PKCS#5、RC2以及RC4.JCA是可擴展的,豐富的API可用于構建安全的應用,而其它還是算法與實現相互獨立的,使用基于提供(可插拔)的體系結構。

其他體系結構

JCE

這是Sun微系統公司對數據塊加密與解密的擴展,也是JCA實現的一部分。JCE是根據美國加密技術出口于第三方國家的條件對Java的擴展

JSSE

安全套接層(SSL)已經成為應用最為廣泛的通過加密保證數據完整性的數據協議。JSSE是一個標準接口和對SSL協議的實現。開發人員可以使用另外一個商業化的SSL實現,而且通用JSSE接口仍舊可以使用。最新的Java平臺包含了其它的安全套接協議,如傳輸層安全(TLS)、Kerberos和簡單認證與安全層(SASL)。同時JSSE還包括SSL/TLS上的HTTPS支持。

JAAS

JAAS實現了基于用戶認證的訪問限制。和訪問控制一起,它們提供了抽象的認證APIs函數,這些函數通過可插拔體系結構集成了各種登錄機制。同時還提供了全面的策略與許可API,使用這些API允許開發人員創建和管理對安全敏感資源具有良好的訪問控制的應用。 JAAS的一個重要特點是可以根據用戶身份或代碼簽名實現多種認證機制單一登錄服務和良好的資源訪問控制。近來對于時間戳簽名(始于Java5)的支持使得實施代碼簽名更加容易,避免了當簽名證書過期時需要重簽的麻煩。

java中安全服務都是從java.security.Provider類中的類似MessageDigestSpi 的子類提供的.XXXSpi是抽象父類
Java安全服務相關類體系圖.png

1)MessageDigest:對消息進行hash算法生成消息摘要(digest)。
2)Signature:對數據進行簽名、驗證數字簽名。
3)KeyPairGenerator:根據指定的算法生成配對的公鑰、私鑰。
4)KeyFactory:根據Key說明(KeySpec)生成公鑰或者私鑰。
5)CertificateFactory:創建公鑰證書和證書吊銷列表(CRLs)。
6)KeyStore:keystore是一個keys的數據庫。Keystore中的私鑰會有一個相關聯的證書鏈,證書用于鑒定對應的公鑰。一個keystore也包含其它的信任的實體。
7)AlgorithmParameters:管理算法參數。KeyPairGenerator就是使用算法參數,進行算法相關的運算,生成KeyPair的。生成Signature時也會用到。
8)AlgorithmParametersGenerator:用于生成AlgorithmParameters。
9)SecureRandom:用于生成隨機數或者偽隨機數。
10)CertPathBuilder:用于構建證書鏈。
11)CertPathValidator:用于校驗證書鏈。
12)CertStore:存儲、獲取證書鏈、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
當然我們也可以實現自己的Provider,或者使用三方的,然后在該配置文件中配置一下即可。
Provider三方擴展
第三方java寬展.png

Base64加密算法

1.產生:郵件的“歷史問題”

因為有些網絡傳送渠道并不支持所有的字節,例如傳統的郵件只支持可見字符的傳送,像ASCII碼的控制字符就不能通過郵件傳送。這樣用途就受到了很大的限制,比如圖片二進制流的每個字節不可能全部是可見字符,所以就傳送不了。最好的方法就是在不改變傳統協議的情況下,做一種擴展方案來支持二進制文件的傳送。把不可打印的字符也能用可打印字符來表示,問題就解決了。Base64編碼應運而生

2.定義:Base64就是一種基于64個可打印字符來表示二進制數據的表示方法。
Base64.png
3.衍生:Base16、Base32、Url Base64

4.Base64代碼實現

JDK實現
/**
 * 使用JDK提供的api實現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實現
/**
 * 使用三方-Commons Codes實現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實現
/**
 * 使用三方-Bouncy Castle實現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));
}
總結

Base64:屬于加密算法,是可逆的,經過encode后,可以將decode得到原文。在開發中,有的公司上傳圖片采用的是將圖片轉換成Base64字符串,再上傳。在做加密相關的功能時,通常會將數據進行Base64加密/解密。其他的應用場景:郵件,證書等。

6.消息摘要算法

消息摘要(Message Digest)又稱為數字摘要。它是一個唯一對應一個消息或文本的固定長度的值,它由一個單向Hash加密函數對消息進行作用而產生。如果消息在途中改變了,則接收者通過對收到消息的新產生的摘要與原摘要比較,就可知道消息是否被改變了。因此消息摘要保證了消息的完整性,常用于驗證數據的完整性。

6.1.消息摘要算法-MD家族

MD家族.png

MD5:是一種不可逆的摘要算法,用于生成摘要,無法逆破解到原文,用于驗證數據的有效性。比如,在網絡請求接口中,通過將所有的參數生成摘要,客戶端和服務端采用同樣的規則生成摘要,這樣可以防止篡改。又如,下載文件時,通過生成文件的摘要,用于驗證文件是否損壞。

JDK實現
/**
 * 使用JDK實現MD5加密
 * @param src:消息
 */
public static void jdkMD5(String src) {
    try {
        MessageDigest md = MessageDigest.getInstance("MD5");
        byte[] md5Bytes = md.digest(src.getBytes());
        //轉化為16進制字符串輸出
        System.out.println(Hex.encodeHexString(md5Bytes));
    } catch (NoSuchAlgorithmException e) {
        e.printStackTrace();
    }
}

如果想是想MD2等加密,只需要將MessageDigest.getInstance("MD2");參數換成對應的算法名稱即可。

三方Bouncy Castle實現

/**
 * 使用三方Bouncy Castle實現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);
        //轉化為16進制字符串輸出
        System.out.println(org.bouncycastle.util.encoders.Hex.toHexString(md5Bytes));
    } catch (Exception e) {
        e.printStackTrace();
    }
}

三方-Commons Codes實現

/**
 * 使用三方Commons Codes實現MD5加密
 * @param src:消息
 */
public static void commonsCodesMD5(String src) {
    byte[] md5Bytes = DigestUtils.md5(src);
    System.out.println(Hex.encodeHexString(md5Bytes));
}

MD應用

MD應用.png

6.2.消息摘要算法-SHA家族

SHA算法.png

SHA算法分為一代和二代,這個是美國安全局發布的一系列的密碼散列算法
除了SHA-1以外其他的也統稱為SHA-2(二代)

JDK實現
/**
 * 使用JDK實現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實現
/**
 * 使用三方Commons Codes實現SHA-1加密
 * @param src:消息
 */
public static void commonsCodesSHA1(String src) {
    String sha1Hex = DigestUtils.sha1Hex(src.getBytes());
    System.out.println(sha1Hex);
}
三方-Bouncy Castle實現
/**
 * 使用三方Bouncy Castle實現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));
}

應用

SHA應用.png

6.3.消息摘要算法-MAC家族

MAC(Message Authentication Code,消息認證碼算法)是含有密鑰散列函數算法,兼容了MD和SHA算法的特性,并在此基礎上加上了密鑰。因此MAC算法也經常被稱作HMAC算法

MAC算法.png

使用JDK實現

/**
 * 使用JDK實現HmacMD5(MAC)加密
 * @param src
 */
public static void jdkHmacMD5(String src) {
    try {
        KeyGenerator keyGenerator = KeyGenerator.getInstance("HmacMD5");//初始化密鑰生成器
        SecretKey secretKey = keyGenerator.generateKey();//產生密鑰
        byte[] encoded = secretKey.getEncoded();//獲取密鑰
        SecretKey restoreSecretKey = new SecretKeySpec(encoded, "HmacMD5");//還原密鑰
        Mac mac = Mac.getInstance(restoreSecretKey.getAlgorithm());//實例化MAC
        mac.init(restoreSecretKey);//初始化MAC
        byte[] hmacmd5Bytes = mac.doFinal(src.getBytes());//執行摘要
        System.out.println(Hex.encodeHexString(hmacmd5Bytes));
    } catch (Exception e) {
        e.printStackTrace();
    }
}

使用Bouncy Castle實現

/**
 * 使用三方Bouncy Castle實現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()];//執行摘要
    hMac.doFinal(hmacmd5Bytes, 0);
    System.out.println(org.bouncycastle.util.encoders.Hex.toHexString(hmacmd5Bytes));
}

應用

MAC應用.png

java中的加密算法(二)

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容