目录
  • 一、凯撒加密
  • 二、Base64
  • 三、信息摘要算法(MD5 或 SHA)
  • 四、对称加密(Des,Triple Des,AES)
  • 五、非对称加密
    • 1.生成公钥和私钥文件
    • 2.使用RSA进行加密、解密
  • 六、查看系统支持的算法
    • 总结

      一、凯撒加密

      在密码学中,凯撒加密是一种最简单且最广为人知的加密技术。它是一种替换加密的技术,明文中的所有字母都在字母表上向后(或向前)按照一个固定数目进行偏移后被替换成密文。这个加密方法是以罗马共和时期恺撒的名字命名的,当年恺撒曾用此方法与其将军们进行联系。

      public class caesarCipher {
          public static void main(String[] args) {
              String show = "ABCDEFGHIJKLMNOPQRSTUVWXYZ~~";
              int key = 3;
              String ciphertext = encryption(show, key, true);
              System.out.println(ciphertext);
              String showText = encryption(ciphertext, key, false);
              System.out.println(showText);
          }
          /**
           * @param text 明文/密文
           * @param key  位移
           * @param mode 加密/解密  true/false
           * @return 密文/明文
           */
          private static String encryption(String text, int key, boolean mode) {
              char[] chars = text.toCharArray();
              StringBuffer sb = new StringBuffer();
              for (char aChar : chars) {
                  int a = mode ? aChar + key : aChar - key;
                  char newa = (char) a;
                  sb.append(newa);
              }
              return sb.toString();
          }
      }

      明文字母表:ABCDEFGHIJKLMNOPQRSTUVWXYZ~~

      密文字母表:DEFGHIJKLMNOPQRSTUVWXYZ[\]

      注意:当字符的ASCII码  +  偏移量  >  127,密文转化出来会乱码,~(波浪号):126+3=129

      二、Base64

      Base64是网络上最常见的用于传输8Bit字节码的编码方式之一,Base64就是一种基于64个可打印字符来表示二进制数据的方法。

       base64 :  A-Z  a-z   0-9  +  /

      Base64要求把每三个8Bit的字节转换为四个6Bit的字节(3*8 = 4*6 = 24),然后把6Bit再添两位高位0,组成四个8Bit的字节,也就是说,转换后的字符串理论上将要比原来的长1/3。

      import com.sun.org.apache.xml.internal.security.exceptions.Base64DecodingException;
      import com.sun.org.apache.xml.internal.security.utils.Base64;
      import java.nio.charset.StandardCharsets;
      public class base64Demo {
          public static void main(String[] args) throws Base64DecodingException {
              //MQ==   一个字节补两个=
              System.out.println(Base64.encode("1".getBytes(StandardCharsets.UTF_8)));
              //MTE=   两个字节补一个=
              System.out.println(Base64.encode("11".getBytes(StandardCharsets.UTF_8)));
              //MTEx
              System.out.println(Base64.encode("111".getBytes(StandardCharsets.UTF_8)));
              //解密11
              System.out.println(new String(Base64.decode("MTE=")));
          }
      }

      三、信息摘要算法(MD5 或 SHA)

      信息摘要是安全的单向哈希函数,它接收任意大小的数据,并输出固定长度的哈希值。

      import com.alibaba.fastjson.JSON;
      import com.sun.org.apache.xml.internal.security.utils.Base64;
      import java.nio.charset.StandardCharsets;
      import java.security.MessageDigest;
      import java.security.NoSuchAlgorithmException;
      import java.util.HashMap;
      //信息摘要是安全的单向哈希函数,它接收任意大小的数据,并输出固定长度的哈希值。
      public class DigestDemo {
          /**
           * @param input     明文
           * @param algorithm 算法  MD5 | sha-1 SHA-256 |
           * @return 密文  Base64 & Hex
           */
          private static String toHexOrBase64(String input, String algorithm) throws NoSuchAlgorithmException {
              MessageDigest digest = MessageDigest.getInstance(algorithm);
              byte[] digest1 = digest.digest(input.getBytes(StandardCharsets.UTF_8));
              String base64 = Base64.encode(digest1);
              StringBuffer haxValue = new StringBuffer();
              for (byte b : digest1) {
                  //0xff是16进制数,这个刚好8位都是1的二进制数,而且转成int类型的时候,高位会补0
                  int val = ((int) b) & 0xff;//只取得低八位
                  //在&正数byte值的话,对数值不会有改变 在&负数数byte值的话,对数值前面补位的1会变成0,
                  if (val < 16) {
                      haxValue.append("0");//位数不够,高位补0
                  }
                  haxValue.append(Integer.toHexString(val));
              }
              HashMap<String, String> DigestMap = new HashMap<>();
              DigestMap.put("Base64", base64);
              DigestMap.put("Hex", String.valueOf(haxValue));
              return JSON.toJSONString(DigestMap);
          }
      }

      加密原文:123456

      算法 Base64

      MD5

      4QrcOUm6Wau+VuBX8g+IPg==

      sha-1

      fEqNCco3Yq9h5ZUglD3CZJT4lBs=

      sha-256

      jZae727K08KaOmKSgOaGzww/XVqGr/PKEgIMkjrcbJI=

      四、对称加密(Des,Triple Des,AES)

      采用单钥密码系统的加密方法,同一个密钥可以同时用作信息的加密和解密,这种加密方法称为对称加密,也称为单密钥加密。常用的单向加密算法:

      • DES(Data Encryption Standard):数据加密标准,速度较快,适用于加密大量数据的场合;
      • 3DES(Triple DES):是基于DES,对一块数据用三个不同的密钥进行三次加密,强度更高;
      • AES(Advanced Encryption Standard):高级加密标准,是下一代的加密算法标准,速度快,安全级别高,支持128、192、256位密钥的加密;

      加密原文:你好世界!!

      import com.sun.org.apache.xerces.internal.impl.dv.util.Base64;
      import javax.crypto.BadPaddingException;
      import javax.crypto.Cipher;
      import javax.crypto.IllegalBlockSizeException;
      import javax.crypto.NoSuchPaddingException;
      import javax.crypto.spec.SecretKeySpec;
      import java.nio.charset.StandardCharsets;
      import java.security.InvalidKeyException;
      import java.security.NoSuchAlgorithmException;
      public class desOrAesDemo {
          public static void main(String[] args) throws Exception {
              String text = "你好世界!!";
              String key = "12345678";//des必须8字节
              // 算法/模式/填充  默认 DES/ECB/PKCS5Padding
              String transformation = "DES";
              String key1 = "1234567812345678";//aes必须16字节
              String transformation1 = "AES";
              String key2 = "123456781234567812345678";//TripleDES使用24字节的key
              String transformation2 = "TripleDes";
              String extracted = extracted(text, key, transformation, true);
              System.out.println("DES加密:" + extracted);
              String extracted1 = extracted(extracted, key, transformation, false);
              System.out.println("解密:" + extracted1);
              String extracted2 = extracted(text, key1, transformation1, true);
              System.out.println("AES加密:" + extracted2);
              String extracted3 = extracted(extracted2, key1, transformation1, false);
              System.out.println("解密:" + extracted3);
              String extracted4 = extracted(text, key2, transformation2, true);
              System.out.println("Triple Des加密:" + extracted4);
              String extracted5 = extracted(extracted, key2, transformation2, false);
              System.out.println("解密:" + extracted5);
          }
          /**
           * @param text           明文/base64密文
           * @param key            密钥
           * @param transformation 转换方式
           * @param mode           加密/解密
           */
          private static String extracted(String text, String key, String transformation, boolean mode) throws NoSuchAlgorithmException, NoSuchPaddingException, InvalidKeyException, IllegalBlockSizeException, BadPaddingException {
              Cipher cipher = Cipher.getInstance(transformation);
              //    key          与给定的密钥内容相关联的密钥算法的名称
              SecretKeySpec secretKeySpec = new SecretKeySpec(key.getBytes(), transformation);
              //Cipher 的操作模式,加密模式:ENCRYPT_MODE、 解密模式:DECRYPT_MODE、包装模式:WRAP_MODE 或 解包装:UNWRAP_MODE)
              cipher.init(mode ? Cipher.ENCRYPT_MODE : Cipher.DECRYPT_MODE, secretKeySpec);
              byte[] bytes = cipher.doFinal(mode ? text.getBytes(StandardCharsets.UTF_8) : Base64.decode(text));
              return mode ? Base64.encode(bytes) : new String(bytes);
          }
      }
      算法 密匙 密文

      DES

      12345678     8位

      j+tPzTH7ttEeK+FrJaLY8OwmOezdN8hF

      AES

      12345678*2   16位

      /+cq03JhyvrTIJyYvWwc2Dc/bFUBNKelKPSANnWgsAw=

      TripleDes

      12345678*3       24位

      j+tPzTH7ttEeK+FrJaLY8OwmOezdN8hF

      五、非对称加密

      公钥加密,也叫非对称(密钥)加密(public key encryption),属于通信科技下的网络安全二级学科,指的是由对应的一对唯一性密钥(即公开密钥和私有密钥)组成的加密方法。它解决了密钥的发布和管理问题,是商业密码的核心。在公钥加密体制中,没有公开的是私钥,公开的是公钥。常用的算法:

      RSA、ElGamal、背包算法、Rabin(Rabin的加密法可以说是RSA方法的特例)、Diffie-Hellman (D-H) 密钥交换协议中的公钥加密算法、Elliptic Curve Cryptography(ECC,椭圆曲线加密算法)。

      1.生成公钥和私钥文件

      目前JDK1.8支持 RSA、DSA、DIFFIEHELLMAN、EC

      /**
       * 生成公钥和私钥文件
       * @param algorithm   算法
       * @param privatePath 私钥路径
       * @param publicPath  公钥路径
       */    
      private static void generateKeyFile(String algorithm, String privatePath, String publicPath) throws NoSuchAlgorithmException, IOException {
              //返回生成指定算法的 public/private 密钥对的 KeyPairGenerator 对象
              KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance(algorithm);
              //生成一个密钥对
              KeyPair keyPair = keyPairGenerator.generateKeyPair();
              //私钥
              PrivateKey privateKey = keyPair.getPrivate();
              //公钥
              PublicKey publicKey = keyPair.getPublic();
              byte[] privateKeyEncoded = privateKey.getEncoded();
              byte[] publicKeyEncoded = publicKey.getEncoded();
              String privateEncodeString = Base64.encode(privateKeyEncoded);
              String publicEncodeString = Base64.encode(publicKeyEncoded);
              //需导入commons-io
              FileUtils.writeStringToFile(new File(privatePath), privateEncodeString, StandardCharsets.UTF_8);
              FileUtils.writeStringToFile(new File(publicPath), publicEncodeString, StandardCharsets.UTF_8);
      }

      2.使用RSA进行加密、解密

      package cryptography;
      import com.sun.org.apache.xml.internal.security.exceptions.Base64DecodingException;
      import com.sun.org.apache.xml.internal.security.utils.Base64;
      import org.apache.commons.io.FileUtils;
      import javax.crypto.BadPaddingException;
      import javax.crypto.Cipher;
      import javax.crypto.IllegalBlockSizeException;
      import javax.crypto.NoSuchPaddingException;
      import java.io.File;
      import java.io.IOException;
      import java.nio.charset.StandardCharsets;
      import java.security.*;
      import java.security.spec.InvalidKeySpecException;
      import java.security.spec.PKCS8EncodedKeySpec;
      import java.security.spec.X509EncodedKeySpec;
      public class RSADemo {
          public static void main(String[] args) throws Exception {
              String text = "===你好世界===";
              String algorithm = "RSA";
              PublicKey publicKey = getPublicKey(algorithm, "rsaKey/publicKey2.txt");
              PrivateKey privateKey = getPrivateKey(algorithm, "rsaKey/privateKey2.txt");
              String s = RSAEncrypt(text, algorithm, publicKey);
              String s1 = RSADecrypt(s, algorithm, privateKey);
              System.out.println(s);
              System.out.println(s1);
              //generateKeyFile("DSA","D:\\privateKey2.txt","D:\\publicKey2.txt");
          }
          /**
           * 获取公钥,key
           * @param algorithm  算法
           * @param publicPath 密匙文件路径
           * @return
           */
          private static PublicKey getPublicKey(String algorithm, String publicPath) throws IOException, NoSuchAlgorithmException, Base64DecodingException, InvalidKeySpecException {
              String publicEncodeString = FileUtils.readFileToString(new File(publicPath), StandardCharsets.UTF_8);
              //返回转换指定算法的 public/private 关键字的 KeyFactory 对象。
              KeyFactory keyFactory = KeyFactory.getInstance(algorithm);
              //此类表示根据 ASN.1 类型 SubjectPublicKeyInfo 进行编码的公用密钥的 ASN.1 编码
              X509EncodedKeySpec x509EncodedKeySpec = new X509EncodedKeySpec(Base64.decode(publicEncodeString));
              return keyFactory.generatePublic(x509EncodedKeySpec);
          }
          /**
           * 获取私钥,key
           * @param algorithm   算法
           * @param privatePath 密匙文件路径
           * @return
           */
          private static PrivateKey getPrivateKey(String algorithm, String privatePath) throws IOException, NoSuchAlgorithmException, Base64DecodingException, InvalidKeySpecException {
              String privateEncodeString = FileUtils.readFileToString(new File(privatePath), StandardCharsets.UTF_8);
              //返回转换指定算法的 public/private 关键字的 KeyFactory 对象。
              KeyFactory keyFactory = KeyFactory.getInstance(algorithm);
              //创建私钥key的规则  此类表示按照 ASN.1 类型 PrivateKeyInfo 进行编码的专用密钥的 ASN.1 编码
              PKCS8EncodedKeySpec pkcs8EncodedKeySpec = new PKCS8EncodedKeySpec(Base64.decode(privateEncodeString));
              //私钥对象
              return keyFactory.generatePrivate(pkcs8EncodedKeySpec);
          }
          /**
           * 加密
           * @param text      明文
           * @param algorithm 算法
           * @param key       私钥/密钥
           * @return 密文
           */
          private static String RSAEncrypt(String text, String algorithm, Key key) throws NoSuchAlgorithmException, NoSuchPaddingException, InvalidKeyException, IllegalBlockSizeException, BadPaddingException, NoSuchProviderException {
              Cipher cipher = Cipher.getInstance(algorithm);
              cipher.init(Cipher.ENCRYPT_MODE, key);
              byte[] bytes = cipher.doFinal(text.getBytes(StandardCharsets.UTF_8));
              return Base64.encode(bytes);
          }
          /**
           * 解密
           * @param extracted 密文
           * @param algorithm 算法
           * @param key       密钥/私钥
           * @return String 明文
           */
          private static String RSADecrypt(String extracted, String algorithm, Key key) throws NoSuchAlgorithmException, NoSuchPaddingException, InvalidKeyException, IllegalBlockSizeException, BadPaddingException, Base64DecodingException, NoSuchProviderException {
              Cipher cipher = Cipher.getInstance(algorithm);
              cipher.init(Cipher.DECRYPT_MODE, key);
              byte[] bytes1 = cipher.doFinal(Base64.decode(extracted));
              return new String(bytes1);
          }
          /**
           * 生成公钥和私钥文件
           * @param algorithm   算法
           * @param privatePath 私钥路径
           * @param publicPath  公钥路径
           */
          private static void generateKeyFile(String algorithm, String privatePath, String publicPath) throws NoSuchAlgorithmException, IOException {
              //返回生成指定算法的 public/private 密钥对的 KeyPairGenerator 对象
              KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance(algorithm);
              //生成一个密钥对
              KeyPair keyPair = keyPairGenerator.generateKeyPair();
              //私钥
              PrivateKey privateKey = keyPair.getPrivate();
              //公钥
              PublicKey publicKey = keyPair.getPublic();
              byte[] privateKeyEncoded = privateKey.getEncoded();
              byte[] publicKeyEncoded = publicKey.getEncoded();
              String privateEncodeString = Base64.encode(privateKeyEncoded);
              String publicEncodeString = Base64.encode(publicKeyEncoded);
              //需导入commons-io
              FileUtils.writeStringToFile(new File(privatePath), privateEncodeString, StandardCharsets.UTF_8);
              FileUtils.writeStringToFile(new File(publicPath), publicEncodeString, StandardCharsets.UTF_8);
          }
      }

      密文(明文:===你好世界===)  

      ZBadyYCIck2iYV8RtsY35T1GbaYt9aLS51dcws5H4IcrOH+i6/8AIEdgtwJO3p1ccqKP6XTwQAWm
      ceJ7kpsk76nvFD8Hg2pLYzH2oEE+oy07bLBdBiE+zVFkP+0DL+nrsHO4elQxc9BSslj5wGLQqbb1
      Mxh9Tcpf5zJEOxdBZvE= 

      六、查看系统支持的算法

      public static void main(String[] args) throws Exception {
              System.out.println("列出加密服务提供者:");
              Provider[] pro=Security.getProviders();
              for(Provider p:pro){
                  System.out.println("Provider:"+p.getName()+" - version:"+p.getVersion());
                  System.out.println(p.getInfo());
              }
              System.out.println("=======");
              System.out.println("列出系统支持的消息摘要算法:");
              for(String s:Security.getAlgorithms("MessageDigest")){
                  System.out.println(s);
              }
              System.out.println("=======");
              System.out.println("列出系统支持的生成公钥和私钥对的算法:");
              for(String s:Security.getAlgorithms("KeyPairGenerator")){
                  System.out.println(s);
              }
      }

      其他加密算法可以使用 Bouncy Castle Crypto包

      <dependency>
          <groupId>org.bouncycastle</groupId>
          <artifactId>bcprov-jdk15on</artifactId>
          <version>1.70</version>
      </dependency>

      总结

      声明:本站所有文章,如无特殊说明或标注,均为本站原创发布。任何个人或组织,在未征得本站同意时,禁止复制、盗用、采集、发布本站内容到任何网站、书籍等各类媒体平台。如若本站内容侵犯了原著者的合法权益,可联系我们进行处理。