【加密算法】5 种常见的摘要、加密算法

news2025/1/12 23:18:01

大家平时的工作中,可能也在很多地方用到了加密、解密,比如:

  1. 用户的密码不能明文存储,要存储加密后的密文
  2. 用户的银行卡号、身份证号之类的敏感数据,需要加密传输
  3. 还有一些重要接口,比如支付,客户端要对请求生成一个签名,服务端要对签名进行验证
  4. ……

那么上面提到的这些能力,我们都可以利用哪些加密算法来实现呢?咱们接着往下看。

加密算法整体上可以分为:不可逆加密、可逆加密。可逆加密又可以分为:对称加密、非对称加密。
在这里插入图片描述

1.不可逆算法

不可逆加密的算法的加密是不可逆的,密文无法被还原成原文。

散列算法,就是一种不可逆算法。散列算法中,明文通过散列算法生成散列值,散列值是长度固定的数据,和明文长度无关;常用于数字签名、消息认证、密码存储等场景;不需要密钥的,当然也有一些不可逆算法,需要密钥,例如 HMAC 算法。

散列算法的具体实现有很多种,常见的包括 MD5SHA1SHA-224SHA-256 等等。

1.1 MD5

MD5,全称为 “Message-Digest Algorithm 5”,翻译过来叫“信息摘要算法”。它可以将任意长度的数据通过散列算法,生成一个固定长度的散列值。MD5算法的输出长度为 128 位,通常用 32 个 16 进制数表示

public class Md5Util {

    private static final String[] hexDigits = new String[]{"0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "a", "b", "c", "d", "e", "f"};

    /**
     * 获取MD5加密结果
     *
     * @param plainText   要加密的原字符串
     * @param uppercase   是否转为大写字符串
     * @param bit         加密结果位数(16,32),默认是32
     * @return 返回加密结果
     */
    public static String encrypt(String plainText, boolean uppercase, Integer bit) {
        byte[] btInput = plainText.getBytes(StandardCharsets.UTF_8);
        MessageDigest messageDigest;
        try {
            //获得MD5摘要对象
            messageDigest = MessageDigest.getInstance("MD5");
            //使用指定的字节数组更新摘要信息
            messageDigest.update(btInput);
        } catch (NoSuchAlgorithmException e) {
            throw new RuntimeException("MD5签名过程中出现错误,算法异常");
        }
        byte[] digest = messageDigest.digest();
        //字节数组转成16进制字符串
        String result = byteArrayToHexString(digest);
        //如果获取的是16位加密结果的,则截取原加密结果(32位)中间的16位,也就是8-24位
        if (bit != null && bit == 16) {
            //截取下标从0开始
            result = result.substring(8, 24);
        }
        //结果的大小写处理
        return uppercase ? result.toUpperCase() : result;
    }

    /**
     * 字节数组转成16进制字符串
     *
     * @author zzc
     * @date 2023/6/28 17:29
     * @param bytes
     * @return java.lang.String
     */
    private static String byteArrayToHexString(byte[] bytes) {
        StringBuilder builder = new StringBuilder();
        for (byte b : bytes) {
            builder.append(byteToHexString(b));
        }
        return builder.toString();
    }

    /**
     * 字节转成16进制字符
     *
     * @author zzc
     * @date 2023/6/28 17:29
     * @param b
     * @return java.lang.String
     */
    private static String byteToHexString(byte b) {
        int n = b;
        if (n < 0) {
            n = 256 + n;
        }
        int d1 = n / 16;
        int d2 = n % 16;
        return hexDigits[d1] + hexDigits[d2];
    }

    public static void main(String[] args) throws Exception {
        String s = "zzc";
        System.out.println(encrypt(s, false, 32));
    }

}
  • 优点:算速度快、输出长度固定、应用广泛
  • 缺点:不安全。

MD5算法已经被攻破,而且 MD5 算法的输出长度有限,攻击者可以通过暴力破解或彩虹表攻击等方式,找到与原始数据相同的散列值,从而破解数据。虽然可以通过加盐,也就是对在原文里再加上一些不固定的字符串来缓解,但是完全可以用更安全的 SHA 系列算法替代

1.2 SHA-256

SHA(Secure Hash Algorithm)系列算法是一组密码散列函数,用于将任意长度的数据映射为固定长度的散列值。SHA系列算法由美国国家安全局(NSA)于1993年设计,目前共有 SHA-1SHA-2SHA-3 三种版本。其中 SHA-1 系列存在缺陷,已经不再被推荐使用。

SHA-2 算法包括 SHA-224、SHA-256、SHA-384 和 SHA-512 四种散列函数,分别将任意长度的数据映射为 224 位、256 位、384 位和 512 位的散列值。

public class SHA256Util {

    public static String getSHA256String(String str) {
        MessageDigest messageDigest;
        String sha256Str = "";
        try {
            messageDigest = MessageDigest.getInstance("SHA-256");
            messageDigest.update(str.getBytes("UTF-8"));
            sha256Str = byte2Hex(messageDigest.digest());
        } catch (Exception e) {
            e.printStackTrace();
        }
        return sha256Str;
    }

    /**
     * 将byte转为16进制
     *
     * @param bytes
     * @return
     */
    private static String byte2Hex(byte[] bytes) {
        StringBuffer stringBuffer = new StringBuffer();
        String temp = null;
        for (int i = 0; i < bytes.length; i++) {
            temp = Integer.toHexString(bytes[i] & 0xFF);
            if (temp.length() == 1) {
                stringBuffer.append("0");
            }
            stringBuffer.append(temp);
        }
        return stringBuffer.toString();
    }

    public static void main(String[] args) throws Exception {
        String data = "Hello World";
        String encryptedData = getSHA256String(data);
        System.out.println("加密后的数据:" + encryptedData);
    }

}

SHA-2 算法之所以比 MD5 强,主要有两个原因:

  1. 散列值长度更长:例如 SHA-256 算法的散列值长度为 256 位,而 MD5 算法的散列值长度为 128 位,这就提高了攻击者暴力破解或者彩虹表攻击的难度。
  2. 更强的碰撞抗性:SHA 算法采用了更复杂的运算过程和更多的轮次,使得攻击者更难以通过预计算或巧合找到碰撞。
    当然,SHA-2 也不是绝对安全的,散列算法都有被暴力破解或者彩虹表攻击的风险,所以,在实际的应用中,加盐还是必不可少的

2.可逆算法

2.1 对称加密

对称加密算法使用同一个密钥进行加密和解密。加密和解密过程使用的是相同的密钥,因此密钥的安全性至关重要。如果密钥泄露,攻击者可以轻易地破解加密数据。

常见的对称加密算法包括 DES、3DES、AES 等。其中,AES 算法是目前使用最广泛的对称加密算法之一,具有比较高的安全性和加密效率

2.1.1 DES

DES(Data Encryption Standard)算法是一种对称加密算法,由IBM公司于1975年研发,是最早的一种广泛应用的对称加密算法之一。

DES 算法使用 56 位密钥对数据进行加密,加密过程中使用了置换、替换、异或等运算,具有较高的安全性

public class DES {

    private static final String DES_ALGORITHM = "DES";

    /**
     * DES加密
     *
     * @param data 待加密的数据
     * @param key  密钥,长度必须为8位
     * @return 加密后的数据,使用Base64编码
     */
    public static String encrypt(String data, String key) throws Exception {
        // 根据密钥生成密钥规范
        KeySpec keySpec = new DESKeySpec(key.getBytes());
        // 根据密钥规范生成密钥工厂
        SecretKeyFactory secretKeyFactory = SecretKeyFactory.getInstance(DES_ALGORITHM);
        // 根据密钥工厂和密钥规范生成密钥
        SecretKey secretKey = secretKeyFactory.generateSecret(keySpec);

        // 根据加密算法获取加密器
        Cipher cipher = Cipher.getInstance(DES_ALGORITHM);
        // 初始化加密器,设置加密模式和密钥
        cipher.init(Cipher.ENCRYPT_MODE, secretKey);
        // 加密数据
        byte[] encryptedData = cipher.doFinal(data.getBytes());
        // 对加密后的数据进行Base64编码
        return Base64.getEncoder().encodeToString(encryptedData);
    }

    /**
     * DES解密
     *
     * @param encryptedData 加密后的数据,使用Base64编码
     * @param key           密钥,长度必须为8位
     * @return 解密后的数据
     */
    public static String decrypt(String encryptedData, String key) throws Exception {
        // 根据密钥生成密钥规范
        KeySpec keySpec = new DESKeySpec(key.getBytes());
        // 根据密钥规范生成密钥工厂
        SecretKeyFactory secretKeyFactory = SecretKeyFactory.getInstance(DES_ALGORITHM);
        // 根据密钥工厂和密钥规范生成密钥
        SecretKey secretKey = secretKeyFactory.generateSecret(keySpec);

        // 对加密后的数据进行Base64解码
        byte[] decodedData = Base64.getDecoder().decode(encryptedData);
        // 根据加密算法获取解密器
        Cipher cipher = Cipher.getInstance(DES_ALGORITHM);
        // 初始化解密器,设置解密模式和密钥
        cipher.init(Cipher.DECRYPT_MODE, secretKey);
        // 解密数据
        byte[] decryptedData = cipher.doFinal(decodedData);
        // 将解密后的数据转换为字符串
        return new String(decryptedData);
    }

    public static void main(String[] args) throws Exception {
        String data = "Hello World";
        String key = "12345678";

        String encryptedData = encrypt(data, key);
        System.out.println("加密后的数据:" + encryptedData);

        String decryptedData = decrypt(encryptedData, key);
        System.out.println("解密后的数据:" + decryptedData);
    }
}

DES 的算法速度较快,但是在安全性上面并不是最优选择,因为DES算法的密钥长度比较短,被暴力破解和差分攻击的风险比较高,一般推荐用一些更安全的对称加密算法,比如 3DES、AES

2.1.2 AES

AES(Advanced Encryption Standard)即高级加密标准,是一种对称加密算法,被广泛应用于数据加密和保护领域。AES 算法使用的密钥长度为 128 位、192 位或 256 位,比 DES 算法的密钥长度更长,安全性更高

public class AES {

    private static final String AES_ALGORITHM = "AES";
    // AES加密模式为CBC,填充方式为PKCS5Padding
    private static final String AES_TRANSFORMATION = "AES/CBC/PKCS5Padding";
    // AES密钥为16位
    private static final String AES_KEY = "1234567890123456";
    // AES初始化向量为16位
    private static final String AES_IV = "abcdefghijklmnop";

    /**
     * AES加密
     *
     * @param data 待加密的数据
     * @return 加密后的数据,使用Base64编码
     */
    public static String encrypt(String data) throws Exception {
        // 将AES密钥转换为SecretKeySpec对象
        SecretKeySpec secretKeySpec = new SecretKeySpec(AES_KEY.getBytes(), AES_ALGORITHM);
        // 将AES初始化向量转换为IvParameterSpec对象
        IvParameterSpec ivParameterSpec = new IvParameterSpec(AES_IV.getBytes());
        // 根据加密算法获取加密器
        Cipher cipher = Cipher.getInstance(AES_TRANSFORMATION);
        // 初始化加密器,设置加密模式、密钥和初始化向量
        cipher.init(Cipher.ENCRYPT_MODE, secretKeySpec, ivParameterSpec);
        // 加密数据
        byte[] encryptedData = cipher.doFinal(data.getBytes(StandardCharsets.UTF_8));
        // 对加密后的数据使用Base64编码
        return Base64.getEncoder().encodeToString(encryptedData);
    }

    /**
     * AES解密
     *
     * @param encryptedData 加密后的数据,使用Base64编码
     * @return 解密后的数据
     */
    public static String decrypt(String encryptedData) throws Exception {
        // 将AES密钥转换为SecretKeySpec对象
        SecretKeySpec secretKeySpec = new SecretKeySpec(AES_KEY.getBytes(), AES_ALGORITHM);
        // 将AES初始化向量转换为IvParameterSpec对象
        IvParameterSpec ivParameterSpec = new IvParameterSpec(AES_IV.getBytes());
        // 根据加密算法获取解密器
        Cipher cipher = Cipher.getInstance(AES_TRANSFORMATION);
        // 初始化解密器,设置解密模式、密钥和初始化向量
        cipher.init(Cipher.DECRYPT_MODE, secretKeySpec, ivParameterSpec);
        // 对加密后的数据使用Base64解码
        byte[] decodedData = Base64.getDecoder().decode(encryptedData);
        // 解密数据
        byte[] decryptedData = cipher.doFinal(decodedData);
        // 返回解密后的数据
        return new String(decryptedData, StandardCharsets.UTF_8);
    }

    public static void main(String[] args) throws Exception {
        String data = "Hello World";

        String encryptedData = encrypt(data);
        System.out.println("加密后的数据:" + encryptedData);

        String decryptedData = decrypt(encryptedData);
        System.out.println("解密后的数据:" + decryptedData);
    }
}

AES 算法采用的密钥长度更长,密钥空间更大,安全性更高,能够有效地抵抗暴力破解攻击。当然,因为密钥长度较长,需要的存储也更多。

对于对称加密算法而言,最大的痛点就在于密钥管理困难,相比而言,非对称加密就没有这个担忧

2.2 非对称加密

非对称加密算法需要两个密钥,这两个密钥互不相同,但是相互匹配,一个称为公钥,另一个称为私钥。使用其中的一个加密,则使用另一个进行解密。例如使用公钥加密,则需要使用私钥解密。

RSA 算法是是目前应用最广泛的非对称加密算法

public class RSA {

    private static final String RSA_ALGORITHM = "RSA";

    /**
     * 生成RSA密钥对
     *
     * @return RSA密钥对
     */
    public static KeyPair generateKeyPair() throws NoSuchAlgorithmException {
        KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance(RSA_ALGORITHM);
        keyPairGenerator.initialize(2048); // 密钥大小为2048位
        return keyPairGenerator.generateKeyPair();
    }

    /**
     * 使用公钥加密数据
     *
     * @param data      待加密的数据
     * @param publicKey 公钥
     * @return 加密后的数据
     */
    public static String encrypt(String data, PublicKey publicKey) throws Exception {
        Cipher cipher = Cipher.getInstance(RSA_ALGORITHM);
        cipher.init(Cipher.ENCRYPT_MODE, publicKey);
        byte[] encryptedData = cipher.doFinal(data.getBytes(StandardCharsets.UTF_8));
        return Base64.getEncoder().encodeToString(encryptedData);
    }

    /**
     * 使用私钥解密数据
     *
     * @param encryptedData 加密后的数据
     * @param privateKey    私钥
     * @return 解密后的数据
     */
    public static String decrypt(String encryptedData, PrivateKey privateKey) throws Exception {
        byte[] decodedData = Base64.getDecoder().decode(encryptedData);
        Cipher cipher = Cipher.getInstance(RSA_ALGORITHM);
        cipher.init(Cipher.DECRYPT_MODE, privateKey);
        byte[] decryptedData = cipher.doFinal(decodedData);
        return new String(decryptedData, StandardCharsets.UTF_8);
    }

    public static void main(String[] args) throws Exception {
        KeyPair keyPair = generateKeyPair();
        PublicKey publicKey = keyPair.getPublic();
        PrivateKey privateKey = keyPair.getPrivate();

        String data = "Hello World";

        String encryptedData = encrypt(data, publicKey);
        System.out.println("加密后的数据:" + encryptedData);

        String decryptedData = decrypt(encryptedData, privateKey);
        System.out.println("解密后的数据:" + decryptedData);
    }

}
  • 优点:安全性高,公钥可以公开,私钥必须保密,保证了数据的安全性;可用于数字签名、密钥协商等多种应用场景。

  • 缺点:加密、解密速度较慢,密钥长度越长,加密、解密时间越长;密钥长度过短容易被暴力破解,密钥长度过长则会增加计算量和存储空间的开销

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/703733.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

数据结构和算法的概念以及时间复杂度空间复杂度详解

⭐️ 什么是数据结构&#xff1f; 百度百科给数据结构的定义&#xff1a; 数据结构(Data Structure)是计算机存储、组织数据的方式。数据结构是指相互之间存在一种或多种特定关系的数据元素的集合。 数据结构就是数据在内存中的存储方式。 ⭐️ 什么是算法&#xff1f; 百度百…

基于高精度三维机器视觉的新能源汽车锂电池表面缺陷检测

​Part.1 行业背景 ​随着新能源汽车在全球范围内成为焦点发展领域&#xff0c;企业对电池质量控制和检测的要求也变得更加严格。在机器视觉行业迅速发展的背景下&#xff0c;市场上提供了功能强大且种类齐全的3D相机系列&#xff0c;可以满足锂电池从电芯到模组各个工艺和工位…

IAM风险CTF挑战赛

wiz启动了一个名为“The Big IAM Challenge”云安全CTF挑战赛。旨在让白帽子识别和利用 IAM错误配置&#xff0c;并从现实场景中学习&#xff0c;从而更好的认识和了解IAM相关的风险。比赛包括6个场景&#xff0c;每个场景都专注于各种AWS服务中常见的IAM配置错误。 Challenge…

【Docker】云原生利用Docker确保环境安全、部署的安全性、安全问题的主要表现和新兴技术产生的详细讲解

前言 Docker 是一个开源的应用容器引擎&#xff0c;让开发者可以打包他们的应用以及依赖包到一个可移植的容器中,然后发布到任何流行的Linux或Windows操作系统的机器上,也可以实现虚拟化,容器是完全使用沙箱机制,相互之间不会有任何接口。 &#x1f4d5;作者简介&#xff1a;热…

Vue键盘事件

1.Vue中常用的按键别名&#xff1a; 回车enter 删除delete&#xff08;捕获“删除”和“退格”键&#xff09; 推出esc 空格space 换行tab&#xff08;特殊&#xff0c;必须配合keydown使用&#xff09; 上up 下down 左left 右right 2.Vue未提供别名的按键&#xff0c;可以使用…

Arduino驱动BH1750模块实现光照强度采集

Arduino驱动BH1750模块实现光照强度采集 简介特征电气参数接线程序结果 简介 BH1750FVI是一个用于I2 C总线接口的数字环境光传感器IC。该IC最适合于获取调节手机液晶显示屏和键盘背光功率的环境光数据。在高分辨率下探测大范围是可能的。(1 - 65535 lx )。BH1750FVI可以应用于…

Matlab 回归分析与预测

统计分析 回归分析与预测 数理统计—回归分析 回归分析类型 回归分析目的 一元线性回归 多元线性回归的案例 %{ [B,BINT,R,RINT,STATS] regress(Y,X) [B,BINT,R,RINT,STATS] regress(Y,X,ALPHA) 参数解释&#xff1a;B&#xff1a; 回归系数&#xff0c;是个向量&…

小程序官方tabbar和自定义tabbar

uniapp官方tabbar&#xff1a; 打开项目中的 pages.json 文件。 在 JSON 对象中添加一个名为 tabBar 的字段&#xff0c;并设置其值为一个对象。 在 tabBar 对象中&#xff0c;配置 color 和 selectedColor 字段来定义 TabBar 的默认颜色和选中项的颜色。示例&#xff1a; …

功放IC 2018和功放IC HX8358A的区别

概述&#xff1a; 2018功放IC&#xff0c;目前在市面的情况是品牌多、杂&#xff0c;芯片的工作电压和喇叭输出功率不统一。经常出现低电压芯片用在高电压的产品上面&#xff0c;导致芯片容易损坏&#xff0c;给用户带来一定的麻烦。但它的销售量可能已超过8002的功放芯片了&am…

6.19、JAVA IO流 File 字节流 字符流

IO简介 1 流Stream 在学习IO流之前,我们首先需要学习的概念就是Stream流 为了方便理解,我们可以把数据的读写操作抽象成数据在"管道"中流动,但需注意: 1.流只能单方向流动 2.输入流用来读取 → in 3.输出流用来写出 → out 4.数据只能从头到尾顺序的读写一次 所以以…

Python 基本数据类型(六)

文章目录 每日一句正能量Tuple&#xff08;元组&#xff09;结语 每日一句正能量 一生要做的几件事情一管理好自己的身体。二管理好自己的情绪&#xff0c;正面思维。三服务好自己的家庭&#xff0c;让家人生活幸福。四做好本职工作&#xff0c;做一两件特别完美&#xff0c;石…

剑指 Offer 51: 数组中的逆序对

这道题归根结底就是一个归并问题&#xff0c;逆序对本质上就是比较大小&#xff0c;如果两边作为一个整体比较过那么就可以排序合并&#xff08;因为这个过程每一步都计算了count的值&#xff0c;所以合并起来是可以的&#xff09;。 下面的k应该是mid1&#xff08;从中间的右…

智“绘“城市:智慧环卫可视化运营管理系统

前言 随着我国城镇化的不断推进&#xff0c;城市的规模、数量不断增加&#xff0c;城市的人口数量也快速增长&#xff0c;造成的城镇生活垃圾、建筑垃圾也随之增长&#xff0c;这造成人们对环卫服务的需求增加。而与此同时&#xff0c;随着经济社会的快速发展&#xff0c;人们…

ChatGLM-6B微调p tuning v2和lora对比

官方项目地址&#xff1a;https://github.com/THUDM/ChatGLM-6B 参考本人之前的博客下载ChatGLM-6B模型&#xff1a; https://blog.csdn.net/Acecai01/article/details/131221676 设备 一张3090Ti&#xff0c; 24G显卡 实验目的 通过微调的方法&#xff0c;训练ChatGLM-6B模…

【AUTOSAR】BMS开发实际项目讲解(二十七)----电池管理系统高压上下电管理

高压上下电管理 关联的系统需求 Sys_Req_3201、Sys_Req_3202、Sys_Req_3203、Sys_Req_3204、Sys_Req_3205、Sys_Req_3206、Sys_Req_3207、Sys_Req_3208、Sys_Req_3209; 功能实现描述 高压上下电管理基于下图所示高压拓扑开发 图继电器高压拓扑图 高压上电管理 高压上电管理需…

华为bgp跨跳建立邻居后产生黑洞路由用mpls ldp解决方法

捉包发现R2在处理1.1.1.1到5.5.5.5走的是标签转发 R1: dis current-configuration [V200R003C00] snmp-agent local-engineid 800007DB03000000000000 snmp-agent clock timezone China-Standard-Time minus 08:00:00 portal local-server load flash:/portalpage.zip drop i…

Jenkins2.3.46安装

一、安装和安装Jenkins 0.前提 因jenkins从2.357版本开始不再支持java8 2、jenkins与java版本对应查看&#xff0c;与jenkins下载&#xff1a;Redhat Jenkins Packages 3、打算使用java8&#xff0c;所以选择安装2.346.3-1.1 4、安装jenkins之前&#xff0c;安装好java8并…

Day_58-59 NB 算法

目录 Day_58符号型数据的 NB 算法 一. 关于NB算法的介绍 1. 条件概率 2. 独立性假设 3. 以上式子的分析 4. Laplacian 平滑 5. 问题的回顾 二. 代码实现 1. 代码的符号说明 2. 构造函数和基础函数 3. 计算结果的分布情况 4. 核心代码 5. 分类 三. 符号型数据的运行结果 Da…

使用vtk创建设置了面的颜色的立方体

引言 该示例为官网上的例子。创建了一个每个面被设置相同颜色的立方体。 示例 开发环境 使用QtCreator4.11.2,Qt5.14.2。使用的vtk9.2的库及其头文件。创建空项目。 示例代码 其pro文件中的内容&#xff1a; QT core guigreaterThan(QT_MAJOR_VERSION, 4): QT w…

利用jmeter测试java请求

jmeter和loadrunner一样包含了测试脚本开发、测试执行、以及测试结果统计三个部分。只是jmeter没有脚本开发工具&#xff0c;因此测试java请求的脚本选择在eclipse中进行。 首先介绍如何用eclipse编写接口性能测试脚本。 针对"Java请求"类型的测试&#xff0c;需要…