Java加密與安全

1、簡介

數據安全java

  • 防竊聽
  • 防篡改
  • 防僞造
    古代加密方式:
  • 移位密碼:HELLO => IFMMP 按照英文順序日後移動一位
  • 替代密碼:HELLO =>p12,5,3 或者是用某一本書的第幾頁第幾行第幾個字達到替換密碼的目的

這些都是靠人的想象和直覺來涉及的,很是不靠譜,而現代計算機加密:算法

  • 創建在嚴格的數據理論基礎上
  • 密碼學逐漸發展成一門學科

總結 數組

  • 設計一個安全的加密算法很是困難
  • 驗證一個加密算法是否安全更加困難
  • 當前被認爲安全的加密算法僅僅是迄今爲止還沒有被攻破
  • 不要 本身設計加密算法
  • 不要 本身實現加密算法
  • 不要 本身修改已有的加密算法

2、URL編碼

1、什麼是URL編碼?
URL編碼是瀏覽器發送數據給服務器時使用的編碼。瀏覽器

  • key1=value1&key2=value2&key3=valuye
  • q=%E4%B8%AD%E6%96%87

什麼是編碼?
ascii碼就是一種編碼,例如安全

字母 編碼(16進制)
A 0x41
B 0x42
C 0x43
D 0x44
... ...

漢字 Unicode編碼 UTF-8編碼
0x4e2d 0xe4b8ad
0x6587 0xe69687
0x7f16 0xe7bc96
0x7801 0xe7a081
... ... ...

URL編碼規則是什麼?服務器

  • A-Z,a-z,0-9以及**-_.***保持不變
  • 其餘字符以%XX表示
    例如:
    1.<:%3C
    2.中:%E4%B8%AD(utf-8:0xe4b8ad)

例子dom

/**
 * URL編碼
 */
public class SecURL {
    public static void main(String[] args) throws UnsupportedEncodingException {
        String original = "URL 參數";
        String encoded = URLEncoder.encode(original,"UTF-8");
        System.out.println("編碼後:"+encoded);
        String ori = new String(URLDecoder.decode(encoded,"UTF-8"));
        System.out.println("解碼後:"+ori);
    }
}

Java加密與安全

總結ide

  • URL編碼是編碼算法,不是加密算法
  • URL編碼的目的是把任意文本數據編碼爲%前綴表示的文本,編碼後的文本僅包含A-Z,a-z,0-9以及-_.,%*便於瀏覽器和服務器處理

2、Base64編碼
* 什麼是Base64編碼?
是一種把二進制數據用文本表示的編碼算法,例如:byte[]{0xe4,0xb8,0xad} ==> "5Lit"測試

索引 編碼 索引 編碼 索引 編碼
0 A 26 a 52 0
1 B 27 b 53 1
2 C 28 c ... ...
3 D 29 d 61 9
... ... ... ... 62 +
25 Z 51 z 63 /

目的編碼

  • 是一種用文本(A-Z,a-z,0-9,+/=)表示二進制內容的方式
  • 適用於文本協議
  • 效率降低
    由於二進制通過base64編碼它的長度會增長三分之一,若是數組的長度不是3的整數倍,末尾補0x00或0x00 0x00
    編碼後加=表示補充了1個字節
    編碼後加==表示補充了2個字節
    應用
  • 電子郵件協議
/**
 * Base64編碼
 */
public class SecBase64 {

    public static void main(String[] args) throws Exception {
        String original = "Hello\u00ff編碼測試";
        //withoutPadding()能夠去掉編碼後「=」這個字節,有沒有=對於解碼來講沒有影響
        String b64 = Base64.getEncoder().withoutPadding().encodeToString(original.getBytes("UTF-8"));
        System.out.println(b64);
        String ori = new String(Base64.getDecoder().decode(b64), "UTF-8");
        System.out.println(ori);
    }
}

Java加密與安全
因爲標準的base64在url中會引發衝突,因此在url中使用base64編碼會使用另一種。
Java加密與安全
在java中,使用url的base64編碼它會把「+」變爲「-」,把「/"變爲「_」這樣在傳遞url參數的時候不會引發衝突

總結

  • Base64是編碼算法,不是加密算法
  • Base64編碼的目的是把任意二進制數據編碼爲文本(長度增長1/3)
  • 其餘編碼:Base3二、Base4八、Base58

3、摘要算法

1、什麼是摘要算法?
摘要算法是一種能產生特殊輸出格式的算法,這種算法的特色是:不管用戶輸入多少長度的原始數據,通過計算後輸出的密文都是固定長度的,只要原數據稍有改變,輸出的「摘要」便徹底不一樣,所以,基於這種原理的算法便能對數據完整性提供較爲健全的保障。
        經常使用的摘要算法主要有MD5和SHA1。D5的輸出結果爲16字節(128位),SHA1的輸出結果爲20字節(160位)。
摘要算法(又稱哈希算法/數字指紋)
* 計算任意成都數據的摘要(固定長度)

  • 相同的輸入數據始終獲得相同的輸出
  • 不一樣的輸入數據儘可能獲得不一樣的輸出

目的:

  • 驗證原始數據是否被篡改

例如:
輸入:任意長度的數據(byte[])
輸出:固定長度的數據(byte[n])
hash("hello") = 0x5e918d2
hash("hello,java") = 0x7a9d88e8
hash("hello,bob") = 0xa0dbae2f

Java的Object.hashCode()方法就是一個摘要算法
這就是說相同的輸入必須獲得相同的輸出,當咱們從新equals()方法的時候也要同時從新hashCode()方法


什麼是碰撞?
兩個不一樣的輸入獲得了相同的輸出
例如:
hash("abc") = 0x12345678
hash("xyz") = 0x12345678
這個時候咱們就說發生了碰撞,碰撞能不能呢,碰撞是不能避免的。
輸出的字節是固定的,而輸入的字節是不肯定的

輸出n bits 範圍
0000000000 0
0000000001 1
0000000010 2
... ...
11111111111 62235

Hash算法的安全性?

  • 碰撞率低
  • 不能猜想輸出
  • 輸入任意一個bit的變化都會形成徹底不一樣的輸出
  • 很難從輸出反推出輸入(只能依靠暴力窮舉)

經常使用摘要算法
Java加密與安全

彩虹表
什麼是彩虹表呢?是一個預先計算好的經常使用的字符和md5的一個對照表。
抵禦彩虹表

  • 對每一個口令額外添加隨機數鹽值(salt)
public static void main(String[] args) throws Exception{

        String str = "MD5摘要算法測試";
        byte[] bytes = toMD5(str.getBytes("UTF-8"));
        //以16進制的方式,打印出byte數組
        System.out.println(String.format("%032x",new BigInteger(1,bytes)));
    }
    public static byte[] toMD5(byte[] input){
        MessageDigest md;
        try {
            md = MessageDigest.getInstance("MD5");
        }catch (Exception e){
            throw new RuntimeException(e);
        }
        md.update(input);
        return md.digest();
    }

Java加密與安全

public static void main(String[] args) throws Exception{

        String password = "helloworld";
        String salt = "Random salt";
        byte[] bytes = toMD5((salt+password).getBytes("UTF-8"));
        //以16進制的方式,打印出byte數組
        System.out.println(String.format("%032x",new BigInteger(1,bytes)));
    }
    public static byte[] toMD5(byte[] input){
        MessageDigest md;
        try {
            md = MessageDigest.getInstance("MD5");
        }catch (Exception e){
            throw new RuntimeException(e);
        }
        md.update(input);
        return md.digest();
    }

Java加密與安全


2、SHA-1

  • 也是一種哈希算法
  • 輸出160bits / 20 bytes
  • 美國國家安全局開發
  • SHA-0/SHA-1/SHA-256/SHA-512

Java加密與安全
例子:同md5
Java加密與安全

public static void main(String[] args) throws Exception{

        String str = "MD5摘要算法測試";
        byte[] bytes = toMD5(str.getBytes("UTF-8"));
        //因爲SHA-1輸出是40個字節,因此用%040x來表示輸出
        System.out.println(String.format("%040x",new BigInteger(1,bytes)));
    }
    public static byte[] toMD5(byte[] input){
        MessageDigest md;
        try {
            md = MessageDigest.getInstance("SHA-1");
        }catch (Exception e){
            throw new RuntimeException(e);
        }
        md.update(input);
        return md.digest();
    }

jdk並未包含RipeMD160算法,須要單獨下載jar包放入jdk中


3、BouncyCastle

  • 第三方提供的一組加密/哈希算法
  • 提供JDK沒有提供的算法 ,例如:RipeMD160哈希算法

如何使用第三方提供的算法?

  • 添加第三方jar至classpath
  • 註冊第三方算法提供方
  • 正常使用JDK提供的接口

Java加密與安全


4、Hmac
Hmac:Hash-based Message Authentication Code

  • 基於密鑰的消息認證碼算法
  • 更安全的消息摘要算法
    HmacMD5能夠看作帶安全Salt的MD5
    Java加密與安全

    public class Hmac {
    
    public static byte[] hmac(String hmacAlgorithm, SecretKey skey,byte[] input)throws Exception{
        Mac mac = Mac.getInstance(hmacAlgorithm);
        mac.init(skey);
        mac.update(input);
        return mac.doFinal();
    }
    
    public static void main(String[] args) throws Exception {
        String algorithm = "HmacSHA1";
        //String algorithm = "HmacSHA256";
        //原始數據
        String data = "hello world";
        //隨機生成一個key
        KeyGenerator keyGen = KeyGenerator.getInstance(algorithm);
        SecretKey skey = keyGen.generateKey();
        //打印key
        byte[] key = skey.getEncoded();
        BigInteger bigInteger = new BigInteger(1, key);
        System.out.println("Key:"+bigInteger.toString(key.length/2));
        //用這個key計算
        byte[] result = hmac(algorithm,skey,data.getBytes("UTF-8"));
        BigInteger resultInteger = new BigInteger(1, result);
        System.out.println("Hash:"+resultInteger.toString(result.length/2));
    }
    }

    Java加密與安全

總結:

  • Hmac並非從新發明的一種算法,而是把Key混入摘要的算法
  • 能夠配合MD五、SHA-1等摘要算法
  • 摘要長度和原摘要算法長度相同

    4、對稱加密算法

    一.什麼是對稱加密算法

  • 加密和解密使用同一個密鑰,例如:WinRAR
    Java加密與安全

2、經常使用的加密算法
Java加密與安全
它們的密鑰長度各不相同,密鑰長度決定了加密的強度。工做模式和填充模式能夠看作是加密算法的參數和格式的選擇,jdk提供的算法並無提供全部的工做模式及填充模式。
des算法由於密鑰果斷能夠在短期內暴力破解,已經被淘汰

相關文章
相關標籤/搜索