网络传输加密及openssl使用样例(客户端服务器)

news2024/9/18 13:26:43

文章目录

  • 背景
    • 常用加密方式
    • SSL
    • OpenSSL
      • 主要功能
    • 库结构
  • 交互流程
  • 证书生成
    • 生成 RSA 私钥
      • 私钥的主要组成部分
      • 私钥的格式
    • 创建自签名证书:
  • 签发证书
  • 服务器端代码
  • 客户端代码
  • 常见错误
    • 版本问题
    • 证书问题
    • 证书格式

背景

网络传输中为保证数据安全,通常需要加密

常用加密方式

  • 对称加密:
    特点:使用同一个密钥进行加密和解密,速度快,但密钥管理复杂,适合在密钥交换后的大量数据传输。
    常用算法:DES、3DES、AES等。
  • 非对称加密:
    特点:使用一对密钥(公钥和私钥),公钥用于加密,私钥用于解密,或者私钥用于签名,公钥用于验证。这种方式解决了密钥交换的问题,但加密解密速度较慢。
    常用算法:RSA、DSS、ECC等。
  • 单向加密(散列加密、签名):
    特点:只能加密,不能解密,常用于生成数据的摘要或验证数据的完整性。元数据改变签名大概率发生变化
    常用算法:MD5、SHA-1、SHA-256、SHA-512等。

SSL

SSL(Secure Sockets
Layer)是最常用的网络传输加密协议之一,但需要注意的是,随着技术的发展,SSL的继任者TLS(Transport Layer
Security)已经成为更广泛使用的标准。然而,由于历史原因,“SSL”这一术语在日常使用中仍然非常普遍。

SSL/TLS协议通过结合对称加密、非对称加密和数字签名等多种加密技术,为网络通信提供了强大的安全保障。RSA、DSA和ECC等算法在SSL/TLS中扮演着重要的角色,分别用于密钥交换、数字签名等关键过程。

SSL/TLS协议主要包括以下几个关键组成部分:

  • 加密技术:SSL/TLS利用对称加密和非对称加密技术来保护数据的机密性和完整性。
  • 对称加密(如AES)用于加密和解密实际传输的数据,因为它速度快且效率高。
  • 非对称加密(如RSA、DSS、ECC)则用于密钥交换和数字签名,以确保通信双方的身份验证和数据的不可抵赖性。
  • 密钥交换:在SSL/TLS握手过程中,客户端和服务器会协商一个共同的加密密钥(会话密钥),用于后续的数据加密和解密。这个过程中,非对称加密算法(如RSA、ECC)被用来安全地交换密钥信息。
  • 数字签名:数字签名用于验证通信双方的身份和数据的完整性。在SSL/TLS中,服务器会向客户端发送一个包含其公钥和身份信息的证书,该证书由受信任的证书颁发机构(CA)签发,并使用非对称加密算法(如RSA、ECC)进行签名。客户端通过验证证书的签名来确认服务器的身份。

关于RSA、DSS(通常指DSA,即Digital Signature Algorithm)和ECC(Elliptic Curve Cryptography)与SSL/TLS的关系:

  • RSA:是一种非对称加密算法,广泛用于SSL/TLS中的密钥交换和数字签名。RSA算法的安全性基于大数分解的困难性,它使用一对密钥(公钥和私钥)来进行加密和解密操作。
  • DSA:是一种专门用于数字签名的算法,与RSA类似,也是基于非对称加密原理。DSA在SSL/TLS中主要用于验证证书的数字签名,而不是用于密钥交换。
  • ECC:是一种基于椭圆曲线密码学的加密算法,与RSA相比,ECC提供了更高的安全性和更短的密钥长度。ECC在SSL/TLS中的应用越来越广泛,因为它能够在保持相同安全性的同时减少计算量和存储需求。

OpenSSL

OpenSSL 是一个强大的开源加密软件库,它提供了多种加密算法、随机数生成器、安全套接字层(SSLv3/TLS)协议实现等功能。OpenSSL
不仅可以用于开发安全的网络应用程序,还可以作为一个命令行工具来处理加密相关的任务。

主要功能

  • 加密算法: 包括对称加密算法(如 AES)、非对称加密算法(如 RSA 和 ECC)、哈希算法(如 SHA-256)等。
  • 随机数生成: 提供了安全的随机数生成器。
  • 安全套接字层 (SSL/TLS): 实现了 SSLv3 和 TLS 协议,用于加密网络通信。
  • X.509 证书管理: 支持 X.509 标准的数字证书的创建、验证和管理。
  • PKCS 标准: 支持 PKCS#7、PKCS#12 等标准。

库结构

  • Crypto Library: 提供基本的加密功能。
  • SSL Library: 基于 Crypto Library 提供 SSL/TLS 协议的支持。
    命令行工具:
    openssl: 提供了丰富的命令行选项,用于执行各种加密操作

版本查看

openssl version -a

交互流程

证书生成

生成 RSA 私钥

openssl genrsa -out server.key 2048

OpenSSL
生成的私钥的数据结构并不是简单的随机数集合,而是遵循特定加密算法和协议规定的复杂数据结构。私钥的格式和内容取决于所使用的加密算法(如RSA、DSA、ECDSA等)和密钥的格式(如PEM、DER等)。

私钥的主要组成部分

对于不同的加密算法,私钥的组成会有所不同,但通常包括以下几个基本部分:

  • 算法标识:指明使用的是哪种加密算法(如RSA、DSA、ECDSA等)。
  • 参数:包括加密算法所需的具体参数。例如,对于RSA算法,这些参数可能包括两个大的质数(p和q)、模数(n = p * q)、公钥和私钥指数(e和d)等。
  • 随机性:私钥的生成通常涉及一定程度的随机性,以确保私钥的不可预测性和安全性。然而,这并不意味着私钥完全由随机数组成,而是随机数用于生成私钥的某些关键部分(如私钥指数d)。

私钥的格式

私钥可以以不同的格式存储,最常见的两种是PEM(Privacy Enhanced Mail)和DER(Distinguished Encoding Rules):

  • PEM格式:以-----BEGIN PRIVATE KEY-----和-----END PRIVATE KEY-----为边界,内部是Base64编码的私钥数据。PEM格式是文本格式,易于阅读和存储,但可能会包含额外的换行符和空格。
  • DER格式:DER是二进制格式,直接存储私钥的二进制数据,没有额外的编码或标记。DER格式更加紧凑,适用于需要最小化大小的场景,如嵌入式系统。

创建自签名证书:

openssl req -new -key server.key -out server.csr
openssl x509 -req -days 365 -in server.csr -signkey server.key -out server.crt
在创建证书的过程中,你可能需要输入一些信息,
如国家代码、组织名称等。你可以填写适当的值或直接按回车键使用默认值

在这里插入图片描述

使用openssl req -new -x509 -key server.key -out server.crt -days 365
-nodes命令生成的证书(server.crt)是一个自签名的X.509证书,其数据结构包含了多个关键的信息字段。以下是该证书数据结构中通常包含的内容:

  • 证书版本(Version):
    表明证书遵循的X.509版本,常见的版本有V1、V2和V3。
  • 序列号(Serial Number):
    由证书颁发机构(CA)分配的唯一数字,用于唯一标识该证书。
  • 签名算法(Signature Algorithm):
    指出用于签名证书的算法,如SHA-256 with RSA等。
  • 颁发者(Issuer):
    指出颁发该证书的实体,由于是自签名证书,颁发者和主体(Subject)通常相同。
  • 有效期(Validity Period):
    包括证书的生效日期(Not Before)和失效日期(Not After),本例中有效期为365天。
  • 主体(Subject):
    包含证书持有者的信息,如组织名(O)、组织单位名(OU)、通用名(CN,即- Common Name,通常指域名或服务器名)等。这些信息在openssl req命令执行时会通过交互式输入或配置文件提供。
  • 公钥信息(Public Key Info):
    包含证书的公钥和公钥使用的算法(如RSA)。公钥用于与私钥配对,进行加密/解密和签名/验证操作。
  • 证书签名(Signature):
    使用颁发者的私钥对证书内容的哈希值进行签名,确保证书内容的完整性和真实性。由于是自签名证书,这里的签名是使用server.key中的私钥生成的。
  • 其他可选字段:
    如主题备用名称(Subject Alternative Name,SANs),可以包含除了CN之外的多个域名或IP地址,增强证书的灵活性。
  • 扩展(Extensions):
    X.509 V3证书支持扩展字段,用于包含额外的信息,如证书吊销列表(CRL)的分发点、密钥用途(Key Usage)、扩展密钥用途(Extended Key Usage)等。

签发证书

上述例子由于是自签名证书,其颁发者信息、签名和公钥都是基于server.key中的私钥生成的,因此不需要外部证书颁发机构(CA)的参与。自签名证书通常用于测试和开发环境,而不推荐在生产环境中使用,因为自签名证书无法由客户端自动验证其真实性,可能会导致安全警告。

线上环境需要购买证书 比如使用XX云

服务器端代码

版本 OpenSSL 1.0.2

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <openssl/ssl.h>
#include <openssl/err.h>

#define PORT 8443
#define BUFFER_SIZE 1024

void handle_ssl_connection(SSL *ssl) {
    char buffer[BUFFER_SIZE];
    char resp[BUFFER_SIZE+10];
    int bytes_received;

    while ((bytes_received = SSL_read(ssl, buffer, BUFFER_SIZE)) > 0) {
        buffer[bytes_received] = '\0';
        printf("Received: %s\n", buffer);
        sprintf(resp,"srv recv %s",buffer);
        // 响应客户端
        SSL_write(ssl,resp, strlen(resp) + 1);
    }

    if (bytes_received <= 0) {
        fprintf(stderr, "Error on read: %d\n", bytes_received);
    }
}

int main() {
    int listen_fd, conn_fd;
    struct sockaddr_in serv_addr;
    SSL_CTX *ctx;
    SSL *ssl;
    int opt = 1;

    // 创建 socket
    if ((listen_fd = socket(AF_INET, SOCK_STREAM, 0)) < 0) {
        perror("Socket creation failed");
        exit(EXIT_FAILURE);
    }

    // 设置 SO_REUSEADDR 选项
    if (setsockopt(listen_fd, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt))) {
        perror("Setsockopt failed");
        exit(EXIT_FAILURE);
    }

    // 绑定地址
    memset(&serv_addr, 0, sizeof(serv_addr));
    serv_addr.sin_family = AF_INET;
    serv_addr.sin_addr.s_addr = htonl(INADDR_ANY);
    serv_addr.sin_port = htons(PORT);

    if (bind(listen_fd, (struct sockaddr *)&serv_addr, sizeof(serv_addr)) < 0) {
        perror("Bind failed");
        exit(EXIT_FAILURE);
    }

    // 监听连接
    if (listen(listen_fd, 5) < 0) {
        perror("Listen failed");
        exit(EXIT_FAILURE);
    }

    // 初始化 SSL 上下文
    SSL_library_init();
    ctx = SSL_CTX_new(TLSv1_2_method());
    if (!ctx) {
        ERR_print_errors_fp(stderr);
        exit(EXIT_FAILURE);
    }

    // 加载证书和私钥
    if (SSL_CTX_use_certificate_file(ctx, "server.crt", SSL_FILETYPE_PEM) <= 0) {
        ERR_print_errors_fp(stderr);
        exit(EXIT_FAILURE);
    }
    if (SSL_CTX_use_PrivateKey_file(ctx, "server.key", SSL_FILETYPE_PEM) <= 0) {
        ERR_print_errors_fp(stderr);
        exit(EXIT_FAILURE);
    }

    // 验证私钥
    if (!SSL_CTX_check_private_key(ctx)) {
        fprintf(stderr, "Private key does not match the certificate public key\n");
        exit(EXIT_FAILURE);
    }

    // 接受客户端连接
    while (1) {
        struct sockaddr_in client_addr;
	socklen_t client_len = sizeof(client_addr);
        conn_fd = accept(listen_fd,(struct sockaddr *)&client_addr, &client_len);
        if (conn_fd < 0) {
            perror("Accept failed");
            continue;
        }
        printf("Accepted client  %s:%d\n", inet_ntoa(client_addr.sin_addr), ntohs(client_addr.sin_port));
        ssl = SSL_new(ctx);
        SSL_set_fd(ssl, conn_fd);

        // 建立 SSL 连接
        if (SSL_accept(ssl) == -1) {
            ERR_print_errors_fp(stderr);
            SSL_free(ssl);
            close(conn_fd);
            continue;
        }

        // 处理 SSL 连接
        handle_ssl_connection(ssl);

        // 清理资源
        SSL_shutdown(ssl);
        SSL_free(ssl);
        close(conn_fd);
    }

    SSL_CTX_free(ctx);
    close(listen_fd);

    return 0;
}

客户端代码

#include <stdio.h>
#include <openssl/ssl.h>
#include <openssl/err.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <unistd.h>

#define RCVBUFSIZE 1024

/*
gcc -g -o client client.c -lssl -lcrypto
*/
 
int main() {
    int sock;
    struct sockaddr_in serv_addr;
    char user_input[1024];
    char buffer[RCVBUFSIZE];
    int  recv_len =0;
    SSL_CTX *ctx;
    SSL *ssl;
    int res = 0;
    int i = 0;
    SSL_library_init();
    ctx = SSL_CTX_new(TLSv1_2_method());

	if ((sock = socket(AF_INET, SOCK_STREAM, 0)) < 0) {
        perror("Socket creation failed");
        exit(EXIT_FAILURE);
    }
	memset(&serv_addr, 0, sizeof(serv_addr));
    serv_addr.sin_family = AF_INET;
    serv_addr.sin_port = htons(8443);
    inet_pton(AF_INET, "127.0.0.1", &serv_addr.sin_addr);
	

    if (connect(sock, (struct sockaddr *)&serv_addr, sizeof(serv_addr)) == -1) {
        printf("socket connect failed\n");
    }

    printf("connect client, socket:%d\n", sock);

    ssl = SSL_new(ctx);
    if (ssl == NULL) {
        printf("socket:%d, SSL_new failed\n", sock);
        goto sslerror;
    }

    SSL_set_fd(ssl, sock);

    if (SSL_connect(ssl) < 0) {
        printf("socket:%d, SSL_accept failed\n", sock);
        goto sslerror;
    }
    printf("ssl connected ok\n");
    
	for(i+0;i<500;i++){ // test
		printf("Enter data to send: ");
		fgets(user_input,sizeof(user_input)-1, stdin);
		int result = SSL_write(ssl, user_input, strlen(user_input));
		if (result <= 0) {
			int error = SSL_get_error(ssl, result);
			switch (error) {
				case SSL_ERROR_ZERO_RETURN:
					printf("SSL_write error: Connection closed\n");
					break;
				case SSL_ERROR_WANT_READ:
				case SSL_ERROR_WANT_WRITE:
					printf("SSL_write error: Try again later\n");
					break;
				case SSL_ERROR_SYSCALL:
					perror("SSL_write error");
					break;
				default:
					printf("SSL_write error: %d\n", error);
					break;
			}
		}

		recv_len = SSL_read(ssl, buffer, sizeof(buffer));
		printf("Received[%d] %s\n",recv_len,buffer);
	}

sslerror:
    SSL_shutdown(ssl);
    close(sock); 
    if (ssl) SSL_free(ssl);
    return 0;
}

常见错误

版本问题

新旧版本接口API会有不同

证书问题

139851570730928:error:140A90A1:lib(20):func(169):reason(161):ssl_lib.c:1966
  • lib(20) 表示错误发生在 SSL 库中。
  • func(169) 表示错误发生在 SSL 库中的某个特定函数。
  • reason(161) 表示错误的具体原因,通常表示私钥与证书不匹配或私钥格式不正确。
  • ssl_lib.c:1966 表示错误发生的源代码位置
    解决方法
  • 确认私钥格式:
    确保私钥文件 server.key 的格式是 PEM 格式。
    使用 openssl rsa -in server.key -check 来检查私钥文件是否正确。
  • 确认证书和私钥匹配:
    确保证书和私钥是由同一组密钥对生成的。
    使用 openssl x509 -pubkey -in server.crt -noout -text 获取证书中的公钥。
    使用 openssl rsa -in server.key -pubout -outform PEM 获取私钥对应的公钥,并与证书中的公钥进行比较。
  • 重新生成证书和私钥:
    如果私钥文件格式不正确或与证书不匹配,可以尝试重新生成证书和私钥文件。
    使用 OpenSSL 命令行工具重新生成文件。
  • 检查文件路径:
    确认 server.crt 和 server.key 文件的路径是正确的。
    如果文件不在当前目录下,确保提供完整的路径。
  • 设置正确的文件权限:
    确保您的程序有足够的权限读取证书和私钥文件。
    可以尝试更改文件权限以允许程序访问:chmod 600 server.crt server.key

证书格式

SSL_FILETYPE_PEM 是 OpenSSL 中用于处理 PEM (Privacy Enhanced Mail) 格式的常量。PEM
是一种广泛使用的 ASCII 编码格式,用于存储证书、密钥和其他加密数据。除了 PEM 格式之外,OpenSSL 还支持其他几种格式,例如
DER (Distinguished Encoding Rules) 格式。

PEM 格式的特点是使用 Base64 编码,并以特定的文本标记开始和结束。例如,一个 PEM 格式的私钥文件通常看起来像这样:

-----BEGIN RSA PRIVATE KEY-----
MIIEowIBAAKCAQEAwUq...
...
-----END RSA PRIVATE KEY-----

PEM 格式的证书文件通常看起来像这样:

-----BEGIN CERTIFICATE-----
MIIEowIBAAKCAQEAwUq...
...
-----END CERTIFICATE-----

DER 格式

DER 格式是一种二进制编码格式,它不包含任何文本标记。这种格式比 PEM 更紧凑,但不是文本可读的。一个 DER
格式的文件通常是一个纯二进制文件,没有额外的文本标记。

在 OpenSSL 中使用不同格式

  • 使用 PEM 格式:
    使用 SSL_FILETYPE_PEM 常量来加载 PEM 格式的证书和密钥文件。
  • 使用 DER 格式:
    使用 SSL_FILETYPE_ASN1 常量来加载 DER 格式的证书和密钥文件。

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

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

相关文章

Open3D 基于曲率大小的特征点提取

目录 一、概述 1.1原理 1.2实现步骤 1.3应用场景 二、代码实现 三、实现效果 3.1原始点云 3.2提取特征点 Open3D点云算法汇总及实战案例汇总的目录地址&#xff1a; Open3D点云算法与点云深度学习案例汇总&#xff08;长期更新&#xff09;-CSDN博客 一、概述 基于曲率…

STM32 外部中断(EXTI)

STM32 外部中断(EXTI) 实验&#xff1a;配置一个引脚的下降沿作为外部中断。 参考&#xff1a;江协科技 相关缩写 RCC(Reset and Clock Control) 复位和时钟控制 GPIO(General Purpose Input/Output) 通用输入/输出 AFIO(Alternate Function Input Output) 复用功能输入输…

6.Lab five —— Lazy Page Allocation

首先先切换到lazy分支 git checkout lazy make clean Xv6应用程序使用sbrk()系统调用向内核请求堆内存。sbrk()分配物理内存并将其映射到进程的虚拟地址空间。内核为一个大请求分配和映射内存可能需要很长时间。为了提高效率&#xff0c;故采用懒分配的策略 Eliminate alloc…

Scratch在线玩:3D地铁跑酷

小虎鲸Scratch资源站-免费Scratch作品源码,素材,教程分享平台! 作品介绍&#xff1a; 欢迎体验在 Scratch 上重新制作的 3D 地铁跑酷游戏&#xff01;这款游戏完全采用 3D 技术打造&#xff0c;带来流畅的视觉效果和出色的游戏体验。游戏的目标是避免列车和障碍物&#xff0c;同…

力扣 1419. 数青蛙

力扣 1419. 数青蛙 1. 题目 2. 思路 本题就是一道 字符串模拟题&#xff1b; 题目说到了&#xff0c; 会混杂着青蛙的叫声&#xff0c; 如果字符串 croakOfFrogs 不是由若干有效的 “croak” 字符混合而成&#xff0c;请返回 -1, 那就是说如果有多余的 c, r, o等等, 比如 &quo…

【机器学习】机器学习引领未来:赋能精准高效的图像识别技术革新

&#x1f4dd;个人主页&#x1f339;&#xff1a;Eternity._ &#x1f339;&#x1f339;期待您的关注 &#x1f339;&#x1f339; ❀目录 &#x1f50d;1. 引言&#x1f4d2;2. 机器学习基础与图像识别原理&#x1f341;机器学习概述&#xff1a;监督学习、无监督学习与强化学…

「深入理解」HTML Meta标签:网页元信息的配置

「深入理解」HTML Meta标签&#xff1a;网页元信息的配置 HTML的<meta>元素用于提供关于HTML文档的元数据&#xff08;metadata&#xff09;&#xff0c;这些信息对于浏览器和其他处理HTML文档的应用程序来说是非常有用的&#xff0c;如&#xff1a;<base>、<li…

虚幻引擎VR游戏开发02 | 性能优化设置

常识&#xff1a;VR需要保持至少90 FPS的刷新率&#xff0c;以避免用户体验到延迟或晕眩感。以下是优化性能的一系列设置&#xff08;make sure the frame rate does not drop below a certain threshold&#xff09; In project setting-> &#xff08;以下十个设置都在pr…

用于全栈自动化测试的最佳Python工具

我知道大多数测试人员会说Java是他们创建自动化测试的首选语言。 但是我最喜欢的是Python。为什么?为什么是Python ? Al Sweigart&#xff0c;《自动化那些无聊的东西》的作者&#xff0c;Python一直是他的首选语言&#xff0c;因为:它有一个温和的学习曲线。它适用于Windows…

42.哀家要长脑子了!

1.965. 单值二叉树 - 力扣&#xff08;LeetCode&#xff09; 深度优先搜索&#xff0c;看边两端的结点是不是一样的值 class Solution { public:bool isUnivalTree(TreeNode* root) {if(!root) return true;if(root->right) {if(root->val ! root->right->val || …

数字图像处理基础:图像处理概念、步骤、方式介绍

《博主简介》 小伙伴们好&#xff0c;我是阿旭。专注于人工智能、AIGC、python、计算机视觉相关分享研究。 &#x1f44d;感谢小伙伴们点赞、关注&#xff01; 《------往期经典推荐------》 一、AI应用软件开发实战专栏【链接】 项目名称项目名称1.【人脸识别与管理系统开发…

5.2.数据结构-c/c++二叉树详解(下篇)(算法面试题)

本章所有代码请见&#xff1a;5.3.数据结构-c/c二叉树代码-CSDN博客 上篇:5.数据结构-c/c二叉树详解(上篇)&#xff08;遍历方法&#xff0c;完全二叉树&#xff09;-CSDN博客 目录 1 求二叉树 第k层的节点 2 查找一个节点是否在二叉树中 3 求二叉树节点的个数 4 求二叉树…

c#笔记5 详解事件的内置类型EventHandler、windows事件在winform中的运用

为什么要研究这一问题&#xff1f; 事件和委托可以说是息息相关。 前面先解释了什么是委托&#xff0c;怎么定义一个委托以及怎么使用匿名方法来内联地新建委托。 事实上事件这一机制在c#的程序开发中展很重要的地位&#xff0c;尤其是接触了winform软件开发的同学们应该都知…

chapter12-异常(Exception)——(注解)——day14

444-异常处理入门 445-异常基本介绍 446-异常体系图 虚线代表 实现接口&#xff0c;实线代表继承 447-五大运行时异常 448-异常课堂练习 449-异常处理机制 450-tryCatch异常处理 1&#xff09;如果异常发送&#xff0c;则异常发生后面的代码不会执行&#xff0c;直接进入到Catc…

接口报错403 Forbidden 【已解决】

接口报错403 Forbidden 【已解决】 在Web开发中&#xff0c;接口请求错误是开发者经常遇到的问题之一。其中&#xff0c;403 Forbidden错误尤为常见&#xff0c;它表明服务器理解了客户端的请求&#xff0c;但是拒绝执行此请求。本文将深入探讨接口请求403 Forbidden错误&#…

iMazing 3官方中文版软件新功能全面解析,最好用的ios设备管理软件

iMazing 3是一款专为iOS设备设计的全面管理软件&#xff0c;想要更换设备的用户&#xff0c;iMazing 3的数据迁移功能能确保无缝切换。iMazing 3不仅提供了强大的备份和恢复功能&#xff0c;确保用户数据安全无虞&#xff0c;还实现了设备与电脑间的高效文件传输。无论是照片、…

浅析SVG无功补偿器在新能源发电中的应用

引言 随着新能源技术的不断进步&#xff0c;光伏发电已经崛起为未来能源发展的一个关键领域&#xff0c;各地纷纷建立起越来越多的光伏电站。然而&#xff0c;光伏发电领域仍面临诸多挑战&#xff0c;包括电网电压不稳定、发电过剩以及电压波动等问题。在这样的背景下&#xf…

《零散知识点 · Kafka 知识拓展》

&#x1f4e2; 大家好&#xff0c;我是 【战神刘玉栋】&#xff0c;有10多年的研发经验&#xff0c;致力于前后端技术栈的知识沉淀和传播。 &#x1f497; &#x1f33b; CSDN入驻不久&#xff0c;希望大家多多支持&#xff0c;后续会继续提升文章质量&#xff0c;绝不滥竽充数…

【教学类-56-04】数感训练——数字04(中2班寻找自己的学号数字,1号-29号,出现5-10\10-15\15-20次)

背景需求&#xff1a; 今天有个客户购买“学号版的数感训练” 我找到文件夹&#xff0c;发现里面没有1-40号的学号数感&#xff0c;只有上学期为重4班制作的1-31号&#xff08;其中缺了1和7号&#xff09;的数感训练模版 于是用代码重新生成 【教学类-56-03】数感训练——数字…

HarmonyOS开发实战( Beta5版)Swiper高性能开发指南

背景 在应用开发中&#xff0c;Swiper 组件常用于翻页场景&#xff0c;比如&#xff1a;桌面、图库等应用。Swiper 组件滑动切换页面时&#xff0c;基于按需加载原则通常会在下一个页面将要显示时才对该页面进行加载和布局绘制&#xff0c;这个过程包括&#xff1a; 如果该页面…