62 加密算法

62 加密算法

三种加密算法分类:

  • 对称加密:密钥只有一个,解密、解密都是这个密码,加解密速度快,典型的对称加密有DESAESRC4
  • 非对称加密:密钥成对出现,分别为公钥和私钥,从公钥无法推知私钥,反之,从私钥也无法推知公钥,加密和解密使用不同的密钥,公钥加密需要私钥解密,反之,私钥加密需要公钥解密。非对称加密速度较慢,典型的非对称算法有:RSA,DSA,DSS.
  • Hash算法:这是一种不可逆的算法,它常用于验证数据的完整性。

针对拥有密钥的数量来分类,发送方和接收方拥有一样的密钥,用这个密钥进行加密解密的话就是对称加密。如果拥有两个密钥的话,分为私钥和公钥

摘要算法

摘要算法是一类用于生成固定长度的摘要或哈希值的算法,其核心目的是将任意长度的数据通过计算转化为一个简短的唯一标识符(摘要)。摘要算法的主要特性包括:

  1. 固定长度输出:无论输入数据的长度多长,摘要算法都会输出固定长度的哈希值,例如MD5生成128位的哈希值,SHA-256生成256位的哈希值。
  2. 高效性:摘要算法的计算速度通常很快,即使面对大规模数据,生成哈希值的过程也十分高效。
  3. 不可逆性:摘要算法是单向的,无法从哈希值逆向推导出原始数据。这使得摘要算法在密码学中常用于数据的完整性校验和数字签名。
  4. 抗碰撞性:好的摘要算法应该很难找到两个不同的输入数据产生相同的哈希值,这种特性称为抗碰撞性。常见的摘要算法包括MD5、SHA-1、SHA-256等。

摘要算法简单的来说就是无论输入多长都会将输入加密成指定长度的哈希值。

MD5加密

准确来讲,MD5不是一种加密算法,而是一种摘要算法,MD5能将明文输出为128bits的字符串,这个字符串是无法再被转换成明文的。所以说如果使用了MD5加密之后的字符串是无法通过密文得到其原来的明文的。这种摘要算法一般用于数字签名、密码储存和数据完整性。

public class MD5 {/*** 生成MD5* @param str* @return*/public String encode(String str) {byte[] result = null;try {MessageDigest md = MessageDigest.getInstance("MD5");md.update(str.getBytes("UTF-8"));result = md.digest();} catch (Exception e) {e.printStackTrace();return null;}return parseByte2HexStr(result);}/*** 将二进制转换成十六进制** @param buf* @return*/private String parseByte2HexStr(byte buf[]) {StringBuffer sb = new StringBuffer();for (int i = 0; i < buf.length; i++) {String hex = Integer.toHexString(buf[i] & 0xFF);if (hex.length() == 1) {hex = '0' + hex;}sb.append(hex.toUpperCase());}return sb.toString();}public static void main(String[] args) {MD5 md5=new MD5();String content = "测试test";System.out.println(md5.encode(content));}
}

SHA1算法

SHA1也是和MD5类似的信息摘要算法,但是它比MD5更加安全。

public class SHA1 {public String encode(String str) {try {MessageDigest md = MessageDigest.getInstance("SHA-1");md.update(str.getBytes("utf-8"));byte[] digest = md.digest();return byteToHexString(digest);} catch (Exception e) {e.printStackTrace();return null;}}public static String byteToHexString(byte[] bytes) {return String.valueOf(Hex.encodeHex(bytes));}public static void main(String[] args) {SHA1 sha1 = new SHA1();String content = "测试test";System.out.println(sha1.encode(content));}
}

对称加密

AES

AES代表Advanced Encryption Standard,即高级加密标准。AES是很常见的对称加密算法,所谓对称加密,就是通过密钥加密后可以再通过密钥解密。这里需要注意的是密钥十分重要,如果密钥丢失,就有信息泄漏的风险。

public class AES {/*** 将传入的明文转换为密文* @param str* @param pwd* @return*/public String encode(String str,String pwd) {byte[] result = null;try {KeyGenerator kgen = KeyGenerator.getInstance("AES");SecureRandom random = SecureRandom.getInstance("SHA1PRNG");random.setSeed(pwd.getBytes());kgen.init(128, random);SecretKey secretKey = kgen.generateKey();byte[] enCodeFormat = secretKey.getEncoded();SecretKeySpec key = new SecretKeySpec(enCodeFormat, "AES");// 创建密码器Cipher cipher = Cipher.getInstance("AES/ECB/PKCS5Padding");cipher.init(Cipher.ENCRYPT_MODE, key);byte[] byteContent = str.getBytes();result = cipher.doFinal(byteContent);} catch (Exception e) {return null;}return parseByte2HexStr(result);}/*** 将传入的密文转换为明文* @param str* @param pwd* @return*/public String decode(String str,String pwd) {byte[] result = null;byte[] content = parseHexStr2Byte(str);try {KeyGenerator kgen = KeyGenerator.getInstance("AES");SecureRandom random = SecureRandom.getInstance("SHA1PRNG");random.setSeed(pwd.getBytes());kgen.init(128, random);SecretKey secretKey = kgen.generateKey();byte[] enCodeFormat = secretKey.getEncoded();SecretKeySpec key = new SecretKeySpec(enCodeFormat, "AES");// 创建密码器Cipher cipher = Cipher.getInstance("AES/ECB/PKCS5Padding");cipher.init(Cipher.DECRYPT_MODE, key);result = cipher.doFinal(content);} catch (Exception e) {e.printStackTrace();return null;}return new String(result);}/*** 将二进制转换成十六进制** @param buf* @return*/private String parseByte2HexStr(byte buf[]) {StringBuffer sb = new StringBuffer();for (int i = 0; i < buf.length; i++) {String hex = Integer.toHexString(buf[i] & 0xFF);if (hex.length() == 1) {hex = '0' + hex;}sb.append(hex.toUpperCase());}return sb.toString();}/*** 将十六进制转换为二进制** @param hexStr* @return*/private byte[] parseHexStr2Byte(String hexStr) {if (hexStr.length() < 1) {return null;}byte[] result = new byte[hexStr.length() / 2];for (int i = 0; i < hexStr.length() / 2; i++) {int high = Integer.parseInt(hexStr.substring(i * 2, i * 2 + 1), 16);int low = Integer.parseInt(hexStr.substring(i * 2 + 1, i * 2 + 2), 16);result[i] = (byte) (high * 16 + low);}return result;}public static void main(String[] args) {AES aes = new AES();String content = "测试加密";// AES的密钥长度最好是16位(不是必须)String pwd = "javayznbjavayznb";// 加密System.out.println("加密前:" + content);String encodeResultStr = aes.encode(content,pwd);System.out.println("加密后:" + encodeResultStr);// 解密String decodeResultStr = aes.decode(encodeResultStr,pwd);System.out.println("解密后:" + decodeResultStr);}}

DES

DES也是一种对称加密算法,但是在安全性、效率和灵活性上比AES略差,但是也能保证安全,DES也需要通过密钥进行加密,通过密钥进行解密,因此密钥很重要:

public class DES {/*** 将传入的明文转换为密文* @param str* @param pwd* @return*/public String encode(String str,String pwd) {byte[] result = null;try {DESKeySpec keySpec = new DESKeySpec(pwd.getBytes());SecretKeyFactory keyFactory = SecretKeyFactory.getInstance("DES");SecretKey key = keyFactory.generateSecret(keySpec);Cipher cipher = Cipher.getInstance("DES/ECB/PKCS5Padding");cipher.init(Cipher.ENCRYPT_MODE, key);byte[] byteContent = str.getBytes();result = cipher.doFinal(byteContent);} catch (Exception e) {e.printStackTrace();return null;}return parseByte2HexStr(result);}/*** 将传入的密文转换为明文* @param str* @param pwd* @return*/public String decode(String str,String pwd) {byte[] result = null;byte[] content = parseHexStr2Byte(str);try {DESKeySpec keySpec = new DESKeySpec(pwd.getBytes());SecretKeyFactory keyFactory = SecretKeyFactory.getInstance("DES");SecretKey key = keyFactory.generateSecret(keySpec);Cipher cipher = Cipher.getInstance("DES/ECB/PKCS5Padding");cipher.init(Cipher.DECRYPT_MODE, key);result = cipher.doFinal(content);} catch (Exception e) {e.printStackTrace();return null;}return new String(result);}/*** 将二进制转换成十六进制** @param buf* @return*/private String parseByte2HexStr(byte buf[]) {StringBuffer sb = new StringBuffer();for (int i = 0; i < buf.length; i++) {String hex = Integer.toHexString(buf[i] & 0xFF);if (hex.length() == 1) {hex = '0' + hex;}sb.append(hex.toUpperCase());}return sb.toString();}/*** 将十六进制转换为二进制** @param hexStr* @return*/private byte[] parseHexStr2Byte(String hexStr) {if (hexStr.length() < 1) {return null;}byte[] result = new byte[hexStr.length() / 2];for (int i = 0; i < hexStr.length() / 2; i++) {int high = Integer.parseInt(hexStr.substring(i * 2, i * 2 + 1), 16);int low = Integer.parseInt(hexStr.substring(i * 2 + 1, i * 2 + 2), 16);result[i] = (byte) (high * 16 + low);}return result;}public static void main(String[] args) {DES des = new DES();String content = "测试test";// DES的密钥长度必须是8位(小于8位则会报错,8位之后对加密结果不会产生影响)String pwd = "javayznb";// 加密System.out.println("加密前:" + content);String encodeResultStr = des.encode(content,pwd);System.out.println("加密后:" + encodeResultStr);//解密String decodeResultStr = des.decode(encodeResultStr,pwd);System.out.println("解密后:" + decodeResultStr);}
}

非对称加密

RSA

RSA是目前最具影响力的公钥加密算法,并且可以用于加密和验签。支付宝支付对接时用的加密方式就是RSA。在RSA中,存在一对密钥,分别称为公钥和私钥,通过私钥由个人保存,公钥可能多人持有。

RSA的主要应用场景就是加密和验签,加密就不用说了,验签是指通过私钥对消息进行签名,使得消息无法篡改和伪造。

加密方式:B传加密数据给A

1、A生成公钥和私钥,私钥自己保留,公钥任何人可以获取。

2、B拿到公钥,将数据通过公钥加密

3、A收到密文,通过私钥解密。

验签方式:A传消息给B

1、A生成公钥和私钥,私钥自己保留,公钥任何人可以获取。

2、A使用私钥对消息加签,并将加签后的消息传给B。

3、B通过公钥验签,如果返回是true则说明消息是A发过来的且未被篡改。

public class TestRSA {/*** RSA最大加密明文大小*/private static final int MAX_ENCRYPT_BLOCK = 117;/*** RSA最大解密密文大小*/private static final int MAX_DECRYPT_BLOCK = 128;/*** 获取密钥对** @return 密钥对*/public static KeyPair getKeyPair() throws Exception {KeyPairGenerator generator = KeyPairGenerator.getInstance("RSA");generator.initialize(1024);return generator.generateKeyPair();}/*** 获取私钥** @param privateKey 私钥字符串* @return*/public static PrivateKey getPrivateKey(String privateKey) throws Exception {KeyFactory keyFactory = KeyFactory.getInstance("RSA");byte[] decodedKey = Base64.decodeBase64(privateKey.getBytes());PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(decodedKey);return keyFactory.generatePrivate(keySpec);}/*** 获取公钥** @param publicKey 公钥字符串* @return*/public static PublicKey getPublicKey(String publicKey) throws Exception {KeyFactory keyFactory = KeyFactory.getInstance("RSA");byte[] decodedKey = Base64.decodeBase64(publicKey.getBytes());X509EncodedKeySpec keySpec = new X509EncodedKeySpec(decodedKey);return keyFactory.generatePublic(keySpec);}/*** RSA加密** @param data 待加密数据* @param publicKey 公钥* @return*/public static String encrypt(String data, PublicKey publicKey) throws Exception {Cipher cipher = Cipher.getInstance("RSA");cipher.init(Cipher.ENCRYPT_MODE, publicKey);int inputLen = data.getBytes().length;ByteArrayOutputStream out = new ByteArrayOutputStream();int offset = 0;byte[] cache;int i = 0;// 对数据分段加密while (inputLen - offset > 0) {if (inputLen - offset > MAX_ENCRYPT_BLOCK) {cache = cipher.doFinal(data.getBytes(), offset, MAX_ENCRYPT_BLOCK);} else {cache = cipher.doFinal(data.getBytes(), offset, inputLen - offset);}out.write(cache, 0, cache.length);i++;offset = i * MAX_ENCRYPT_BLOCK;}byte[] encryptedData = out.toByteArray();out.close();// 获取加密内容使用base64进行编码,并以UTF-8为标准转化成字符串// 加密后的字符串return new String(Base64.encodeBase64String(encryptedData));}/*** RSA解密** @param data 待解密数据* @param privateKey 私钥* @return*/public static String decrypt(String data, PrivateKey privateKey) throws Exception {Cipher cipher = Cipher.getInstance("RSA");cipher.init(Cipher.DECRYPT_MODE, privateKey);byte[] dataBytes = Base64.decodeBase64(data);int inputLen = dataBytes.length;ByteArrayOutputStream out = new ByteArrayOutputStream();int offset = 0;byte[] cache;int i = 0;// 对数据分段解密while (inputLen - offset > 0) {if (inputLen - offset > MAX_DECRYPT_BLOCK) {cache = cipher.doFinal(dataBytes, offset, MAX_DECRYPT_BLOCK);} else {cache = cipher.doFinal(dataBytes, offset, inputLen - offset);}out.write(cache, 0, cache.length);i++;offset = i * MAX_DECRYPT_BLOCK;}byte[] decryptedData = out.toByteArray();out.close();// 解密后的内容return new String(decryptedData, "UTF-8");}/*** 签名** @param data 待签名数据* @param privateKey 私钥* @return 签名*/public static String sign(String data, PrivateKey privateKey) throws Exception {byte[] keyBytes = privateKey.getEncoded();PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(keyBytes);KeyFactory keyFactory = KeyFactory.getInstance("RSA");PrivateKey key = keyFactory.generatePrivate(keySpec);Signature signature = Signature.getInstance("MD5withRSA");signature.initSign(key);signature.update(data.getBytes());return new String(Base64.encodeBase64(signature.sign()));}/*** 验签** @param srcData 原始字符串* @param publicKey 公钥* @param sign 签名* @return 是否验签通过*/public static boolean verify(String srcData, PublicKey publicKey, String sign) throws Exception {byte[] keyBytes = publicKey.getEncoded();X509EncodedKeySpec keySpec = new X509EncodedKeySpec(keyBytes);KeyFactory keyFactory = KeyFactory.getInstance("RSA");PublicKey key = keyFactory.generatePublic(keySpec);Signature signature = Signature.getInstance("MD5withRSA");signature.initVerify(key);signature.update(srcData.getBytes());return signature.verify(Base64.decodeBase64(sign.getBytes()));}public static void main(String[] args) {try {// 生成密钥对KeyPair keyPair = getKeyPair();String privateKey = new String(Base64.encodeBase64(keyPair.getPrivate().getEncoded()));String publicKey = new String(Base64.encodeBase64(keyPair.getPublic().getEncoded()));System.out.println("私钥:" + privateKey);System.out.println("公钥:" + publicKey);// RSA加密String data = "待加密的文字内容";String encryptData = encrypt(data, getPublicKey(publicKey));System.out.println("加密后内容:" + encryptData);// RSA解密String decryptData = decrypt(encryptData, getPrivateKey(privateKey));System.out.println("解密后内容:" + decryptData);// RSA签名String sign = sign(data, getPrivateKey(privateKey));System.out.println("加签后:"+sign);// RSA验签boolean result = verify(data, getPublicKey(publicKey), sign);System.out.print("验签结果:" + result);} catch (Exception e) {e.printStackTrace();System.out.print("加解密异常");}}
}

签名

![外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传](https://img-home.csdnimg.cn/images/20230724024159.png?origin_url=assets%2Fimage-在这里插入图片描述

签名的作用就是验证传输的消息是否被人修改过了。

Base64

Base64是一种二进制到文本的编码方式。如果要更具体一点的话,可以认为它是一种将 byte数组编码为字符串的方法,而且编码出的字符串只包含ASCII基础字符。

例如字符串ShuSheng007对应的Base64为U2h1U2hlbmcwMDc=。其中那个=比较特殊,是填充符,一会再说。

值得注意的是Base64不是加密算法,其仅仅是一种编码方式,算法也是公开的,所以不能依赖它进行加密。

为什么叫Base64?

在这里插入图片描述
在这里插入图片描述

Base64就是为了解决各系统以及传输协议中二进制不兼容的问题而生的

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

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

单细胞转录组 —— simpleaf 原始数据处理

单细胞转录组 —— 原始数据处理实战&#xff08;simpleaf&#xff09; 前言 Alevin-fry 是一个快速、准确且内存节约的单细胞和单核数据处理工具。 Simpleaf 是用 Rust 编写的程序&#xff0c;它提供了一个统一且简化的界面&#xff0c;用于通过 alevin-fry 流程处理一些最…

实现std::sort,replace,fill,accumulate,equal等函数

std::sort /// <summary>/// std::sort 是从小到大排列的/// </summary>/// <typeparam name"IteratorClass"></typeparam>/// <typeparam name"ComparingFunctions"></typeparam>/// <param name"itBegin&qu…

系统端口号被占用问题处理(WindowsLinux系统)

Windows 直接kill占用端口的进程 WinR 输入cmd 打开命令行窗口 1.查询本地已被占用的端口号&#xff1a; 下面以8080端口为例&#xff1a; netstat -aon|findstr "8080" 查看本地8080端口进程的PID 2.杀死"xxxx"端口号的进程 (下面的22868是 你查到…

java.lang.NoClassDefFoundError: kotlin/Result解决方案

问题 在控制窗口上虽然报错是找不到对应的class&#xff0c;但是呢在我们导入kotlin的后&#xff0c;还是报相同的异常&#xff0c;在网上查找了各种资料&#xff0c;都没有解决方案。 问题分析 在idea2021之后&#xff0c;kotlin都使用远程仓库&#xff08;kotlinx-coeouti…

多模态大语言模型(MLLM)-InstructBlip深度解读

前言 InstructBlip可以理解为Blip2的升级版&#xff0c;重点加强了图文对话的能力。 模型结构和Blip2没差别&#xff0c;主要在数据集收集、数据集配比、指令微调等方面下文章。 创新点 数据集收集&#xff1a; 将26个公开数据集转换为指令微调格式&#xff0c;并将它们归类…

鸿蒙开发(NEXT/API 12)【管理应用与Wear Engine服务的连接状态】手机侧应用开发

监测应用与Wear Engine服务的连接状态 华为运动健康App在后台停止服务&#xff08;如功耗过高&#xff09;&#xff0c;从而导致应用与Wear Engine服务的连接状态发生变化。对于类似这种不确定的断开情况&#xff0c;开发者可以通过本功能特性了解当前应用和Wear Engine的连接…

电池大师 2.3.9 | 专业电池管理,延长寿命优化性能

Battery Guru 显示电池使用情况信息&#xff0c;测量电池容量&#xff08;mAh&#xff09;&#xff0c;并通过有用技巧帮助用户改变充电习惯&#xff0c;延长电池寿命。支持显示电池健康状况&#xff0c;优化电池性能。 大小&#xff1a;9.6M 百度网盘&#xff1a;https://pan…

【SQL】换座位

目录 语法 需求 示例 分析 代码 语法 SELECT user_id, user_name, IF(user_age < 18, Minor, IF(user_age < 65, Adult, Senior)) AS age_group FROM users; 使用IF函数来根据user_age的值将用户分为不同的年龄组 在SQL中&#xff0c;IF语法主要用于在查询中根据条…

毕业设计项目-古典舞在线交流平台的设计与实现(源码/论文)

项目简介 基于springboot实现的&#xff0c;主要功能如下&#xff1a; 技术栈 后端框框&#xff1a;springboot/mybatis 前端框架&#xff1a;html/JavaScript/Css/vue/elementui 运行环境&#xff1a;JDK1.8/MySQL5.7/idea&#xff08;可选&#xff09;/Maven3&#xff08…

子弹生产线残次品检测系统源码分享

子弹生产线残次品检测系统源码分享 [一条龙教学YOLOV8标注好的数据集一键训练_70全套改进创新点发刊_Web前端展示] 1.研究背景与意义 项目参考AAAI Association for the Advancement of Artificial Intelligence 项目来源AACV Association for the Advancement of Computer…

Golang | Leetcode Golang题解之第451题根据字符出现频率排序

题目&#xff1a; 题解&#xff1a; func frequencySort(s string) string {cnt : map[byte]int{}maxFreq : 0for i : range s {cnt[s[i]]maxFreq max(maxFreq, cnt[s[i]])}buckets : make([][]byte, maxFreq1)for ch, c : range cnt {buckets[c] append(buckets[c], ch)}an…

ATAM需求说明-系统架构师(七十六)

1体系结构权衡分析法ATAM(Architecture Trade Off Analyzer Method)是一种常见的结构权衡分析法&#xff0c;该框架主要关注系统的&#xff08;&#xff09;&#xff0c;针对性能、安全性、可用性和可修改性&#xff0c;在系统开发前进行分析、评价和这种。 A 需求说明 B 架构…

搭建企业级私有仓库harbor

华子目录 harbor简介实验环境准备下载软件包安装docker-cehosts解析 实验步骤配置https加密传输解压进入解压目录&#xff0c;修改文件配置启动harbor 测试客户端配置harbor本地加速器注意 通过docker compose管理harbor harbor简介 harbor是由wmware公司开源的企业级docker r…

uniapp自定义导航,全端兼容

我们在用uniapp 开发应用的时候&#xff0c;有的页面需要自定义导航&#xff0c; 1.如果普通的直接使用uni 扩展柜组件的 uni-nav-bar 也基本够用&#xff0c; 2.如果稍微带点自定义的这个值无法支持的&#xff0c;特别在小程序端&#xff0c;胶囊是会压住右边的按钮的 自定…

Debezium日常分享系列之:Debezium 3.0.0.Final发布

Debezium日常分享系列之&#xff1a;Debezium 3.0.0.Final发布 Debezium 核心的变化需要 Java 17基于Kafka 3.8 构建废弃的增量信号字段的删除每个表的详细指标 MariaDB连接器的更改版本 11.4.3 支持 MongoDB连接器的更改MongoDB sink connector MySQL连接器的改变MySQL 9MySQL…

九大排序之交换排序

1.前言 所谓交换&#xff0c;就是根据序列中两个记录键值的比较结果来对换这两个记录在序列中的位置&#xff0c;交换排序的特点是&#xff1a;将键值较大的记录向序列的尾部移动&#xff0c;键值较小的记录向序列的前部移动。 重点&#xff1a; 冒泡排序和快速排序 2.冒泡排…

【电子通识】TINA-TI 安装

TINA-TI是一个SPICE的模拟仿真程序&#xff0c;提供了 SPICE 所有的传统直流、瞬态和频域分析以及更多功能。 TINA 具有允许您按照希望的方式设置结果的格式。虚拟仪器允许选择输入波形、探针电路节点电压和波形。 下载链接&#xff1a;TINA-TI 模拟工具 | 德州仪器 TI.com.cn …

MAC备忘录空白解决方案

打开icloud->备忘录 取消勾选同步此MAC后再次勾选&#xff0c;然后点击完成即可。

【投稿优惠|稳定检索】2024 年信息学、网络与电子工程国际会议(INEE 2024)

2024 年信息学、网络与电子工程国际会议 2024 International Conference on Informatics, Networks, and Electronic Engineering 【1】大会信息 会议名称&#xff1a;2024 年信息学、网络与电子工程国际会议 会议简称&#xff1a;INEE 2024 大会时间&#xff1a;请查看官网 …

qt 3D编程

Qt 3D是一个用于构建交互式3D图形应用的库&#xff0c;它是Qt库的一 部分。Qt 3D提供了一组C和QMLAPI&#xff0c;帮助开发者快速构 建3D应用程序。 一、核心模块 Qt3DCore 功能&#xff1a;提供3D场景中的基本概念&#xff0c;如实体&#xff08;Entity&#xff09;、组件&…