密码学之常见加密方式(05)

举报
海拥 发表于 2021/11/25 16:52:23 2021/11/25
【摘要】 🌊 作者主页:海拥🌊 简介:🏆CSDN全栈领域优质创作者、🥇HDZ核心组成员、🥈蝉联C站周榜前十🌊 粉丝福利:粉丝群 每周送六本书,不定期送各种小礼品 常见加密方式@TOC 前言提示:这里可以添加本文要记录的大概内容:例如:随着人工智能的不断发展,机器学习这门技术也越来越重要,很多人都开启了学习机器学习,本文就介绍了机器学习的基础内容。提示:以下是本篇文章正文内容,下面案例可供参...

🌊 作者主页:海拥
🌊 简介:🏆CSDN全栈领域优质创作者、🥇HDZ核心组成员、🥈蝉联C站周榜前十
🌊 粉丝福利:粉丝群 每周送六本书,不定期送各种小礼品

常见加密方式

在这里插入图片描述


@TOC


前言

提示:这里可以添加本文要记录的大概内容:
例如:随着人工智能的不断发展,机器学习这门技术也越来越重要,很多人都开启了学习机器学习,本文就介绍了机器学习的基础内容。


提示:以下是本篇文章正文内容,下面案例可供参考

一、对称加密

  • 采用单钥密码系统的加密方法,同一个密钥可以同时用作信息的加密和解密,这种加密方法称为对称加密,也称为单密钥加密。
  • 示例
    我们现在有一个原文3要发送给B
    设置密钥为108, 3 * 108 = 324, 将324作为密文发送给B
    B拿到密文324后,使用324/108 = 3 得到原文
  • 常见加密算法
    ==DES== : Data Encryption Standard,即数据加密标准,是一种使用密钥加密的块算法,1977年被美国联邦政府的国家标准局确定为联邦资料处理标准(FIPS),并授权在非密级政府通信中使用,随后该算法在国际上广泛流传开来。
    ==AES== : Advanced Encryption Standard, 高级加密标准,在密码学中又称Rijndael加密法,是美国联邦政府采用的一种区块加密标准。这个标准用来替代原先的DES,已经被多方分析且广为全世界所使用。
  • 特点
    1.加密速度快, 可以加密大文件
    2.密文可逆, 一旦密钥文件泄漏, 就会导致数据暴露
    3.加密后编码表找不到对应字符, 出现乱码
    4.一般结合Base64使用

二、DES加密

示例代码 des加密算法

Cipher :文档

https://docs.oracle.com/javase/8/docs/api/javax/crypto/Cipher.html#getInstance-java.lang.String

代码如下(示例):

package com.atguigu.desaes;

import javax.crypto.Cipher;
import javax.crypto.spec.SecretKeySpec;

/**
 * @author JsonHao😋
 * @date 2020年9月11日 下午8:58:47
 */
public class DesAesDemo {
	public static void main(String[] args) throws Exception{
        // 原文
        String input = "硅谷";
        // des加密必须是8位
        String key = "123456";
        // 算法
        String algorithm = "DES";

        String transformation = "DES";
        // Cipher:密码,获取加密对象
        // transformation:参数表示使用什么类型加密
        Cipher cipher = Cipher.getInstance(transformation);
        // 指定秘钥规则
        // 第一个参数表示:密钥,key的字节数组
        // 第二个参数表示:算法
        SecretKeySpec sks = new SecretKeySpec(key.getBytes(), algorithm);
        // 对加密进行初始化
        // 第一个参数:表示模式,有加密模式和解密模式
        // 第二个参数:表示秘钥规则
        cipher.init(Cipher.ENCRYPT_MODE,sks);
        // 进行加密
        byte[] bytes = cipher.doFinal(input.getBytes());
        // 打印字节,因为ascii码有负数,解析不出来,所以乱码
//        for (byte b : bytes) {
//            System.out.println(b);
//        }
        // 打印密文
        System.out.println(new String(bytes));
    }
}

在这里插入图片描述
密钥是6个字节,DES加密算法规定,密钥key必须是8个字节,所以需要修改上面key,改成key=“12345678”

修改 密钥 key = “12345678” ,再次运行 ,出现乱码是因为对应的字节出现负数,但负数,没有出现在 ascii 码表里面,所以出现乱码,需要配合base64进行转码
在这里插入图片描述
使用 base64 进行编码

base64导包的时候,需要注意 ,别导错了,需要导入 apache 包
在这里插入图片描述

在这里插入图片描述
运行程序:
在这里插入图片描述

三、DES解密

idea中使用 ctrl + alt + m 快捷键抽取代码

package com.atguigu.desaes;

import com.sun.org.apache.xml.internal.security.utils.Base64;

import javax.crypto.Cipher;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
/**
 * @author JsonHao😋
 * @date 2020年9月11日 下午9:22:52
 */
public class DesDemo {
    // DES加密算法,key的大小必须是8个字节

    public static void main(String[] args) throws Exception {
        String input ="硅谷";
        // DES加密算法,key的大小必须是8个字节
        String key = "12345678";

        String transformation = "DES"; // 9PQXVUIhaaQ=
        // 指定获取密钥的算法
        String algorithm = "DES";
        String encryptDES = encryptDES(input, key, transformation, algorithm);
        System.out.println("加密:" + encryptDES);
        String s = decryptDES(encryptDES, key, transformation, algorithm);
        System.out.println("解密:" + s);

    }

    /**
     * 使用DES加密数据
     *
     * @param input          : 原文
     * @param key            : 密钥(DES,密钥的长度必须是8个字节)
     * @param transformation : 获取Cipher对象的算法
     * @param algorithm      : 获取密钥的算法
     * @return : 密文
      * @throws Exception
      */
    private static String encryptDES(String input, String key, String transformation, String algorithm) throws Exception {
        // 获取加密对象
        Cipher cipher = Cipher.getInstance(transformation);
        // 创建加密规则
        // 第一个参数key的字节
        // 第二个参数表示加密算法
        SecretKeySpec sks = new SecretKeySpec(key.getBytes(), algorithm);
        // ENCRYPT_MODE:加密模式
        // DECRYPT_MODE: 解密模式
        // 初始化加密模式和算法
        cipher.init(Cipher.ENCRYPT_MODE,sks);
        // 加密
        byte[] bytes = cipher.doFinal(input.getBytes());

        // 输出加密后的数据
        String encode = Base64.encode(bytes);

         return encode;
     }

    /**
     * 使用DES解密
     *
     * @param input          : 密文
     * @param key            : 密钥
     * @param transformation : 获取Cipher对象的算法
     * @param algorithm      : 获取密钥的算法
     * @throws Exception
     * @return: 原文
     */
    private static String decryptDES(String input, String key, String transformation, String algorithm) throws Exception {
        // 1,获取Cipher对象
        Cipher cipher = Cipher.getInstance(transformation);
        // 指定密钥规则
        SecretKeySpec sks = new SecretKeySpec(key.getBytes(), algorithm);
        cipher.init(Cipher.DECRYPT_MODE, sks);
        // 3. 解密,上面使用的base64编码,下面直接用密文
        byte[] bytes = cipher.doFinal(Base64.decode(input));
        //  因为是明文,所以直接返回
        return new String(bytes);
    }
}

运行程序:在这里插入图片描述

Base64 算法简介

Base64是网络上最常见的用于传输8Bit字节码的可读性编码算法之一
可读性编码算法不是为了保护数据的安全性,而是为了可读性
可读性编码不改变信息内容,只改变信息内容的表现形式
所谓Base64,即是说在编码过程中使用了64种字符:大写AZ、小写a到z、数字09、“+”和“/Base58Bitcoin(比特币)中使用的一种编码方式,主要用于产生Bitcoin的钱包地址
相比Base64Base58不使用数字"0",字母大写"O",字母大写"I",和字母小写"i",以及"+""/"符号

Base64 算法原理

base64 是 3个字节为一组,一个字节 8位,一共 就是24位 ,然后,把3个字节转成4组,每组6位,

3 * 8 = 4 * 6 = 24 ,每组6位,缺少的2位,会在高位进行补0 ,这样做的好处在于 ,base取的是后面6位,去掉高2位 ,那么base64的取值就可以控制在0-63位了,所以就叫base64,111 111 = 32 + 16 + 8 + 4 + 2 + 1 =

Base64 构成原则

① 小写 a - z = 26个字母

② 大写 A - Z = 26个字母

③ 数字 0 - 9 = 10 个数字

④ + / = 2个符号

大家可能发现一个问题,咱们的base64有个 = 号,但是在映射表里面没有发现 = 号 , 这个地方需要注意,等号非常特殊,因为base64是三个字节一组 ,如果当我们的位数不够的时候,会使用等号来补齐
在这里插入图片描述

四、base64补等号测试

package com.atguigu;
import com.sun.org.apache.xml.internal.security.utils.Base64;


/**
 * @author JsonHao😋
 * @date 2020年9月11日 下午9:30:20
 */
public class TestBase64 {
	public static void main(String[] args) {
        //  1:MQ== 表示一个字节,不够三个字节,所以需要后面通过 == 号补齐
        System.out.println(Base64.encode("1".getBytes()));
        System.out.println(Base64.encode("12".getBytes()));
        System.out.println(Base64.encode("123".getBytes()));
//        // 硅谷:中文占6个字节,6 * 8 = 48 ,刚刚好被整除,所以没有等号
        System.out.println(Base64.encode("硅谷".getBytes()));
    }
}

运行:
在这里插入图片描述

五、AES加密解密

AES 加密解密和 DES 加密解密代码一样,只需要修改加密算法就行,拷贝 ESC 代码

package com.atguigu.desaes;
import com.sun.org.apache.xml.internal.security.utils.Base64;

import javax.crypto.Cipher;
import javax.crypto.spec.SecretKeySpec;

/**
 * @author JsonHao😋
 * @date 2020年9月11日 下午9:34:48
 */
public class AesDemo {
    // DES加密算法,key的大小必须是8个字节

    public static void main(String[] args) throws Exception {
        String input ="硅谷";
        // AES加密算法,比较高级,所以key的大小必须是16个字节
        String key = "1234567812345678";

        String transformation = "AES"; // 9PQXVUIhaaQ=
        // 指定获取密钥的算法
        String algorithm = "AES";
        // 先测试加密,然后在测试解密
        String encryptDES = encryptDES(input, key, transformation, algorithm);
        System.out.println("加密:" + encryptDES);
        String s = dncryptDES(encryptDES, key, transformation, algorithm);
        System.out.println("解密:" + s);

    }

    /**
     * 使用DES加密数据
     *
     * @param input          : 原文
     * @param key            : 密钥(DES,密钥的长度必须是8个字节)
     * @param transformation : 获取Cipher对象的算法
     * @param algorithm      : 获取密钥的算法
     * @return : 密文
     * @throws Exception
     */
    private static String encryptDES(String input, String key, String transformation, String algorithm) throws Exception {
        // 获取加密对象
        Cipher cipher = Cipher.getInstance(transformation);
        // 创建加密规则
        // 第一个参数key的字节
        // 第二个参数表示加密算法
        SecretKeySpec sks = new SecretKeySpec(key.getBytes(), algorithm);
        // ENCRYPT_MODE:加密模式
        // DECRYPT_MODE: 解密模式
        // 初始化加密模式和算法
        cipher.init(Cipher.ENCRYPT_MODE,sks);
        // 加密
        byte[] bytes = cipher.doFinal(input.getBytes());

        // 输出加密后的数据
        String encode = Base64.encode(bytes);

        return encode;
    }

    /**
     * 使用DES解密
     *
     * @param input          : 密文
     * @param key            : 密钥
     * @param transformation : 获取Cipher对象的算法
     * @param algorithm      : 获取密钥的算法
     * @throws Exception
     * @return: 原文
     */
    private static String dncryptDES(String input, String key, String transformation, String algorithm) throws Exception {
        // 1,获取Cipher对象
        Cipher cipher = Cipher.getInstance(transformation);
        // 指定密钥规则
        SecretKeySpec sks = new SecretKeySpec(key.getBytes(), algorithm);
        cipher.init(Cipher.DECRYPT_MODE, sks);
        // 3. 解密
        byte[] bytes = cipher.doFinal(Base64.decode(input));

        return new String(bytes);
    }
}

运行程序:AES 加密的密钥key , 需要传入16个字节
在这里插入图片描述

六、toString()与new String ()用法区别

举例子

package com.atguigu;


import com.sun.org.apache.xerces.internal.impl.dv.util.Base64;


public class TestBase64 {
    public static void main(String[] args) {
        String str="TU0jV0xBTiNVYys5bEdiUjZlNU45aHJ0bTdDQStBPT0jNjQ2NDY1Njk4IzM5OTkwMDAwMzAwMA==";


        String rlt1=new String(Base64.decode(str));

        String rlt2=Base64.decode(str).toString();

        System.out.println(rlt1);

        System.out.println(rlt2);
    }
}

运行结果是:

MM#WLAN#Uc+9lGbR6e5N9hrtm7CA+A==#646465698#399900003000

[B@1540e19d

哪一个是正确的?为什么?

这里应该用new String()的方法,因为Base64加解密是一种转换编码格式的原理

toString()与new String ()用法区别

str.toString是调用了这个object对象的类的toString方法。一般是返回这么一个String:[class name]@[hashCode]

new String(str)是根据parameter是一个字节数组,使用java虚拟机默认的编码格式,将这个字节数组decode为对应的字符。若虚拟机默认的编码格式是ISO-8859-1,按照ascii编码表即可得到字节对应的字符。

什么时候用什么方法呢?

new String()一般使用字符转码的时候,byte[]数组的时候

toString()对象打印的时候使用


未完待续。。。
【版权声明】本文为华为云社区用户原创内容,转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息, 否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。