程序中的加密和解密---現代密碼學--相關知識概念

1. 密碼學基本概念

密碼學習其實就是將明文進行加密的過程,在這個過程中需要防止別人篡改,攔截解密等。古代也有密碼學的概念,下面主要將解現代密碼學;

2.現代密碼學

① 散列函數

散列函數,也見雜湊函數、摘要函數或哈希函數,可將任意長度的消息經過運算,變成固定長度數值,常見的有MD5SHA-1SHA256,多應用在文件校驗,數字簽名中。

  • MD5 可以將任意長度的原文生成一個128位(16字節)的哈希值
  • SHA-1可以將任意長度的原文生成一個160位(20字節)的哈希值

② 對稱密碼

對稱密碼應用了相同的加密密鑰和解密密鑰。對稱密碼分爲:序列密碼(流密碼),分組密碼(塊密碼)兩種。流密碼是對信息流中的每一個元素(一個字母或一個比特)作爲基本的處理單元進行加密,塊密碼是先對信息流分塊,再對每一塊分別加密。

例如原文爲1234567890,流加密即先對1進行加密,再對2進行加密,再對3進行加密……最後拼接成密文;塊加密先分成不同的塊,如1234成塊,5678成塊,90XX(XX爲補位數字)成塊,再分別對不同塊進行加密,最後拼接成密文。前文提到的古典密碼學加密方法,都屬於流加密。

③ 非對稱密碼

對稱密碼的密鑰安全極其重要,加密者和解密者需要提前協商密鑰,並各自確保密鑰的安全性,一但密鑰泄露,即使算法是安全的也無法保障原文信息的私密性。在實際的使用中,遠程的提前協商密鑰不容易實現,即使協商好,在遠程傳輸過程中也容易被他人獲取,因此非對稱密鑰此時就凸顯出了優勢。

非對稱密碼有兩支密鑰,公鑰(publickey)和私鑰(privatekey),加密和解密運算使用的密鑰不同。用公鑰對原文進行加密後,需要由私鑰進行解密;用私鑰對原文進行加密後(此時一般稱爲簽名),需要由公鑰進行解密(此時一般稱爲驗籤)。公鑰可以公開的,大家使用公鑰對信息進行加密,再發送給私鑰的持有者,私鑰持有者使用私鑰對信息進行解密,獲得信息原文。因爲私鑰只有單一人持有,因此不用擔心被他人解密獲取信息原文。

2 ASCII編碼

ASCII(American Standard Code for Information Interchange,美國信息交換標準代碼)是基於拉丁字母的一套電腦編碼系統,主要用於顯示現代英語和其他西歐語言。它是現今最通用的單字節編碼系統,並等同於國際標準ISO/IEC 646。

.Logo

字符轉換成ascii碼

public class AsciiDemo {

    public static void main(String[] args) {
        char a = 'A';
        int b = a;
        // 打印ascii碼
        System.out.println(b);
    }
}

運行程序

注意:這個列子主要用來描述字符轉int的類型時時候根據ascll碼來的。 


Byte和bit (字節和位之間的關係)

byte : 字節. 數據存儲的基本單位,比如移動硬盤1T , 單位是byte

bit : 比特, 又叫位. 一個位要麼是0要麼是1. 數據傳輸的單位 , 比如家裏的寬帶100MB,下載速度並沒有達到100MB,一般都是12-13MB,那麼是因爲需要使用 100 / 8

關係: 1Byte = 8bit 

注意:byte(字節)是描述數據存儲的單位,而bit(位)是描述數據傳輸的單位。

1.5.1 獲取字符串byte

public class ByteBit {
    public static void main(String[] args) {
        String a = "a";
        byte[] bytes = a.getBytes();
        for (byte b : bytes) {
            int c=b;
            // 打印發現byte實際上就是ascii碼
            System.out.println(c);
        }
    }
}

 運行程序

1584441334957

1.5.2 byte對應bit

public class ByteBit {
    public static void main(String[] args) {
        String a = "a";
        byte[] bytes = a.getBytes();
        for (byte b : bytes) {
            int c=b;
            // 打印發現byte實際上就是ascii碼
            System.out.println(c);
            // 我們在來看看每個byte對應的bit,byte獲取對應的bit
            String s = Integer.toBinaryString(c);
            System.out.println(s);
        }
    }
}

 運行程序

打印出來應該是8個bit,但前面是0,沒有打印 ,從打印結果可以看出來,一個英文字符 ,佔一個字節

1584441490479

1.5.3 中文對應的字節  (中文在GBK編碼下, 佔據2個字節   中文在UTF-8編碼下, 佔據3個字節)

// 中文在GBK編碼下, 佔據2個字節
// 中文在UTF-8編碼下, 佔據3個字節

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

        String a = "尚";
        byte[] bytes = a.getBytes();
        for (byte b : bytes) {
            System.out.print(b + "   ");
            String s = Integer.toBinaryString(b);
            System.out.println(s);
        }
    }
    
    
}

 運行程序:我們發現一箇中文是有 3 個字節組成

1586689495419

我們修改 編碼格式 , 編碼格式改成 GBK ,我們在運行發現變成了 2 個字節

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

        String a = "尚";

        // 在中文情況下,不同的編碼格式,對應不同的字節
       //GBK :編碼格式佔2個字節
       // UTF-8:編碼格式佔3個字節
        byte[] bytes = a.getBytes("GBK");
       // byte[] bytes = a.getBytes("UTF-8");
        for (byte b : bytes) {
            System.out.print(b + "   ");
            String s = Integer.toBinaryString(b);
            System.out.println(s);
        }
    }

 1.5.4 英文對應的字節  (英文在不同的編碼格式中是一致的,中文在編碼格式是UTF-8的格式中是三個字節)

我們在看看英文,在不同的編碼格式佔用多少字節 

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

        String a = "A";
        byte[] bytes = a.getBytes();
        // 在中文情況下,不同的編碼格式,對應不同的字節
//        byte[] bytes = a.getBytes("GBK");
        for (byte b : bytes) {
            System.out.print(b + "   ");
            String s = Integer.toBinaryString(b);
            System.out.println(s);
        }
    }
}

 運行程序

1586690247699

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 


 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章