程序中的加密和解密---现代密码学--相关知识概念

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

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 


 

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