天天看點

《Shiro安全架構》專題(四)-Shiro之加密

目錄

  • ​​1.概念​​
  • ​​2.加密分類​​
  • ​​2.1.對稱加密​​
  • ​​2.2.非對稱加密​​
  • ​​2.3.對稱加密和非對稱加密小結​​
  • ​​3.加密算法分類​​
  • ​​3.1.單向加密​​
  • ​​3.2.雙向加密​​
  • ​​4.常見算法​​
  • ​​5.MD5的使用​​
  • ​​6.鹽值的作用​​
  • ​​7.shiro中使用MD5加密​​

1.概念

加密,是以某種特殊的算法改變原有的資訊資料,使得未授權的使用者即使獲得了已加密的資訊,但因不知解密的方法,仍然無法了解資訊的内容

資料加密的基本過程就是對原來為明文的檔案或資料按某種算法進行處理,使其成為不可讀的一段代碼,通常稱為"密文",使其隻能在輸入相應的密鑰之後才能顯示出本來内容,通過這樣的途徑來達到保護資料不被非法人竊取、閱讀的目的。該過程的逆過程為解密,即将該編碼資訊轉化為其原來資料的過程。

2.加密分類

2.1.對稱加密

在對稱加密算法中,加密和解密使用的是同一把鑰匙,即:使用相同的密匙對同一密碼進行加密和解密;

加密過程如下:

加密:原文 + 密匙 = 密文
解密:密文 - 密匙 = 原文      
《Shiro安全架構》專題(四)-Shiro之加密

例如:小明給小紅發送微信消息表白,為了避免小紅手機臨時不在身邊而導緻消息被其他熱看到,遠原本小明計劃發送”我愛你一生一世”,小明和小紅使用一種約定好的暗語”5201314”來替代。當小紅收到消息時,則自然明白文字的含義。

2.2.非對稱加密

白了對稱加密後,我們來了解一下什麼是非對稱加密。我們知道,對稱加密是使用的

同一把密匙進行加密和解密。那麼,非對稱加密自然是使用不同的密鑰進行加密和解密啦。

非對稱加密有兩個鑰匙,及公鑰(Public Key)和私鑰(Private Key)。公鑰和私鑰是成對的存在,如果對原文使用公鑰加密,則隻能使用對應的私鑰才能解密;因為加密和解密使用的不是同一把密鑰,是以這種算法稱之為非對稱加密算法。

非對稱加密算法的密匙是通過一系列算法擷取到的一長串随機數,通常随機數的長度越長,加密資訊越安全。通過私鑰經過一系列算法是可以推導出公鑰的,也就是說,公鑰是基于私鑰而存在的。但是無法通過公鑰反向推倒出私鑰,這個過程的單向的。

下面,讓我們看一下非對稱加密及解密過程。

《Shiro安全架構》專題(四)-Shiro之加密

根據上圖,我們可以看到,對于原文,通過接收方的公鑰進行加密,發送給接收方,接收方拿到密文後,通過自己的私鑰可以解密,擷取原文資訊。在這個過程中,及時接收方公鑰洩漏,也不會導緻消息洩漏,因為密文隻能通過接收方的私鑰才能打開。是以,資訊安全過程中,接收方隻需要保管好自己的私鑰不洩露即可。

同樣,當接收方向發送方發送消息時,接收方将密文通過原發送方的公鑰進行加密,原發送方通過自己的私鑰才可解密。

到了這裡,是不是感覺思維清晰了很多。了解了對稱加密和非對稱加密,那麼,先來聊聊它們各自的優缺點吧。

2.3.對稱加密和非對稱加密小結

對稱加密:

優點:算法簡單,加密解密容易,效率高,執行快。

缺點:相對來說不算特别安全,隻有一把鑰匙,密文如果被攔截,且密鑰也被劫持,那麼,資訊很容易被破譯。      

非對稱加密:

優點:安全,即使密文被攔截、公鑰被擷取,但是無法擷取到私鑰,也就無法破譯密文。作為接收方,務必要保管好自己的密鑰。

缺點:加密算法及其複雜,安全性依賴算法與密鑰,而且加密和解密效率很低。      

3.加密算法分類

3.1.單向加密

單向加密是不可逆的,也就是隻能加密,不能解密。通常用來傳輸類似使用者名和密碼,直接将加密後的資料送出到背景,因為背景不需要知道使用者名和密碼,可以直接将收到的加密後的資料存儲到資料庫

3.2.雙向加密

通常分為對稱性加密算法和非對稱性加密算法,對于對稱性加密算法,資訊接收雙方都需事先知道密匙和加解密算法且其密匙是相同的,之後便是對資料進行 加解密了。非對稱算法與之不同,發送雙方A,B事先均生成一堆密匙,然後A将自己的公有密匙發送給B,B将自己的公有密匙發送給A,如果A要給B發送消 息,則先需要用B的公有密匙進行消息加密,然後發送給B端,此時B端再用自己的私有密匙進行消息解密,B向A發送消息時為同樣的道理。

4.常見算法

算法 描述
DES(Data Encryption Standard 資料加密标準,速度較快,适用于加密大量資料的場合;
3DES(Triple DES) 是基于DES,對一塊資料用三個不同的密鑰進行三次加密,強度更高;
RC2和 RC4 用變長密鑰對大量資料進行加密,比 DES 快;
IDEA(International Data Encryption Algorithm) 國際資料加密算法:使用 128 位密鑰提供非常強的安全性;
RSA 由 RSA 公司發明,是一個支援變長密鑰的公共密鑰算法,需要加密的檔案塊的長度也是可變的;
DSA(Digital Signature Algorithm) 數字簽名算法,是一種标準的 DSS(數字簽名标準);
AES(Advanced Encryption Standard) 進階加密标準,是下一代的加密算法标準,速度快,安全級别高,目前 AES 标準的一個實作是 Rijndael 算法;
BLOWFISH 它使用變長的密鑰,長度可達448位,運作速度很快;
MD5 (Message-Digest Algorithm) 消息摘要算法,一種被廣泛使用的密碼散列函數,可以産生出一個128位(16位元組)的散列值(hash value),用于確定資訊傳輸完整一緻

5.MD5的使用

package com.bruce.test;

import org.apache.shiro.crypto.hash.Md5Hash;
import org.junit.Test;

/**
 * @BelongsProject: shiro2020
 * @BelongsPackage: com.bruce.test
 * @CreateTime: 2021-01-29 14:43
 * @Description: TODO
 */
public class Md5Test {

    @Test
    public void Md5Test() {
        // 對單個資訊加密
        Md5Hash md5 = new Md5Hash("123456");
        System.out.println(md5.toString());
        // 加密添加鹽值 增大解密難度
        md5 = new Md5Hash("123456","aaa");
        System.out.println(md5.toString());
        // 加密添加鹽值 增大解密難度 2疊代兩次
        md5 = new Md5Hash("123456","aaa",2);
        System.out.println(md5);
    }

}      

輸出的結果:

e10adc3949ba59abbe56e057f20f883e
88316675d7882e3fdbe066000273842c
a7cf41c6537065fe724cc9980f8b5635      

6.鹽值的作用

使用MD5存在一個問題,相同的password生成的hash值是相同的,如果兩個使用者設定了相同的密碼,那麼資料庫中會存儲兩個相同的值,這是極不安全的,加Salt可以在一定程度上解決這一問題,所謂的加Salt方法,就是加點‘佐料’。其基本想法是這樣的,當使用者首次提供密碼時(通常是注冊時)由系統自動往這個密碼裡撒一些‘佐料’,然後在散列,而當使用者登入時,系統為使用者提供的代碼上撒上相同的‘佐料’,然後散列,再比較散列值,來确定密碼是否正确。

加鹽的原理:

給原文加入随機數生成新的MD5的值

7.shiro中使用MD5加密

認證方法中修改

/**
     * 認證方法
     * @param token
     *  就是我們在測試代碼中 定義的UsernamePasswordToken對象
     *  有我們儲存的需要驗證的賬号密碼資訊
     */
    @Override
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
        // 擷取賬号資訊
        String principal = (String) token.getPrincipal();
        // 正常邏輯此處應該根據賬号去資料庫中查詢,此處我們預設賬号為 root 密碼123456
        // 驗證賬号
        if(!"root".equals(principal)){
            // 賬号錯誤
            return null;
        }
        //String pwd = "123456";
        // 12345 根據 鹽值 aaa 加密擷取的密文
        //88316675d7882e3fdbe066000273842c  1次疊代的密文
        //a7cf41c6537065fe724cc9980f8b5635  2次疊代的密文
        String pwd = "88316675d7882e3fdbe066000273842c";
        // 驗證密碼
        AuthenticationInfo info = new SimpleAuthenticationInfo(
                principal, pwd,new SimpleByteSource("aaa"),"myrealm");
        return info;
    }      
《Shiro安全架構》專題(四)-Shiro之加密

shiro.ini檔案修改

[main]
#定義憑證比對器
credentialsMatcher=org.apache.shiro.authc.credential.HashedCredentialsMatcher
#雜湊演算法
credentialsMatcher.hashAlgorithmName=md5
#散列次數
credentialsMatcher.hashIterations=1

#将憑證比對器設定到realm
customRealm=com.bruce.realm.MyRealm
customRealm.credentialsMatcher=$credentialsMatcher
securityManager.realms=$customRealm      

測試

@Test
    public void test() {
        // 1.擷取SecurityManager工廠對象
        Factory<SecurityManager> factory =
                new IniSecurityManagerFactory("classpath:shiro.ini");
        // 2.通過Factory對象擷取SecurityManager對象
        SecurityManager securityManager = factory.getInstance();
        // 3.将SecurityManager對象添加到目前運作環境中
        SecurityUtils.setSecurityManager(securityManager);

        // 4.擷取Subject對象
        Subject subject = SecurityUtils.getSubject();
        AuthenticationToken token = new UsernamePasswordToken("root", "123456");
        // 登入操作
        try {
            subject.login(token);
        } catch (UnknownAccountException e) {
            System.out.println("賬号出錯...");
        } catch(IncorrectCredentialsException e){
            System.out.println("密碼出錯...");
        }
        // 擷取登入的狀态
        System.out.println(subject.isAuthenticated());
    }