密码学

概述

  • 密码学:主要是研究编制密码和破译密码得学科
  • 密码学的主要目的:研究如何隐藏信息并且把信息传递出去得的一个学科
  • 应用:网络安全、信息安全、区块链等学科的基础
  • 古典密码学 -> 类似古代史
  • 近代密码学 -> 类似近代史
  • 现代密码学 -> 类似现代史

古典密码学

核心原理:替换法、移位法

  • 替换法
    • 就是使用固定的信息,将原文替换成密文如:hello,将b替换为a,将e替换为v,将l替换为t,将o替换为y,那么hello加密之后就是:avtty
    • 第一种:单表替换
      • 原文和密文使用的是同一张表
      • 如:将原文替换成密文如:hello,将b替换为a,将e替换为v,将l替换为t,将o替换为y,那么hello加密之后就是:avtty
    • 第二种:多表替换
      • 原文和密文不是同一张表
      • 如,表1:abcde - swtrp,表2:abcde - chfhk,表3:abcde - jftou
      • 原文:bee 密钥:312
      • 加密之后:fpk
  • 移位法
    • 是按照字母,在字母表上面的位置,进行移动
    • 凯撒加密
    • 例如:abcde - cdefg 向后移动2位
  • 破解方式
    • 频度分析法破译密码,在不知道加密规则的前提下,进行破译密码
    • 通过概率论研究字母或者字母组合在文本中出现的频率
    • 密码中的频率和英文字母的频率,进行匹配,就可以解密
  • 如何设置密码才比较安全
    • 密码不要太常见
    • 各个应用软件里面的密码不要设置一样 - 撞库(破解一个软件的密码,去匹配所有软件的密码,成为撞库)
    • 在设置密码的时候,可以加一些特殊的标记,和网站相关的标记方便记忆
  • 古代密码
    • 武则天破解 ”青鹅“ 造反案 拆字加密
    • 凯撒加密
  • 解密凯撒加密:使用频度分析法进行猜测破解

近代密码学

核心原理:替换法、移位法

  • 恩尼格玛密码机(二战)
    • 核心使用的是移位法和替换法
    • 被人工智能之父图灵破解

现代密码学

散列函数

  • MD5
  • SHA-1
  • SHA-256
  • SHA512

对称加密

  • 核心原理
    • 使用的加密方式和解密方式是同一把密钥
    • 流加密 如:123345,对1、2、3、3、4、5 分别加密,然后再将其拼接起来
    • 块解密 如:123345,对123、345 一整块解密,然后拼接成密文
  • DES加密解密
  • 特点
    • 加密速度快,可以加密大文件
    • 密文不可逆,一旦密钥文件泄漏,就会导致数据泄漏
    • 加密后编码表找不到相应的字符,出现乱码
    • 一般结合Base64使用
  • 密钥key必须是8个字节
  • Base64
    • 不是加密算法,是可读性算法
    • 目的不是为了保护数据,目的是为了可读性
    • base64是由64个字符组成 大写A - Z,小写 a - z,数字 0 - 9,两个符合 + 和 /
    • base58:一般用在于比特币上
      • 和base64的区别,没有数字0,也没有字母o,没有大写字母 I 也没有小写字母 i 没有 + 和 /
    • base64原理
      • 是三个字节为一组,一个字节8位 ,一共就是24位,base64 把三个字节转换为4组,每组6位,一个字节应该是8位,缺少2位,在高位补齐,高位补0
      • 这样做的好处,base64取后面的6位,可以把base64控制到 0 ~ 63 之间
      • 11 1111 => 32 + 16 + 8 + 4 + 2 + 1 = 63
      • 在base64里面,需要设置一共是三个字节为一组,如果在输出的时候,不够三个字节,就要使用 = 进行补齐
  • AES加密解密
    • 密钥必须是16个字节
  • toString()和new String()的原理和区别
    • new String:如果在使用编码解码,使用 new String,根据参数,字节数组,使用Java虚拟机默认编码格式,会对这个字节数组进行decode。找到对应的字符 (转码的时候使用)
    • toString: 实际上调用的的Object里面的toString方法,一般的Object的toString方法,返回的是哈希值。做对象打印,使用toString,或者得到地址的时候
  • 加密模式
    • ECB(电子密码本)
      • 把一段文本进行分拆加密,使用同一个key,分别进行加密,然后组合到一起
      • 优点:可以并行处理数据
      • 缺点:同样的原文生成的是同样的密文,不能很好的保护数据
      • 同时加密,原文的一样的,加密出来的密文也是一样的
    • CBC(密码块连接)
      • 每一个明文块会给前一个密文块进行异或后,再进行加密
      • 优点:同样的原文生成的密文不一样
      • 缺点:串行处理数据
  • 填充模式
    • NoPadding(不填充)
      • 在DES加密算法下,要求原文长度必须是8byte的整倍数
      • 在AES加密算法下,要求原文长度必须是16bytes的整数倍
    • PKCS5padding
      • 数据块大小为8位,不够就补足
  • 消息摘要
    • 又称为数字摘要
    • 它是唯一一个对应一个消息或者文本的固定长度的值,由一个单向hash加密函数对消息进行作用而产生
    • 使用数字摘要生成的值是不可以篡改的,为了保证文件或者值得安全
    • 特点
      • 无论输入得消息有多长,计算出来的消息摘要的长度总是固定的,例如使用MD5算法摘要的消息有128个比特位,使用SHA-1算法摘要消息最终有160比特位的输出
      • 只要输入的消息不同,对其进行摘要之后的消息也比不相同,但是相同的输入会有相同的输出,消息摘要是单向、不可逆的

非对称加密

  • 非对称加密的特点
    • 有两把密钥,使用公钥加密,必须使用私钥解密。或者是私钥加密,必须使用公钥解密
    • 公钥和私钥是一对,叫做密钥对
  • RSA算法和ECC算法
    • RSA 以下是代码实现
  1. public class RSADemo {
  2. public static void main(String[] args) throws Exception {
  3. // 创建密钥对
  4. String algorithm = "RSA";
  5. KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance(algorithm);
  6. // 生成密钥对
  7. KeyPair keyPair = keyPairGenerator.generateKeyPair();
  8. // 生成私钥
  9. PrivateKey aPrivate = keyPair.getPrivate();
  10. // 生成公钥
  11. PublicKey aPublic = keyPair.getPublic();
  12. // 获取私钥的字节数组
  13. byte[] privateEncodedBytes = aPrivate.getEncoded();
  14. // 获取公钥的字节数组
  15. byte[] publicEncodedBytes = aPublic.getEncoded();
  16. // 使用base64 编码
  17. String privateEncoded = Base64.encode(privateEncodedBytes);
  18. String publicEncoded = Base64.encode(publicEncodedBytes);
  19. System.out.println(privateEncoded);
  20. System.out.println(publicEncoded);
  21. }
  22. }
  1. MIICdgIBADANBgkqhkiG9w0BAQEFAASCAmAwggJcAgEAAoGBALrXZxGPW9JihIKLX2FgeJ6HYy8z
  2. DQYNkKyj8crctM6AQW11XijRG997FNocgR2rfwX3vwbwJj/3zsQ1MHIPtGAuttlJZzlx9egqCqfe
  3. adL+dTVj3FGyrNR2RjKcOl4dXgkqbs0c8mjJyyJzytxaMajp6pQTjbCcoenxSTEKMdZfAgMBAAEC
  4. gYBUyh3G9UTZM8Yoq/EL8siqQIx9RfCaF5vZDMlUo1YWBFQsxT+GzGaWw3dSB+98NHB/l8+D6YWi
  5. L+YQWobyrDfRSnE6TZQkoTGiiGUveJR2GhfDYKLURmUyrlqovCW1gxoTN5W8Jc1mroq6CKzsjEwf
  6. lO/qNWVn5MPNLqictiZ5EQJBAPVbN/HQUJgLaZLvQXcBMymu7qC7yS4xJHPbI9UIkbHBBs5xasDF
  7. CJQk5tDyiiWcP+EmFAICcQYPOdnuYSeZ9xcCQQDC8loxaSZH9mSCQwFEIGRHV+weycKm0KK/uSVB
  8. HAHDeaEJHaOtykwygQjLv7fyJN/9zBLgu7liiKbcIJY1FCf5AkAL6p1B+lsft1YuU757OCyy9pMS
  9. bWxs+OgLVHZeD2d8GaLp/eowaKFtCInJVi5Ne1RC7CWGn3W71Jt7sS84zCqLAkATU3VPiq4J2kpS
  10. g5P/jfqC/BtjXfsXEH3h5dfkoYMnPsqRHcgZNYHiS9p0YHg64B74iR+h+dpCA2wPTIe3kVz5AkEA
  11. 5mnK6UbCaqUeKZzjXLGLJ1JVhGCc9QvPWHO+dO7OfPUE7yzBbqMiwTEFCijSpLDi5+qrMpYAAUZh
  12. U1e6F51ZJQ==
  13. MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQC612cRj1vSYoSCi19hYHieh2MvMw0GDZCso/HK
  14. 3LTOgEFtdV4o0RvfexTaHIEdq38F978G8CY/987ENTByD7RgLrbZSWc5cfXoKgqn3mnS/nU1Y9xR
  15. sqzUdkYynDpeHV4JKm7NHPJoycsic8rcWjGo6eqUE42wnKHp8UkxCjHWXwIDAQAB
  • 私钥加密
  1. public class RSADemo {
  2. public static void main(String[] args) throws Exception {
  3. // 创建密钥对
  4. String algorithm = "RSA";
  5. KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance(algorithm);
  6. // 生成密钥对
  7. KeyPair keyPair = keyPairGenerator.generateKeyPair();
  8. // 生成私钥
  9. PrivateKey aPrivate = keyPair.getPrivate();
  10. // 生成公钥
  11. PublicKey aPublic = keyPair.getPublic();
  12. // 获取私钥的字节数组
  13. byte[] privateEncodedBytes = aPrivate.getEncoded();
  14. // 获取公钥的字节数组
  15. byte[] publicEncodedBytes = aPublic.getEncoded();
  16. // 使用base64 编码
  17. String privateEncoded = Base64.encode(privateEncodedBytes);
  18. String publicEncoded = Base64.encode(publicEncodedBytes);
  19. // System.out.println(privateEncoded);
  20. // System.out.println(publicEncoded);
  21. // 创建加密对象
  22. Cipher cipher = Cipher.getInstance(algorithm);
  23. // 对加密初始化
  24. // 加密的模式,第二个,使用那把要是加密
  25. cipher.init(Cipher.ENCRYPT_MODE, aPrivate);
  26. // 使用私钥加密
  27. String input = "甜";
  28. byte[] bytes = cipher.doFinal(input.getBytes());
  29. System.out.println(Base64.encode(bytes));
  30. }
  31. }
  1. J0q66D3VMqllATeqBAWlZ8nJVHGz0pbjq6G9lbvawp4kzQ581QYTsDA5FsRxJWehNAVO0LEQEQ/G
  2. +bqNUD/aDr7NZruZpJ3mlGBq/tUrwjxe48v38Jcj1UFtl3N0UlJBCgCuvM09n7QPW31ouzxyRStS
  3. dH/MqwR6ryrR+hwCEA8=
  • 公钥解密
  1. public class RSADemo {
  2. public static void main(String[] args) throws Exception {
  3. // 创建密钥对
  4. String algorithm = "RSA";
  5. KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance(algorithm);
  6. // 生成密钥对
  7. KeyPair keyPair = keyPairGenerator.generateKeyPair();
  8. // 生成私钥
  9. PrivateKey aPrivate = keyPair.getPrivate();
  10. // 生成公钥
  11. PublicKey aPublic = keyPair.getPublic();
  12. // 获取私钥的字节数组
  13. byte[] privateEncodedBytes = aPrivate.getEncoded();
  14. // 获取公钥的字节数组
  15. byte[] publicEncodedBytes = aPublic.getEncoded();
  16. // 使用base64 编码
  17. String privateEncoded = Base64.encode(privateEncodedBytes);
  18. String publicEncoded = Base64.encode(publicEncodedBytes);
  19. // System.out.println(privateEncoded);
  20. // System.out.println(publicEncoded);
  21. // 创建加密对象
  22. Cipher cipher = Cipher.getInstance(algorithm);
  23. // 对加密初始化
  24. // 加密的模式,第二个,使用那把要是加密
  25. cipher.init(Cipher.ENCRYPT_MODE, aPrivate);
  26. // 使用私钥加密
  27. String input = "甜";
  28. byte[] bytes = cipher.doFinal(input.getBytes());
  29. System.out.println(Base64.encode(bytes));
  30. cipher.init(Cipher.DECRYPT_MODE,aPublic);
  31. byte[] bytes1 = cipher.doFinal(bytes);
  32. String s = new String(bytes1);
  33. System.out.println(s);
  34. }
  35. }
  1. b9C7sLQ86iO8sTDDeo0Shcw9EMiyKHmJax65Dw62r2JOcs5BtHu8IlcqD+OLNk6MHDtExxWAlbOb
  2. g3x05dITki6jJpnCxrOcNU6GaJl+bAICQpV2IWkxDYVBjdoaeD0uCSlZVrC6pxzeiqyfa8VAR2Os
  3. GckaJ59efM37UIjoP64=
  • 数字摘要
  • 数字签名和数字整数
    • 公钥数字签名,只有信息的发送者,才能产生别人无法伪造的一段数字串
  • 数字证书
  • keytool工具的使用

自己对于密码学不是很了解,这里只是做简单的介绍