OpenSSL自签证书并基于Express搭建Web服务进行SSL/TLS协议分析
OpenSSL自签证书并基于Express搭建Web服务进行SSL/TLS协议分析
起因
最近在学习安全协议,大多数实验都是基于Windows下IIS,或者Linux下nginx搭建的Web服务,搭建环境和编写配置文件比较麻烦。而且我有多个不同环境的设备,折腾起来也比较麻烦,最好是开箱即用。
所以我就用nodejs + express写了个跨平台的项目专门用于对比没有使用SSL/TLS的http与使用了的https协议。
如果你对代码不感兴趣,仅是想要分析协议,可以到文章末尾的Github仓库中去下载该项目运行即可。
搭建环境
安装nodejs,访问官网https://nodejs.org,建议下载LTS版本并安装
node --version
npm --version
运行上方命令出现版本号即可。
在终端中运行如下命令安装yarn
npm -g install yarn
yarn --version
出现版本号即为成功。
另外需要搭建OpenSSL环境,这个教程网上有很多,请自行搜索。
代码部分
接下来主要分享代码编写思路。
目录结构
创建项目目录为http_ssl
,并在终端中进入
mkdir http_ssl
cd http_ssl
使用yarn初始化,按照提示填写或者一路回车即可
yarn init
创建静态资源目录、配置文件目录、源码目录
mkdir asset
mkdir config
mkdir src
安装依赖
添加express包等
yarn add express
在package.json
文件中修改type
为module
,将语法为ES6,并编写启动命令scripts
。(如果没有直接添加)
"type":"module",
"scripts":{"start":"node ./src/index.js"
}
完整文件大致如下
{"name": "http_ssl","version": "1.0.0","main": "index.js","author": "cairbin","license": "MIT","dependencies": {"express": "^4.19.2"},"type":"module","scripts":{"start":"node ./src/index.js"}
}
初始文件
我们希望http和https的端口号、主机地址之类的都能够放在配置文件里,而非代码中,这样方便我们更改,于是编写配置文件。
touch config/config.js
我们这里为了让配置文件能够像模块一样倒入,直接为js
后缀,编辑该文件
// config/config.js
export default {server:{static: '../asset', //静态资源目录,注意'../',因为index.js在src下,否则找不到这个目录http:{host: "localhost", //主机地址port: 8848 //端口号},https:{host:'localhost',port:8849}}
}
创建src/index.js
为程序入口,我们编写的启动命令就是运行这个文件的
touch src/index.js
然后编写一个404.html
的静态文件
mkdir asset/html/
touch asset/html/404.html
<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>404 Page</title>
</head>
<body><h1>404 NOT FOUND</h1>
</body>
</html>
辅助模块
项目还需要日志功能,我们没必要搞太复杂,想要功能强大的可以引入winston
包,我这里就简单封装下js自带的console.*
mkdir src/utils/
touch src/utils/logger.js
// src/utils/logger.js
const log = (options)=>{console[options.type](`[${options.type.toUpperCase()}] ${options.msg}`)
}const info = (msg)=>{log({type:"info",msg:msg});
}const warn = (msg)=>{log({type:'warn',msg:msg});
}const error = (msg)=>{log({type:'error',msg:msg});
}export default{info,warn,error
}
控制器
尽管是个Demo,但最好还是遵循MVC,我们创建目录和文件,编写一个简单控制器
mkdir src/controller/
touch src/controller/defaultController.js
// src/controller/defaultController.js
import logger from './../utils/logger.js'; //日志模块const defaultFunc = (req, res, next)=>{logger.info('exec defultController.defaultFunc');res.status(500).send('Hello World!'); //为了抓包分析方便,返回500状态码而非200
}export default{defaultFunc
}
这里注意,为了抓包方便观察,我们返回的Code为500,而不是200。
路由
创建Express的路由
mkdir src/route/
touch src/route/defaultRoute.js
// src/route/defaultRoute.js
import express from "express";
import defaultController from './../controller/defaultController.js';
import logger from './../utils/logger.js'; //日志模块const router = express.Router();router.get('/',(req,res,next)=>{logger.info('defaultRoute, path=/');defaultController.defaultFunc(req, res, next);
})export default router;
创建服务
创建http和https服务,指定静态资源目录,设置404页面,并集成使用以上编写的文件
// src/index.js
import express from 'express';
import https from 'https';
import http from 'http';
import defaultRoute from './route/defaultRoute.js'
import fs, { copyFile } from 'fs';
import path from 'path';
import { dirname } from "node:path";
import { fileURLToPath } from "node:url"
import config from './../config/config.js';
import logger from './utils/logger.js';const __filename = fileURLToPath(import.meta.url)
const __dirname = dirname(__filename)const app = express();
const httpsServer = https.createServer({key:fs.readFileSync('keys/private.pem'),cert:fs.readFileSync('keys/file.crt')
},app)
const httpServer = http.createServer({},app);//static path
app.use(express.static(path.join(__dirname, config.server.static)));
logger.info(`static file path '${path.join(__dirname, config.server.static)}'`);app.use('/',defaultRoute);
// 404 page
app.use('*',(req,res)=>{res.redirect('./html/404.html')
})httpsServer.listen(config.server.https.port, config.server.https.host, ()=>{logger.info(`https service is running on https://${config.server.https.host}:${config.server.https.port}`);
})httpServer.listen(config.server.http.port, config.server.http.host, ()=>{logger.info(`http service is running on http://${config.server.http.host}:${config.server.http.port}`);
})
你会发现keys
这个用于存放证书的目录以及证书文件并不存在,我们接下来创建它们项目才能运行。
另外需注意,上面的静态资源目录用path.join()
来设为绝对路径。
生成证书
我们使用OpenSSL自签一个证书,在macOS或者Linux下可编写脚本
touch generate.sh
# generate.sh
mkdir -p keys
openssl genrsa 4096 > keys/private.pem
openssl req -new -key keys/private.pem -out keys/csr.pem
openssl x509 -req -days 365 -in keys/csr.pem -signkey keys/private.pem -out keys/file.crt
然后运行脚本
sh generate.sh
如果是Windows的话也可以编写.bat
批处理文件,或者直接执行命令:
mkdir keys
openssl genrsa 4096 > keys/private.pem
openssl req -new -key keys/private.pem -out keys/csr.pem
openssl x509 -req -days 365 -in keys/csr.pem -signkey keys/private.pem -out keys/file.crt
注意旧版本的CMD或PowerShell可能不支持/
,可以改用\
,可能需要转义字符\\
运行项目
执行我们编写好的指令(package.json
那里的)运行项目:
yarn run start
正常情况下,控制台应该是在报[INFO]
浏览器地址栏输入http://localhost:8848
,即可看到Hello World!
页面(最指定协议头,有些浏览器会自动填充为https)
https的话请访问https://localhost:8849
,正常来讲现代的浏览器会阻止你访问这个页面,并提示非私人连接不安全,因为我们用的是自签名的证书。
直接无视风险,继续访问(doge)
抓包分析
关闭页面,在浏览器的设置里,清除浏览器缓存(这一步很重要,因为我们之前访问过页面了,浏览器为了加速一般都会有缓存导致下次访问时不是向服务器请求,而是加载本地缓存的页面,导致抓包失败)
启动wireshark并进行抓包,与其他情况不同,由于是回环地址,所以我们要抓loopback的包
先来访问http未加密的页面,在wireshark中使用过滤器过滤http的包,该项目为了排除抓包的时候的干扰,访问页面返回的状态码为500,而不是200,所以我们只需要找到http status 为500的包即可
查看数据,果然是明文
再以https协议的方式访问一次并进行抓包
发现抓不到了,我们将过滤器条件改为tls
由此看到数据都被保护起来了,即使抓到也都是密文。
Wireshark是直接看到TLS封包的内容的,我们可以配置环境变量,让浏览器得到的preMasterKey放到指定log中,wireshark支持读取这个文件,然后再进行抓包就可以查看加密的数据了。
文章可以参考 https://segmentfault.com/a/1190000018746027
代码仓库
Click CairBin/SecurityProtocolLab
相关文章:

OpenSSL自签证书并基于Express搭建Web服务进行SSL/TLS协议分析
OpenSSL自签证书并基于Express搭建Web服务进行SSL/TLS协议分析 起因 最近在学习安全协议,大多数实验都是基于Windows下IIS,或者Linux下nginx搭建的Web服务,搭建环境和编写配置文件比较麻烦。而且我有多个不同环境的设备,折腾起来…...

记录一次 vue2 前端项目整合过程
整合成功效果图 具体说明: 项目A是现在的vue2前端项目,项目B是一个开源的工作流前端,项目后端代码已经整合了,就不多提了。这里主要记录下前端整合的过程和思路。 1、开源工作流里面的功能,拷贝到自己对应的vue2项目里…...

物联网五层架构分析
物联网五层架构分析 随着科技的迅速发展,物联网(IoT)作为日常生活中不可或缺的一部分,已融入人们的生活和工作中。物联网五层架构,包括感知层、网络层、数据层、应用层和业务层,扮演着关键的角色。 感知层 …...

【Java EE】多线程(三)线程状态
📚博客主页:爱敲代码的小杨. ✨专栏:《Java SE语法》 | 《数据结构与算法》 | 《C生万物》 |《MySQL探索之旅》 |《Web世界探险家》 ❤️感谢大家点赞👍🏻收藏⭐评论✍🏻,您的三连就是我持续更…...
FFmpeg常用API与示例(一)—— 工具库篇(av_log、AVDictionary、avio)
工具层 1.av_log 可以设置日志的级别,这个看看名字就明白了,也不用过多的解释。 AV_LOG_PANICAV_LOG_FATALAV_LOG_ERRORAV_LOG_WARNINGAV_LOG_INFOAV_LOG_VERBOSEAV_LOG_DEBUG void test_log() {/ av_register_all();AVFormatContext *pAVFmtCtx NU…...

日志的基本用法
目标 1. 掌握如何设置日志级别 2. 掌握如何设置日志格式 3. 掌握如何将日志信息输出到文件中 1. logging模块 Python中有一个标准库模块logging可以直接记录日志 1.1 基本用法 import logging logging.debug("这是一条调试信息") logging.info("这是一条…...

什么是页分裂、页合并?
数据组织方式 在InnoDB存储引擎中,表数据都是根据主键顺序组织存放的,这种存储方式的表称为索引组织表(index organized table IOT)。 行数据,都是存储在聚集索引的叶子节点上的。而我们之前也讲解过InnoDB的逻辑结构图: 在I…...

软件2班20240513
第三次作业 package com.yanyu;import java.sql.*; import java.util.ResourceBundle;public class JDBCTest01 {public static void main(String[] args) {ResourceBundle bundle ResourceBundle.getBundle("com/resources/db");// ctrl alt vString driver …...

嵌入式学习-时钟树
时钟树 时钟分类 时钟树框图 LSI与LSE HSI、HSE与PLL 系统时钟的产生 AHB、APBx的时钟配置 相关寄存器 寄存器部分的细节内容请参考手册。 相关库函数...

对博客系统基本功能进行自动化测试(Junit + Selenium)
环境搭建: 浏览器: 本次测试使用Chrome浏览器在jdk的bin目录下安装对应浏览器驱动(尽量选择与浏览器版本相近的驱动)chromedriver.storage.googleapis.com/index.htmlJunit依赖: <!-- https://mvnreposit…...

《换你来当爹》:AI驱动的养成游戏,探索虚拟亲子关系的新模式
AI技术如何重塑我们对游戏互动的认知 在人工智能技术的浪潮下,一款名为《换你来当爹》的AI养成游戏,以其创新的互动模式和个性化体验,吸引了游戏爱好者的目光。这款游戏利用了先进的LLM技术,通过AI实时生成剧情和图片,…...

在idea中使用vue
一、安装node.js 1、在node.js官网(下载 | Node.js 中文网)上下载适合自己电脑版本的node.js压缩包 2、下载完成后进行解压并安装,一定要记住自己的安装路径 一直点击next即可,这部选第一个 3、安装成功后,按住winR输入…...

Linux系统编程:进程控制
1.进程创建 1.1 fork函数 fork()通过复制调用进程来创建一个新进程。新进程称为子进程,是调用进程的精确副本 进程,但以下几点除外: 子进程有自己的PID,此PID与任何现有进程组的ID不匹配子进程的父进程ID…...

Android 异常开机半屏重启代码分析
Android 的稳定性是 Android 性能的一个重要指标,它也是 App 质量构建体系中最基本和最关键的一环;如果应用经常崩溃,或者关键功能不可用,那显然会对我们的留存产生重大影响所以为了保障应用的稳定性,我们首先应该树立…...

Kafka从0到消费者开发
安装ZK Index of /zookeeper/zookeeper-3.9.2 下载安装包 一定要下载-bin的,不带bin的是源码,没有编译的,无法执行。-bin的才可以执行。 解压 tar -zxvf apache-zookeeper-3.9.2-bin.tar.gz 备份配置 cp zoo_sample.cfg zoo_sample.cfg-b…...

01-项目功能,架构设计介绍
稻草快速开发平台 开发背景就是通过此项目介绍使用SpringBoot Vue3两大技术栈开发一个拥有动态权限、路由的前后端分离项目,此项目可以继续完善,成为一个模板为将来快速开发做铺垫。 实现功能 开发流程 通过命令构建前端项目在VSCode中开发ÿ…...

bvh 好用强大的播放器源码
目录 效果图: 显示旋转角度: 显示骨骼名称 下载链接: 可以显示骨骼名称,旋转角度,自适应大小,支持3维npz数据可视化 python实现,提供源代码,修改和完善很方便。 根据3维npz生成…...
安阳在线知识付费系统,培训机构如何进行课程体系的设置?
校外培训不管是从招生还是课程体系都是截然不同的,在课程体系设置上,不同的层次设计也就不同。课程体系设计在功能诉求上可以分为入门课、核心课、高利润课、种子课四个类别。下面为大家介绍一下。 1、入门课 “入门课”就是最易、最省、最少障碍的满足家…...

网络编程:服务器模型-并发服务器-多进程
并发服务器概念: 并发服务器同一时刻可以处理多个客户机的请求 设计思路: 并发服务器是在循环服务器基础上优化过来的 (1)每连接一个客户机,服务器立马创建子进程或者子线程来跟新的客户机通信 (accept之后…...
React 基础案例
React的特点: 1、声明式编程 2、组件化开发 3、多平台适配yuan 原生实现: <h2 class"title"></h2><button class"btn">改变文本</button><script>let msg "Hello World";const titleEl d…...

深入浅出Asp.Net Core MVC应用开发系列-AspNetCore中的日志记录
ASP.NET Core 是一个跨平台的开源框架,用于在 Windows、macOS 或 Linux 上生成基于云的新式 Web 应用。 ASP.NET Core 中的日志记录 .NET 通过 ILogger API 支持高性能结构化日志记录,以帮助监视应用程序行为和诊断问题。 可以通过配置不同的记录提供程…...

多模态2025:技术路线“神仙打架”,视频生成冲上云霄
文|魏琳华 编|王一粟 一场大会,聚集了中国多模态大模型的“半壁江山”。 智源大会2025为期两天的论坛中,汇集了学界、创业公司和大厂等三方的热门选手,关于多模态的集中讨论达到了前所未有的热度。其中,…...
rknn优化教程(二)
文章目录 1. 前述2. 三方库的封装2.1 xrepo中的库2.2 xrepo之外的库2.2.1 opencv2.2.2 rknnrt2.2.3 spdlog 3. rknn_engine库 1. 前述 OK,开始写第二篇的内容了。这篇博客主要能写一下: 如何给一些三方库按照xmake方式进行封装,供调用如何按…...
【磁盘】每天掌握一个Linux命令 - iostat
目录 【磁盘】每天掌握一个Linux命令 - iostat工具概述安装方式核心功能基础用法进阶操作实战案例面试题场景生产场景 注意事项 【磁盘】每天掌握一个Linux命令 - iostat 工具概述 iostat(I/O Statistics)是Linux系统下用于监视系统输入输出设备和CPU使…...

MODBUS TCP转CANopen 技术赋能高效协同作业
在现代工业自动化领域,MODBUS TCP和CANopen两种通讯协议因其稳定性和高效性被广泛应用于各种设备和系统中。而随着科技的不断进步,这两种通讯协议也正在被逐步融合,形成了一种新型的通讯方式——开疆智能MODBUS TCP转CANopen网关KJ-TCPC-CANP…...

CMake 从 GitHub 下载第三方库并使用
有时我们希望直接使用 GitHub 上的开源库,而不想手动下载、编译和安装。 可以利用 CMake 提供的 FetchContent 模块来实现自动下载、构建和链接第三方库。 FetchContent 命令官方文档✅ 示例代码 我们将以 fmt 这个流行的格式化库为例,演示如何: 使用 FetchContent 从 GitH…...
Mobile ALOHA全身模仿学习
一、题目 Mobile ALOHA:通过低成本全身远程操作学习双手移动操作 传统模仿学习(Imitation Learning)缺点:聚焦与桌面操作,缺乏通用任务所需的移动性和灵活性 本论文优点:(1)在ALOHA…...

华硕a豆14 Air香氛版,美学与科技的馨香融合
在快节奏的现代生活中,我们渴望一个能激发创想、愉悦感官的工作与生活伙伴,它不仅是冰冷的科技工具,更能触动我们内心深处的细腻情感。正是在这样的期许下,华硕a豆14 Air香氛版翩然而至,它以一种前所未有的方式&#x…...

Qemu arm操作系统开发环境
使用qemu虚拟arm硬件比较合适。 步骤如下: 安装qemu apt install qemu-system安装aarch64-none-elf-gcc 需要手动下载,下载地址:https://developer.arm.com/-/media/Files/downloads/gnu/13.2.rel1/binrel/arm-gnu-toolchain-13.2.rel1-x…...

Golang——7、包与接口详解
包与接口详解 1、Golang包详解1.1、Golang中包的定义和介绍1.2、Golang包管理工具go mod1.3、Golang中自定义包1.4、Golang中使用第三包1.5、init函数 2、接口详解2.1、接口的定义2.2、空接口2.3、类型断言2.4、结构体值接收者和指针接收者实现接口的区别2.5、一个结构体实现多…...