SNI (Server Name Indication) 在 TLS 握手中的作用,以及如何利用它进行某些攻击或绕过。

好嘞,各位观众老爷,欢迎来到今天的“TLS那些事儿”讲座!今天咱们不聊诗和远方,就聊聊TLS握手里面一个经常被忽略,但其实非常重要的家伙——SNI(Server Name Indication)。 一、 大家好,我是SNI,一个默默无闻的小助手 设想一下,你是一个服务器,身兼数职,同时为好几个网站提供服务(比如 example.com、example.org、example.net)。每个网站都有自己的域名和证书。当一个客户端(比如你的浏览器)来找你建立TLS连接的时候,你怎么知道它想访问哪个网站呢? 在SNI出现之前,服务器只能根据客户端请求的IP地址来判断。但问题是,很多网站都共享同一个IP地址。这意味着服务器必须使用默认证书,而这个默认证书可能和客户端真正想访问的网站不匹配。 这就尴尬了!客户端会收到证书错误警告,用户体验极差。 这时候,SNI就闪亮登场了! SNI的作用很简单:在TLS握手阶段,客户端告诉服务器它想访问哪个域名。 这样,服务器就能选择正确的证书来完成握手,避免证书不匹配的问题。 简单来说,SNI就像一个报幕员,在TLS握手的大戏开场前,告诉服务器:“观众朋友们, …

JS `import * as name`:导入所有导出成员为一个命名空间对象

各位听众,早上好!今天咱们来聊聊JavaScript里一个挺有意思的家伙:import * as name,也就是把模块里所有的宝贝一股脑儿地塞进一个命名空间对象里。这听起来有点像打包行李,把家里能带走的都塞进一个大箱子里,然后给这个箱子贴个标签。咱们就来细细琢磨一下,这个“打包”的过程,以及这个“大箱子”到底能装些啥。 一、模块化:为什么要打包? 首先,咱们得明白,为啥要搞模块化?想象一下,如果所有的代码都堆在一个文件里,那简直就是一场灾难。变量名冲突、代码混乱、难以维护,想想都头疼。模块化就像是给不同的功能划分了不同的房间,每个房间都有自己的家具(变量、函数、类),互不干扰。 JavaScript的模块化发展历程也是一部血泪史。从最初的全局变量、IIFE(立即执行函数表达式),到CommonJS(Node.js)、AMD(RequireJS)、UMD,再到现在的ES Module,一路走来,都是为了解决代码组织和依赖管理的问题。 ES Module是官方标准,也是我们今天的主角。它提供了 import 和 export 关键字,让我们可以轻松地导入和导出模块。 *二、`import …

C++ Name Mangling 与 Demangling:C++ 符号在二进制文件中的表示

哈喽,各位好! 今天咱们来聊聊C++里一个有点“神秘”,但又无处不在的东西:Name Mangling(名字修饰)与 Demangling(名字反修饰)。这玩意儿就像C++编译器给函数、变量起的小名,目的是让它们在二进制文件里区分开来,避免重名冲突。听起来是不是有点像给幼儿园小朋友编号? 准备好了吗?咱们开始吧! 1. 为什么要Name Mangling? 想象一下,如果没有Name Mangling,会发生什么? 假设你有两个文件: file1.cpp: int add(int a, int b) { return a + b; } file2.cpp: double add(double a, double b) { return a + b; } 这两个文件里都有一个名为 add 的函数,但它们的参数类型不同。如果没有Name Mangling,编译器编译后会得到两个同名的函数,链接器在链接的时候就会懵逼:“我该用哪个add呢?” 这就导致了链接错误。 Name Mangling 就是为了解决这个问题。它通过在函数名后面加上一些信息,比如参数类型、类名、命名空间等,来生成一个独一 …

C++ Name Mangling 与 Demangling:理解 C++ 符号的底层表示

好的,各位观众老爷,今天咱们来聊聊 C++ 里一个挺有意思,但也经常让人头疼的玩意儿:Name Mangling 和 Demangling。简单来说,就是 C++ 编译器怎么给函数和变量起“暗号”,以及咱们怎么把这些“暗号”翻译回人话。 第一幕:啥是 Name Mangling?为啥要有这玩意? 首先,啥是 Name Mangling?中文里,有叫“名字修饰”的,也有叫“名字改编”的,意思都差不多。它指的是 C++ 编译器为了支持函数重载、命名空间、类等特性,把函数和变量的名字进行编码,变成一个更复杂、更独特的字符串。 为啥要这么干呢?你想想,C++ 允许函数重载,也就是可以有多个函数名字一样,但是参数列表不一样。比如: int add(int a, int b) { return a + b; } double add(double a, double b) { return a + b; } 如果我们直接用 add 这个名字,编译器咋知道你调用的是哪个 add? 就算没有重载,C++还有命名空间, namespace A { void foo(); } 和 namespace B …