IFMMP 按照英文順序往后移動一位 替代密碼:HELLO =>p12,5,3 或者是用某一本書..."/>
溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務(wù)條款》

Java加密與安全

發(fā)布時間:2020-05-15 09:30:14 來源:網(wǎng)絡(luò) 閱讀:306 作者:mazongfei 欄目:軟件技術(shù)

一、簡介

數(shù)據(jù)安全

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

這些都是靠人的想象和直覺來涉及的,非常不靠譜,而現(xiàn)代計算機加密:

  • 建立在嚴(yán)格的數(shù)據(jù)理論基礎(chǔ)上
  • 密碼學(xué)逐漸發(fā)展成一門學(xué)科

總結(jié)

  • 設(shè)計一個安全的加密算法非常困難
  • 驗證一個加密算法是否安全更加困難
  • 當(dāng)前被認(rèn)為安全的加密算法僅僅是迄今為止尚未被攻破
  • 不要 自己設(shè)計加密算法
  • 不要 自己實現(xiàn)加密算法
  • 不要 自己修改已有的加密算法

二、URL編碼

一、什么是URL編碼?
URL編碼是瀏覽器發(fā)送數(shù)據(jù)給服務(wù)器時使用的編碼。

  • 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編碼規(guī)則是什么?

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

例子

/**
 * URL編碼
 */
public class SecURL {
    public static void main(String[] args) throws UnsupportedEncodingException {
        String original = "URL 參數(shù)";
        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加密與安全

總結(jié)

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

二、Base64編碼
* 什么是Base64編碼?
是一種把二進制數(shù)據(jù)用文本表示的編碼算法,例如: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,+/=)表示二進制內(nèi)容的方式
  • 適用于文本協(xié)議
  • 效率下降
    因為二進制經(jīng)過base64編碼它的長度會增加三分之一,如果數(shù)組的長度不是3的整數(shù)倍,末尾補0x00或0x00 0x00
    編碼后加=表示補充了1個字節(jié)
    編碼后加==表示補充了2個字節(jié)
    應(yīng)用
  • 電子郵件協(xié)議
/**
 * Base64編碼
 */
public class SecBase64 {

    public static void main(String[] args) throws Exception {
        String original = "Hello\u00ff編碼測試";
        //withoutPadding()可以去掉編碼后“=”這個字節(jié),有沒有=對于解碼來說沒有影響
        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加密與安全
由于標(biāo)準(zhǔn)的base64在url中會引起沖突,所以在url中使用base64編碼會使用另外一種。
Java加密與安全
在java中,使用url的base64編碼它會把“+”變?yōu)椤?”,把“/"變?yōu)椤癬”這樣在傳遞url參數(shù)的時候不會引起沖突

總結(jié)

  • Base64是編碼算法,不是加密算法
  • Base64編碼的目的是把任意二進制數(shù)據(jù)編碼為文本(長度增加1/3)
  • 其他編碼:Base32、Base48、Base58

三、摘要算法

一、什么是摘要算法?
摘要算法是一種能產(chǎn)生特殊輸出格式的算法,這種算法的特點是:無論用戶輸入多少長度的原始數(shù)據(jù),經(jīng)過計算后輸出的密文都是固定長度的,只要原數(shù)據(jù)稍有改變,輸出的“摘要”便完全不同,因此,基于這種原理的算法便能對數(shù)據(jù)完整性提供較為健全的保障。
? ? ? ? 常用的摘要算法主要有MD5和SHA1。D5的輸出結(jié)果為16字節(jié)(128位),SHA1的輸出結(jié)果為20字節(jié)(160位)。
摘要算法(又稱哈希算法/數(shù)字指紋)
* 計算任意成都數(shù)據(jù)的摘要(固定長度)

  • 相同的輸入數(shù)據(jù)始終得到相同的輸出
  • 不同的輸入數(shù)據(jù)盡量得到不同的輸出

目的:

  • 驗證原始數(shù)據(jù)是否被篡改

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

Java的Object.hashCode()方法就是一個摘要算法
這就是說相同的輸入必須得到相同的輸出,當(dāng)我們重新equals()方法的時候也要同時重新hashCode()方法


什么是碰撞?
兩個不同的輸入得到了相同的輸出
例如:
hash("abc") = 0x12345678
hash("xyz") = 0x12345678
這個時候我們就說發(fā)生了碰撞,碰撞能不能呢,碰撞是不能避免的。
輸出的字節(jié)是固定的,而輸入的字節(jié)是不確定的

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

Hash算法的安全性?

  • 碰撞率低
  • 不能猜測輸出
  • 輸入任意一個bit的變化都會造成完全不同的輸出
  • 很難從輸出反推出輸入(只能依靠暴力窮舉)

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

彩虹表
什么是彩虹表呢?是一個預(yù)先計算好的常用的字符和md5的一個對照表。
抵御彩虹表

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

        String str = "MD5摘要算法測試";
        byte[] bytes = toMD5(str.getBytes("UTF-8"));
        //以16進制的方式,打印出byte數(shù)組
        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數(shù)組
        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加密與安全


二、SHA-1

  • 也是一種哈希算法
  • 輸出160bits / 20 bytes
  • 美國國家安全局開發(fā)
  • 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個字節(jié),所以用%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中


三、BouncyCastle

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

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

  • 添加第三方j(luò)ar至classpath
  • 注冊第三方算法提供方
  • 正常使用JDK提供的接口

Java加密與安全


四、Hmac
Hmac:Hash-based Message Authentication Code

  • 基于密鑰的消息認(rèn)證碼算法
  • 更安全的消息摘要算法
    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";
        //原始數(shù)據(jù)
        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加密與安全

總結(jié):

  • Hmac并不是重新發(fā)明的一種算法,而是把Key混入摘要的算法
  • 可以配合MD5、SHA-1等摘要算法
  • 摘要長度和原摘要算法長度相同

    四、對稱加密算法

    一.什么是對稱加密算法

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

二、常用的加密算法
Java加密與安全
它們的密鑰長度各不相同,密鑰長度決定了加密的強度。工作模式和填充模式可以看做是加密算法的參數(shù)和格式的選擇,jdk提供的算法并沒有提供所有的工作模式及填充模式。
des算法因為密鑰果斷可以在短時間內(nèi)暴力破解,已經(jīng)被淘汰

向AI問一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進行舉報,并提供相關(guān)證據(jù),一經(jīng)查實,將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI