网络通讯安全基础知识(加密+解密+验签+证书)

news/2024/9/19 22:48:35/ 标签: 安全

1、加密解密基本概念

通讯的加密和解密‌主要涉及将原始信息(明文)转换为不可直接理解的格式(密文),以及将密文还原为原始信息的过程。这一过程通常包括三个基本步骤:加密、传输和解密,其中加密和解密分别使用特定的算法和密钥进行。

2、加密

加密是将原始信息(明文)通过特定的算法和密钥转换为密文的过程。这个过程旨在保护信息在传输过程中不被未经授权的第三方获取或理解。加密方法包括但不限于替换密码(如凯撒密码)、转换密码(如无线电扩频通信)以及使用专门的加密机进行加密。随着技术的发展,现代加密技术还包括对称加密(如DES、AES 、RC4算法)和非对称加密(如RSA算法),后者通常用于数字签名和公钥基础设施中。

2.1对称加密

加密和解密过程使用同一个密钥。这意味着发送方使用密钥对要传输的数据进行加密,接收方则使用相同的密钥对加密后的数据进行解密,以恢复原始数据。

由于加密和解密使用的是同一个密钥,且算法通常较为简单,因此加密和解密的速度较快,适合对大量数据进行加密和解密。

public class AesExample {public static void main(String[] args) throws Exception {// 生成密钥KeyGenerator keyGen = KeyGenerator.getInstance("AES");keyGen.init(128); // 可选:128, 192, 256SecretKey secretKey = keyGen.generateKey();byte[] key = secretKey.getEncoded();// 加密String plaintext = "Hello, World!";Cipher encryptCipher = Cipher.getInstance("AES");encryptCipher.init(Cipher.ENCRYPT_MODE, new SecretKeySpec(key, "AES"));byte[] encryptedBytes = encryptCipher.doFinal(plaintext.getBytes());String encryptedText = Base64.getEncoder().encodeToString(encryptedBytes);System.out.println("Encrypted Text: " + encryptedText);// 解密Cipher decryptCipher = Cipher.getInstance("AES");decryptCipher.init(Cipher.DECRYPT_MODE, new SecretKeySpec(key, "AES"));byte[] decryptedBytes = decryptCipher.doFinal(Base64.getDecoder().decode(encryptedText));String decryptedText = new String(decryptedBytes);System.out.println("Decrypted Text: " + decryptedText);}
}
2.2非对称加密

采用两个密钥,即公钥和私钥。公钥用于加密数据,私钥则用于解密数据。公钥可以公开分享,而私钥则必须保密。

加密和解密使用的是不同的密钥,且算法相对复杂,因此加密和解密的速度较慢,只适合对少量数据进行加密和解密。

3、解密

解密是接收方使用相应的解密算法和密钥将收到的密文还原为原始明文的过程。解密是加密的反向操作,需要使用与加密过程中相同的算法和密钥。解密的成功与否取决于密钥的保密程度以及加密算法的安全性。如果密钥被泄露或算法被破解,那么加密的信息就不再安全

3.1对称加密的解密

对称加密,也称为单密钥加密,在加密过程中,数据发送方将明文(原始数据)和加密密钥一起经过特殊加密算法处理后,生成复杂的加密密文发送出去,接收方在收到密文后,需要使用与加密时相同的密钥以及相应算法的逆算法对密文进行解密,才能恢复成原始的明文数据。

3.2非对称加密的解密

非对称加密使用一对密钥:公钥和私钥。公钥可以公开分享,而私钥则必须保密。在加密过程中,发送方使用接收方的公钥对要传输的数据进行加密,然后将加密后的密文发送给接收方,接收方在收到密文后,使用自己的私钥对密文进行解密,以恢复成原始的明文数据。由于私钥是保密的,且公钥无法推导出私钥,因此即使公钥被泄露,加密的数据仍然安全

public class RsaExample {public static void main(String[] args) throws Exception {// 生成密钥对KeyPairGenerator keyGen = KeyPairGenerator.getInstance("RSA");keyGen.initialize(2048);KeyPair keyPair = keyGen.generateKeyPair();PublicKey publicKey = keyPair.getPublic();PrivateKey privateKey = keyPair.getPrivate();// 加密String plaintext = "Hello, World!";Cipher encryptCipher = Cipher.getInstance("RSA");encryptCipher.init(Cipher.ENCRYPT_MODE, publicKey);byte[] encryptedBytes = encryptCipher.doFinal(plaintext.getBytes());String encryptedText = Base64.getEncoder().encodeToString(encryptedBytes);System.out.println("Encrypted Text: " + encryptedText);// 解密Cipher decryptCipher = Cipher.getInstance("RSA");decryptCipher.init(Cipher.DECRYPT_MODE, privateKey);byte[] decryptedBytes = decryptCipher.doFinal(Base64.getDecoder().decode(encryptedText));String decryptedText = new String(decryptedBytes);System.out.println("Decrypted Text: " + decryptedText);}
}

4、加签

加签‌是指在数据传输前,使用密钥对数据进行加密生成数字签名的过程。这个过程包括使用私钥对数据进行加密,生成数字签名,并将数字签名与原始数据一起发送给接收方。数字签名的生成过程需要使用私钥,而验证过程则使用相应的公钥。加签的目的是为了证明消息的完整性和真实性,只有拥有密钥的人才能生成数字签名,且数字签名是与消息相关联的,一旦消息被更改,数字签名也会失效

import java.security.KeyPair;
import java.security.KeyPairGenerator;
import java.security.NoSuchAlgorithmException;public class KeyPairGeneratorExample {public static void main(String[] args) {try {// 使用RSA算法生成密钥对KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance("RSA");keyPairGenerator.initialize(2048);// 生成密钥对KeyPair keyPair = keyPairGenerator.generateKeyPair();System.out.println("公钥:" + keyPair.getPublic());System.out.println("私钥:" + keyPair.getPrivate());} catch (NoSuchAlgorithmException e) {e.printStackTrace();}}
}

在上述代码中,我们使用了RSA算法生成一个2048位的密钥对,其中KeyPairGenerator.getInstance("RSA")用于获取RSA算法的密钥对生成器,initialize(2048)用于设置密钥长度,generateKeyPair()用于生成密钥对。

接下来,我们使用私钥对数据进行加签

import java.nio.charset.StandardCharsets;
import java.security.KeyPair;
import java.security.KeyPairGenerator;
import java.security.NoSuchAlgorithmException;
import java.security.PrivateKey;
import java.security.Signature;public class SignExample {public static void main(String[] args) {try {// 使用RSA算法生成密钥对KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance("RSA");keyPairGenerator.initialize(2048);KeyPair keyPair = keyPairGenerator.generateKeyPair();// 使用私钥对数据进行加签String data = "Hello World!";byte[] dataBytes = data.getBytes(StandardCharsets.UTF_8);Signature signature = Signature.getInstance("SHA256withRSA");signature.initSign(keyPair.getPrivate());signature.update(dataBytes);byte[] signBytes = signature.sign();System.out.println("数字签名:" + new String(signBytes, StandardCharsets.UTF_8));} catch (NoSuchAlgorithmException e) {e.printStackTrace();} catch (Exception e) {e.printStackTrace();}}
}

在上述代码中,我们使用了SHA256withRSA算法生成数字签名,其中Signature.getInstance("SHA256withRSA")用于获取SHA256withRSA算法的签名对象,initSign(keyPair.getPrivate())用于初始化签名对象并指定私钥,update(dataBytes)用于更新待加签的数据,sign()用于生成数字签名

5、验签

验签‌是指在数据接收端,使用相同的密钥和加密算法对数据进行解密并验证数字签名的过程。接收方收到原始报文和数字签名后,使用公钥对数字签名进行解密,如果能得到摘要信息,说明的确是持有与该公钥匹配的私钥的发送方发出的。然后,对收到的数据使用相同的哈希函数生成摘要,将得到的摘要结果与解密出来的摘要进行对比。如果两者一致,就证明数据未被修改过。这个过程称为验证数字签名,简称验签

import java.nio.charset.StandardCharsets;
import java.security.KeyPair;
import java.security.PublicKey;
import java.security.Signature;
public class VerifyExample {public static void main(String[] args) {try {// 假设这里已经有了签名数据和原始数据String data = "Hello World!";byte[] dataBytes = data.getBytes(StandardCharsets.UTF_8);byte[] signBytes = /* 这里填入加签代码生成的签名数据 */;// 获取公钥PublicKey publicKey = /* 这里填入对应的公钥 */;// 使用公钥对签名进行验签Signature signature = Signature.getInstance("SHA256withRSA");signature.initVerify(publicKey);signature.update(dataBytes);boolean verified = signature.verify(signBytes);if (verified) {System.out.println("数字签名验证通过");} else {System.out.println("数字签名验证不通过");}} catch (Exception e) {e.printStackTrace();}}
}

在验签代码中,需要填入加签代码生成的签名数据、对应的公钥,然后使用公钥对签名进行验证。如果验证通过,则说明数字签名有效;否则,说明数字签名无效。

为什么有了加密解密还需要加签验签?

假设A想向B发送一份重要的文件,并且希望确保文件在传输过程中没有被篡改。A可以对文件进行数字签名(加签),然后将文件和数字签名一起发送给B。B在接收到文件后,可以使用A的公钥对数字签名进行验证,以确认文件的完整性和真实性。

如果在传输过程中有攻击者E尝试篡改文件内容,即使E能够拦截并修改了文件,但由于E没有A的私钥无法伪造有效的数字签名。因此,B在验证数字签名时会发现签名无效,从而知道文件已被篡改。

通过加签验证,B可以确保接收到的文件是由A签署的原始文件,而不是经过篡改的文件。这样可以防止数据被篡改、伪造或否认,保证数据的安全性和可靠性。

因此,加签验证在数据传输和通信过程中起着非常重要的作用,是保障数据完整性和真实性的重要手段。

6、证书

在网络通信中,证书(Certificate)是用于验证通信双方身份的一种电子文档,通常由权威的第三方机构(称为证书颁发机构,CA)颁发。证书在保障网络通信的安全性和可信性方面起着至关重要的作用。

例如,当你访问一个HTTPS网站时,服务器会提供一个证书给浏览器,浏览器会验证该证书,确认服务器的身份是真实的,而不是假冒的

6.1证书的作用

验证公钥的真实性和可信性。

确认公钥持有者的身份

通过权威的第三方(证书颁发机构,CA)建立信任链。

6.2证书的组成
  • 版本号:标识证书的版本。
  • 序列号:唯一标识一个证书的编号。
  • 签名算法:用于生成证书签名的算法。
  • 发行者(Issuer):颁发证书的 CA 的名称。
  • 有效期:证书的有效时间段。
  • 主体(Subject):证书持有者的名称。
  • 主体公钥信息:证书持有者的公钥及其算法信息。
  • 扩展(Extensions):可选的扩展信息。
  • 签名:由 CA 使用其私钥对证书内容进行签名。
6.3证书的工作原理

证书的工作原理基于公钥加密和数字签名技术,主要包括以下步骤

1. 证书申请:申请者生成一对公私钥,并将公钥和相关信息提交给 CA 进行证书申请。

2. 证书颁发:CA 对申请者的身份进行验证,验证通过后使用 CA 的私钥对申请者的公钥和相关信息进行签名,生成证书

3. 证书分发:申请者获得证书后,可以将证书分发给通信对象。

4. 证书验证:通信对象使用 CA 的公钥对证书进行验证,确保证书的真实性和完整性。
5. 安全通信:通信双方通过证书进行身份验证和数据加密,实现安全通信。


http://www.ppmy.cn/news/1520901.html

相关文章

Python数据结构类型总结

文章目录 Dictionaries, Maps, and Hash Tablesdict:标准字典collections.OrderedDict: 记住键的插入顺序collections.defaultdict: 返回缺失键的默认值collections.ChainMap:将多个词典作为单个映射进行搜索types.MappingProxyType: 制作只读字典的封装器wrapper Array Data S…

C++---基础概念

1 命名空间 在C/C中,变量、函数和后面要学到的类都是大量存在的,这些变量、函数和类的名称将都存 在于全局作用域中,可能会导致很多冲突。使用命名空间的目的是对标识符的名称进行本地化, 以避免命名冲突或名字污染,n…

鸿蒙开发基础知识 第二篇【页面布局】

鸿蒙开发基础知识 第二篇 1. 两端对齐 demo 2.交叉轴对齐方式 demo 3.列表项布局 demo 4.自适应伸缩布局 demo 自行练习 5.弹性布局 flex 换行布局 demo 案例 更多鸿蒙技能知识与案例 我已经整理到下面了 ↓↓↓ 快去看那看吧! 点击下方↓↓↓↓↓↓↓…

奇偶校验、crc循环冗余检验

数据链路层 链路 从一个结点到相邻结点的一段物理线路,而中间没有任何其他的交换点 数据链路 是指把实现通信协议的硬件和软件加到链路上 帧 在数据链路上传输的数据包,称之为帧 数据链路层是以帧为单位进行传输和处理数据的 数据链路层的三个重…

持续改进的艺术:MySQL数据备份策略的优化之路

在快速变化的信息技术领域,数据备份策略的持续改进对于确保企业数据的安全性和可用性至关重要。MySQL作为流行的数据库管理系统,提供了多种工具和特性来支持数据备份。然而,随着业务需求的增长和技术环境的变化,定期评估和优化数据…

MFC的控件无法触发事件函数(ON_COMMAND_RANGE的映射范围冲突)

如果你在MFC中使用ON_COMMAND_RANGE为多个控件绑定了同一个函数,如果使用不当,可能会造成某些控件无法映射或错误映射到对应的事件函数 错误原因: 如下图,假设为所使用的两个ON_COMMAND_RANGE和一个ON_BN_CLICKED,从I…

github源码指引:共享内存、数据结构与算法:平衡二叉树set

初级代码游戏的专栏介绍与文章目录-CSDN博客 我的github:codetoys,所有代码都将会位于ctfc库中。已经放入库中我会指出在库中的位置。 这些代码大部分以Linux为目标但部分代码是纯C的,可以在任何平台上使用。 相关专题:共享内存…

代码随想录算法训练营第五十九天 | 图论part09

47. 参加科学大会 使用邻接表和堆来优化dijkstra算法。原来的时间复杂度是 O ( n 2 ) O(n^2) O(n2),n是节点数量。 使用堆优化,从宏观角度来说就是将每条边都加入堆,一共是E条边,每次操作的时间复杂度是 l o g ( E ) log(E) log(…

RISC-V (八)定时器中断

​​​​​​​riscv中断的分类 Core local INTerrupt: CLINT CLINT编程接口-寄存器 mtime寄存器,由中断触发的时钟,按照固定频率计数。

webpack--处理资源

在webpack.config.js中进行配置 const path require(path) module.exports {// 入口entry: ./src/main.js,// 输出output: {// 文件的输出路径path: path.resolve(__dirname, dist),// 入口文件打包输出的文件名filename: js/main.js,// 自动清空上次打包结果 原理&#xff…

【论文阅读】为大规模航空图像应用神经辐射场

【论文阅读】为大规模航空图像应用神经辐射场 ABSTRACTI. INTRODUCTIONV. EXPERIMENTSA. Evaluations on the entire datasetsA.1. State-of-the-Art comparisonA.2. Cloud-to-Cloud comparisonA.3. Accuracy and completeness B. Evaluations on the selected regionsB.1. Fi…

力扣62-不同路径(Java详细题解)

题目链接:62. 不同路径 - 力扣(LeetCode) 前情提要: 因为本人最近都来刷dp类的题目所以该题就默认用dp方法来做。 dp五部曲。 1.确定dp数组和i下标的含义。 2.确定递推公式。 3.dp初始化。 4.确定dp的遍历顺序。 5.如果没…

IT服务器安全规范 2024.08

安全配置建议 使用场景场景说明安全配置建议登录密钥服务器登录账号及密钥。建议设置为强密码形式:12位以上,同时包含数字、大小写字母、特殊符号远程登录端口22、3389端口分别用于服务器的Linux和Windows场景下的远程登录,需对这两端口进行安…

docker 安装 rabbitmq

参考文档: https://hub.docker.com/_/rabbitmq/ https://www.rabbitmq.com/docs/download https://www.kuangstudy.com/zl/rabbitmq#1366643532940484610 执行下面的命令 docker run -d -it --name myrabbit -e RABBITMQ_DEFAULT_USERadmin -e RABBITMQ_DEFAULT_PA…

GaussDB 24.1.30 分布式3节点命令行方式部署

目录 GaussDB介绍 服务器环境 安装前准备 配置会话不中断 操作系统配置 关闭防火墙并禁止开机启动 设置时区和时间 检查时区和时间 java版本 expect root密码一致 root用户ssh连通性 上传软件包和安装脚本 安装脚本配置 修改 install_cluster.json 配置文件 安装…

鸿蒙系统为什么能安装安卓的APP

鸿蒙系统能够安装安卓的APP,主要得益于其设计理念和技术实现上的几个关键点: 一、设计理念 鸿蒙系统的设计初衷并非完全取代安卓系统,而是与其共存,并建立一个更加广泛的软件生态圈。这一理念体现在鸿蒙系统对安卓应用的兼容性上…

2024.9.3 作业

自己实现栈和队列 代码&#xff1a; /*******************************************/ 文件名&#xff1a;sq.h /*******************************************/ #ifndef SQ_H #define SQ_H #include <iostream> #include<cstring>using namespace std; class …

电路分析 ---- 电平移位电路

1 电平移位电路 如图所示的电平移位电路&#xff0c;用于ADC的前级驱动&#xff0c;它将一个变化范围为-10V ~ 10V的输入信号&#xff0c;线性变化成0.048V ~ 4.048V的信号&#xff0c;以满足ADC的输入范围要求。 2 电路说明 V R E F V_{REF} VREF​为电压基准源&#xff0c…

【 WPF 中常用的Brush类的简要介绍、使用方法和适用场景】

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 WPF 中常用的 Brush 类的简要介绍、使用方法和适用场景 使用场景解释示例代码&#xff08;为按钮创建一个线性渐变背景&#xff09; Brush 类描述使用示例适用场景SolidColor…

oracle 数据库 day0823

ok了家人们&#xff0c;今天学习了orcle的基本用法&#xff0c;一日不见&#xff0c;如隔三秋啊&#xff0c; 一.多表联合查询 和之前学习的MySQL数据库一样的用法&#xff0c; 1.1 笛卡尔积查询 SELECT * FROM A表,B表 查询员工表和部门表 select * from emp e, dept d; e…