Python3与Java Hutool实现SM2国密算法跨语言加解密互通方案
1. 项目概述与核心价值最近在做一个需要跨语言数据交换的项目后端是Java用到了Hutool这个“瑞士军刀”库来处理SM2国密算法的加解密而另一个数据处理服务是用Python3写的。这就引出了一个很实际的问题Java这边用Hutool加密的数据Python那边怎么解反过来Python生成的数据Java这边又如何用SM2解密网上搜了一圈发现关于SM2跨语言互通的资料要么语焉不详要么就是代码跑不通特别是Python这边各种库的兼容性让人头大。所以我花了些时间把这条路彻底走通了形成了一套稳定、可复现的Python3与Java Hutool库SM2加解密互通方案。简单来说这个方案的核心目标就是打破语言壁垒让JavaHutool和Python3能够使用同一套SM2密钥对毫无障碍地进行加密和解密操作。这不仅仅是“能跑通”更要保证在真实的生产环境中数据传输的完整性和安全性。无论是微服务间的敏感配置下发还是跨平台系统的数据安全同步这个需求都非常普遍。接下来我就把从原理梳理、环境搭建、代码实现到踩坑排雷的全过程毫无保留地分享出来。2. SM2算法互通的核心原理与挑战2.1 SM2算法简述与Hutool的实现特点SM2是国家密码管理局发布的椭圆曲线公钥密码算法标准属于非对称加密。它包含数字签名、密钥交换和公钥加密三大功能我们这里聚焦于公钥加密。一个关键点是SM2加密并非直接使用原始的公钥加密数据其标准流程GM/T 0009-2012包含了一个关键的密钥派生函数KDF和消息认证码MAC计算最终输出的是C1C2C3或C1C3C2格式的密文其中C1是椭圆曲线点C2是密文C3是SM3摘要。Hutool的SmUtil.sm2()默认生成的密钥对是PKCS#8格式的私钥和X.509格式的公钥这是Java生态里的标准。在加密时Hutool默认输出的是ASN.1编码的C1C2C3格式密文通过BC库实现。而Python这边常见的gmssl、cryptography等库对SM2的支持方式和默认输出格式可能不同这就是互通的第一个拦路虎密文格式必须统一。2.2 跨语言互通的核心挑战解析实现互通主要需要攻克三个堡垒密钥格式兼容Java生成的PKCS#8私钥和X.509公钥Python要能正确识别和加载。反之亦然。密文格式对齐双方必须约定并使用同一种密文排列顺序C1C2C3或C1C3C2和编码方式通常是ASN.1 DER编码。Hutool默认使用ASN.1 DER编码的C1C2C3。椭圆曲线参数一致必须使用相同的椭圆曲线。SM2标准曲线参数是固定的sm2p256v1但不同库的标识方式可能略有差异需要确保一致。如果格式不对最常见的错误就是“无效的密文格式”、“点解码失败”或者解密出来一堆乱码。我们的解决方案思路很明确以Java Hutool的输出为标准让Python端去适配它。因为在实际项目中加解密标准往往由主导系统或先存在的系统决定。3. 环境准备与核心工具库选型3.1 Java端环境与Hutool配置Java端很简单假设你有一个Maven或Gradle项目。Maven依赖dependency groupIdcn.hutool/groupId artifactIdhutool-all/artifactId version5.8.25/version !-- 请使用最新稳定版 -- /dependencyHutool内置了Bouncy CastleBC库的轻量级封装无需额外引入BC依赖即可使用SM2。关键点确保你项目里没有其他版本BC库的冲突。如果遇到NoSuchAlgorithmException或ClassNotFoundException可以尝试显式引入BC库dependency groupIdorg.bouncycastle/groupId artifactIdbcprov-jdk15to18/artifactId version1.75/version /dependency3.2 Python端库的选择与gmssl的安装Python这边有几个候选gmssl、cryptography结合sm2crypto、pysmx。为了最直接地兼容国密标准我们选择**gmssl**库。它是OpenSSL的一个分支对SM2/SM3/SM4支持比较原生。安装gmsslpip install gmssl-python如果安装缓慢或失败可以使用国内镜像源pip install gmssl-python -i https://pypi.tuna.tsinghua.edu.cn/simple注意有一个同名的gmssl包pip install gmssl功能较弱我们需要的的是gmssl-python。安装后在Python中应使用from gmssl import sm2, sm3, sm4来导入。为什么选gmssl因为它底层是C/C实现性能较好且其SM2密文格式通过特定配置可以与BC库生成的ASN.1 DER格式兼容。而纯Python实现的sm2crypto等库在处理Hutool的密文时可能需要更多的格式转换工作。4. 密钥生成与格式转换Java主导互通的第一步是拥有双方都能识别的密钥对。我们由JavaHutool来生成然后导出供Python使用。4.1 Java端生成并导出密钥import cn.hutool.crypto.SmUtil; import cn.hutool.crypto.asymmetric.KeyType; import cn.hutool.crypto.asymmetric.SM2; import org.bouncycastle.util.encoders.Base64; import java.nio.charset.StandardCharsets; public class JavaSm2KeyGen { public static void main(String[] args) { // 1. 生成SM2密钥对 SM2 sm2 SmUtil.sm2(); // 获取私钥和公钥Base64编码格式 String privateKeyBase64 sm2.getPrivateKeyBase64(); String publicKeyBase64 sm2.getPublicKeyBase64(); System.out.println( Java生成的SM2密钥对 ); System.out.println(私钥 (PKCS#8 Base64):\n privateKeyBase64); System.out.println(\n公钥 (X.509 Base64):\n publicKeyBase64); // 2. 测试加密解密自验证 String plainText Hello, Python! 这是来自Java的测试数据。; System.out.println(\n原始明文: plainText); // 使用公钥加密 byte[] encrypted sm2.encrypt(plainText.getBytes(StandardCharsets.UTF_8), KeyType.PublicKey); String cipherTextBase64 Base64.toBase64String(encrypted); System.out.println(加密后密文 (Base64):\n cipherTextBase64); // 使用私钥解密 byte[] decrypted sm2.decrypt(encrypted, KeyType.PrivateKey); System.out.println(Java解密结果: new String(decrypted, StandardCharsets.UTF_8)); } }运行这段代码你会得到三样关键输出Base64编码的私钥、公钥以及一个用该密钥对加密后的示例密文。请务必保存好privateKeyBase64和publicKeyBase64这两个字符串它们是后续Python端操作的基石。4.2 密钥格式的深入理解与Python端准备Hutool导出的私钥是PKCS#8格式的DER编码再进行Base64。公钥是X.509格式的DER编码再进行Base64。Python的gmssl的sm2类在初始化时需要的是原始的PEM格式或裸的十六进制/字节串形式的密钥。因此我们需要在Python端进行一个简单的转换将Base64字符串解码成字节并去除PEM的头部尾部如果有的话或者直接作为裸密钥字节传入。对于gmssl的sm2.CryptSM2类它接受字节形式的私钥和公钥。这里有一个关键技巧Hutool生成的Base64公钥解码后的字节就是X.509 DER编码的公钥这个可以直接被gmssl识别。私钥同理。5. Python端适配与加解密实现现在我们有了Java生成的密钥和密文开始在Python端进行适配和解密。5.1 Python端加载密钥并解密Java密文创建一个Python脚本例如python_sm2_interop.pyimport base64 from gmssl import sm2, sm3, func # 1. 粘贴从Java控制台输出的密钥和密文 # 替换成你自己Java程序生成的密钥和密文 private_key_base64_java 你的Java生成的私钥Base64字符串 public_key_base64_java 你的Java生成的公钥Base64字符串 cipher_text_base64_from_java 你的Java生成的密文Base64字符串 # 2. 将Base64密钥解码为字节 private_key_bytes base64.b64decode(private_key_base64_java) public_key_bytes base64.b64decode(public_key_base64_java) print( Python端加载Java生成的密钥 ) print(f私钥字节长度: {len(private_key_bytes)}) print(f公钥字节长度: {len(public_key_bytes)}) # 3. 初始化SM2对象 # gmssl的sm2.CryptSM2默认使用C1C3C2顺序但Hutool(BC)默认是C1C2C3。 # 我们需要指定正确的密文顺序。根据测试Hutool 5.8.x 默认输出 ASN.1 DER 编码的 C1C2C3。 # gmssl 的 decrypt 方法需要指定 asn1_encodingTrue 来解码ASN.1格式并指定 cipher_flag0 对应 C1C2C3。 crypt_sm2 sm2.CryptSM2(private_keyprivate_key_bytes, public_keypublic_key_bytes) # 4. 解密Java生成的密文 cipher_bytes base64.b64decode(cipher_text_base64_from_java) try: # 关键参数asn1_encodingTrue 表示密文是ASN.1 DER编码 # cipher_flag0 表示密文顺序是 C1C2C3 (这是BC库和Hutool的默认顺序) decrypted_bytes crypt_sm2.decrypt(cipher_bytes, cipher_flag0, asn1_encodingTrue) decrypted_text decrypted_bytes.decode(utf-8) print(f\n解密Java密文成功) print(f解密结果: {decrypted_text}) except Exception as e: print(f\n解密失败: {e}) # 如果失败尝试另一种顺序 cipher_flag1 (C1C3C2) try: decrypted_bytes crypt_sm2.decrypt(cipher_bytes, cipher_flag1, asn1_encodingTrue) decrypted_text decrypted_bytes.decode(utf-8) print(f尝试 cipher_flag1 成功解密结果: {decrypted_text}) except Exception as e2: print(f尝试 cipher_flag1 也失败: {e2})核心参数解释cipher_flag0: 指定密文组成部分的顺序为C1 || C2 || C3。这是Bouncy Castle和Hutool的默认输出顺序。asn1_encodingTrue: 告知gmssl传入的密文不是简单的拼接字节而是经过了ASN.1 DER编码的。这是互通成功最关键的一步如果设为False解密一定会失败。5.2 Python端加密数据供Java解密反过来Python加密Java解密也需要保证格式一致。# 接上面的代码 # 5. Python端使用公钥加密数据供Java解密 plain_text_for_java Hello from Python! 这是Python加密的数据。 print(f\n Python端加密数据 ) print(f待加密明文: {plain_text_for_java}) # 加密时同样指定 asn1_encodingTrue让 gmssl 输出 ASN.1 DER 编码的密文 # 加密默认使用 C1C2C3 顺序与cipher_flag0对应 encrypted_bytes_from_python crypt_sm2.encrypt(plain_text_for_java.encode(utf-8), asn1_encodingTrue) cipher_text_base64_from_python base64.b64encode(encrypted_bytes_from_python).decode(ascii) print(f加密后密文 (Base64):\n{cipher_text_base64_from_python}) print(\n 供Java端验证的信息 ) print(fPython生成的密文Base64: {cipher_text_base64_from_python}) print(f请将此密文复制到Java程序中使用对应的私钥解密。)运行这个Python脚本。如果一切顺利你应该能看到成功解密了Java生成的密文还原出“Hello, Python! ...”。生成了一个新的密文cipher_text_base64_from_python。5.3 Java端解密Python生成的密文回到Java端编写解密代码import cn.hutool.crypto.SmUtil; import cn.hutool.crypto.asymmetric.KeyType; import cn.hutool.crypto.asymmetric.SM2; import org.bouncycastle.util.encoders.Base64; import java.nio.charset.StandardCharsets; public class JavaSm2DecryptFromPython { public static void main(String[] args) { // 使用之前生成的同一对密钥Base64字符串 String privateKeyBase64 你的Java生成的私钥Base64字符串; String publicKeyBase64 你的Java生成的公钥Base64字符串; // 从Python控制台输出的密文 String cipherTextBase64FromPython 你的Python生成的密文Base64字符串; // 使用密钥初始化SM2对象 SM2 sm2 SmUtil.sm2(privateKeyBase64, publicKeyBase64); try { byte[] encryptedData Base64.decode(cipherTextBase64FromPython); byte[] decryptedData sm2.decrypt(encryptedData, KeyType.PrivateKey); String decryptedText new String(decryptedData, StandardCharsets.UTF_8); System.out.println(解密Python密文成功); System.out.println(解密结果: decryptedText); } catch (Exception e) { System.err.println(解密失败: e.getMessage()); e.printStackTrace(); } } }运行这个Java程序如果输出了“Hello from Python! ...”那么恭喜你双向互通已经完全实现6. 常见问题、排查技巧与深度优化在实际操作中你可能会遇到各种问题。下面是我踩过坑后总结的排查清单和优化建议。6.1 问题排查速查表问题现象可能原因解决方案Python解密失败ValueError: invalid ASN.1 DER encoding或解密结果为空/乱码1. 密文Base64解码错误或传输损坏。2.asn1_encoding参数设置错误。3.cipher_flag顺序不对。4. 使用的公钥/私钥不配对。1. 检查并确保密文Base64字符串完整无误无换行、空格。2.确保Python解密时asn1_encodingTrue。3. 依次尝试cipher_flag0和cipher_flag1。4. 核对Java和Python加载的是否是同一密钥对。Java解密失败Invalid point encoding或Not an EC key1. Python加密时未使用asn1_encodingTrue导致输出的密文格式Java无法识别。2. 密钥格式错误或损坏。1.确保Python加密时asn1_encodingTrue。2. 确认Java加载的私钥是PKCS#8格式的Base64。gmssl导入密钥失败ValueError: invalid private keyHutool导出的私钥Base64是PKCS#8格式gmssl的CryptSM2默认期望的是裸的EC私钥值32字节。解决方案使用gmssl的sm2.SM2PrivateKey和sm2.SM2PublicKey类来解析PKCS#8/X.509格式。详见6.2节优化方案。加解密性能较慢Pythongmssl的encrypt/decrypt在大量数据时可能成为瓶颈。1. SM2非对称加密本身不适合加密大数据。实际应用中应先使用SM2加密一个随机的对称密钥如SM4密钥再用SM4加密数据。2. 考虑对固定数据做缓存。6.2 深度优化更健壮的密钥加载方式上述直接使用字节加载密钥的方式依赖于gmssl内部对格式的猜测。更健壮的方式是使用gmssl提供的密钥解析类显式地处理PKCS#8和X.509格式。from gmssl import sm2, sm3 import base64 def load_private_key_from_pkcs8_base64(private_key_base64): 从Hutool生成的PKCS#8 Base64私钥加载 from gmssl.sm2 import SM2PrivateKey der_bytes base64.b64decode(private_key_base64) # SM2PrivateKey.from_pkcs8 可以解析PKCS#8 DER格式 private_key SM2PrivateKey.from_pkcs8(der_bytes) # 获取裸的私钥值32字节整数 private_key_value private_key.private_key return private_key_value def load_public_key_from_x509_base64(public_key_base64): 从Hutool生成的X.509 Base64公钥加载 from gmssl.sm2 import SM2PublicKey der_bytes base64.b64decode(public_key_base64) # SM2PublicKey.from_der 可以解析X.509 DER格式 public_key SM2PublicKey.from_der(der_bytes) # 获取裸的公钥点04 || x || y 格式65字节 public_key_bytes public_key.to_bytes() return public_key_bytes # 使用方式 private_key_base64_java MIGHAgEAMBMGByqGSM49AgEGCC...你的私钥 public_key_base64_java MFkwEwYHKoZIzj0CAQYIKoEcz1UBgi0D...你的公钥 private_key_value load_private_key_from_pkcs8_base64(private_key_base64_java) public_key_bytes load_public_key_from_x509_base64(public_key_base64_java) # 初始化SM2对象此时传入的是裸密钥值 crypt_sm2 sm2.CryptSM2(private_keyprivate_key_value.to_bytes(32, byteorderbig), public_keypublic_key_bytes)这种方式从根本上解决了密钥格式兼容性问题是生产环境推荐的做法。6.3 关于密文顺序C1C2C3 vs C1C3C2的终极确定不同库、不同版本的默认顺序可能不同。最可靠的方法不是猜而是测试。你可以用Java加密一个短字符串然后在Python端用两种cipher_flag(0和1)分别尝试解密哪个能成功解出明文就说明Hutool当前版本使用的是哪种顺序。根据我的测试Hutool 5.8.x BC 1.75默认顺序是C1C2C3对应cipher_flag0。7. 完整示例代码与集成测试为了确保可靠性我们可以编写一个简单的集成测试循环Java加密 - Python解密 - Python加密 - Java解密验证数据一致性。Java端测试类import cn.hutool.core.util.HexUtil; import cn.hutool.crypto.SmUtil; import cn.hutool.crypto.asymmetric.KeyType; import cn.hutool.crypto.asymmetric.SM2; import org.bouncycastle.util.encoders.Base64; import java.nio.charset.StandardCharsets; public class Sm2InteropTest { private static final String PRIVATE_KEY_BASE64 你的私钥; private static final String PUBLIC_KEY_BASE64 你的公钥; private static final SM2 SM2 SmUtil.sm2(PRIVATE_KEY_BASE64, PUBLIC_KEY_BASE64); public static void main(String[] args) throws Exception { String originalText 跨语言SM2互通测试数据12345ABC!#; System.out.println( Java端开始 ); // 1. Java加密 byte[] encryptedByJava SM2.encrypt(originalText.getBytes(StandardCharsets.UTF_8), KeyType.PublicKey); String cipherJavaB64 Base64.toBase64String(encryptedByJava); System.out.println(Java加密密文(B64): cipherJavaB64); // 模拟网络传输... System.out.println(\n 假设Python端已解密并返回新密文 ); // 此处应粘贴从Python端控制台获取的新密文 String cipherFromPythonB64 从Python脚本复制过来的密文Base64; byte[] encryptedFromPython Base64.decode(cipherFromPythonB64); // 2. Java解密Python的密文 byte[] decryptedByJava SM2.decrypt(encryptedFromPython, KeyType.PrivateKey); System.out.println(Java解密Python密文结果: new String(decryptedByJava, StandardCharsets.UTF_8)); // 验证一致性 if (originalText.equals(new String(decryptedByJava, StandardCharsets.UTF_8))) { System.out.println(\n✅ 双向互通测试成功); } else { System.out.println(\n❌ 测试失败数据不一致。); } } }Python端测试脚本将6.2节的优化密钥加载方法和加解密逻辑整合形成一个完整的接收Java密文、解密、再加密返回的脚本。通过手动或简单的Socket通信传递Base64密文字符串即可完成闭环测试。经过这样一套流程的打磨Python3与Java Hutool的SM2加解密互通就不再是黑盒。关键在于牢牢抓住密钥格式、密文ASN.1 DER编码和C1C2C3顺序这三个锚点。在实际项目集成时建议将密钥加载和加解密逻辑封装成双方统一的工具类并编写详尽的单元测试覆盖边界情况和异常输入这样才能保证在复杂的生产环境中稳定运行。

相关新闻

电商App签名逆向实战:从x-sign/x-miniwua看移动端安全防线

电商App签名逆向实战:从x-sign/x-miniwua看移动端安全防线

1. 项目概述:为什么我们要研究x-sign/x-miniwua? 如果你做过电商数据相关的爬虫或者自动化工具,那么“签名”这个词对你来说一定不陌生。它就像一道门禁,横亘在你和服务器数据之间。而某宝的 x-sign 和 x-miniwua &#xff0c…

2026/7/5 0:27:49 阅读更多 →
AI绘画提示词编写与优化全指南

AI绘画提示词编写与优化全指南

1. AI绘画提示词(Prompt)编写核心逻辑解析AI绘画的核心在于将自然语言描述转化为视觉元素,这个过程本质上是一种跨模态的信息转换。理解这个转换机制是编写优质Prompt的基础。现代AI绘画模型如Stable Diffusion、MidJourney都建立在扩散模型(Diffusion Model)架构上…

2026/7/5 0:25:48 阅读更多 →
如何在Windows家庭版上启用专业级远程桌面:RDP Wrapper Library终极指南(2024版)

如何在Windows家庭版上启用专业级远程桌面:RDP Wrapper Library终极指南(2024版)

如何在Windows家庭版上启用专业级远程桌面:RDP Wrapper Library终极指南(2024版) 【免费下载链接】rdpwrap RDP Wrapper Library 项目地址: https://gitcode.com/gh_mirrors/rd/rdpwrap 你是否曾经因为Windows家庭版无法使用远程桌面功…

2026/7/5 0:21:46 阅读更多 →

最新新闻

AI 压测数据回放:让模型读报告之前先校准口径

AI 压测数据回放:让模型读报告之前先校准口径

AI 压测数据回放:让模型读报告之前先校准口径 一、压测报告不能直接丢给模型 AI 可以帮助分析压测结果,但前提是输入数据口径清楚。很多压测报告里混着预热阶段、限流阶段、错误重试、下游故障和业务噪声。如果直接让模型总结,很容易得到一段…

2026/7/5 1:22:14 阅读更多 →
AI工具链选型:GitHub Copilot与Cursor、Codeium企业开发场景实测对比

AI工具链选型:GitHub Copilot与Cursor、Codeium企业开发场景实测对比

AI工具链选型:GitHub Copilot与Cursor、Codeium企业开发场景实测对比 一、评测体系设计与方法论 AI编码助手已成为开发效率的关键杠杆。本次评测聚焦三项主流工具的实际表现。从四个维度建立可复现的量化评测框架。 %%{init: {theme: base}}%% radartitle AI编码助手…

2026/7/5 1:20:14 阅读更多 →
PyTorch 数据加载瓶颈:GPU 空等时先看 DataLoader

PyTorch 数据加载瓶颈:GPU 空等时先看 DataLoader

PyTorch 数据加载瓶颈:GPU 空等时先看 DataLoader 一、训练慢不一定是模型慢 PyTorch 训练时,很多人看到速度慢就先改模型、调 batch size、换显卡。但如果 GPU 利用率忽高忽低,可能瓶颈根本不在模型,而在数据加载。图片解码、文本…

2026/7/5 1:20:14 阅读更多 →
群晖DSM 7.2.2视频管理终极解决方案:免费恢复Video Station完整功能

群晖DSM 7.2.2视频管理终极解决方案:免费恢复Video Station完整功能

群晖DSM 7.2.2视频管理终极解决方案:免费恢复Video Station完整功能 【免费下载链接】Video_Station_for_DSM_722 Script to install Video Station in DSM 7.2.2 and DSM 7.3 项目地址: https://gitcode.com/gh_mirrors/vi/Video_Station_for_DSM_722 你是否…

2026/7/5 1:20:14 阅读更多 →
云原生可观测性:构建全链路监控体系

云原生可观测性:构建全链路监控体系

引言在微服务架构和容器化部署成为主流的当下,系统的复杂性呈指数级增长。一个请求可能跨越数十个服务实例,传统的日志查看和单点监控已无法满足故障排查的需求。云原生可观测性(Observability)应运而生,它通过Metrics…

2026/7/5 1:18:13 阅读更多 →
工训赛智能小车 PCB 自制指南:从 BTN7971B 四路驱动到主控布局的 5 个要点

工训赛智能小车 PCB 自制指南:从 BTN7971B 四路驱动到主控布局的 5 个要点

工训赛智能小车PCB设计实战:从四路驱动到主控布局的进阶指南在工程训练综合能力竞赛的智能物流搬运赛项中,一辆性能卓越的小车往往始于精良的PCB设计。当现成模块难以满足定制化需求时,自主设计PCB不仅能显著降低成本,更能实现整车…

2026/7/5 1:18:13 阅读更多 →

日新闻

B站视频下载神器BiliTools:5分钟学会轻松保存任何B站内容

B站视频下载神器BiliTools:5分钟学会轻松保存任何B站内容

B站视频下载神器BiliTools:5分钟学会轻松保存任何B站内容 【免费下载链接】BiliTools A cross-platform bilibili toolbox. 跨平台哔哩哔哩工具箱,支持下载视频、番剧等等各类资源 项目地址: https://gitcode.com/GitHub_Trending/bilit/BiliTools …

2026/7/5 0:03:34 阅读更多 →
威胁模型全解析:从新手入门到实战应用,助你构建安全产品!

威胁模型全解析:从新手入门到实战应用,助你构建安全产品!

威胁模型的陌生现状在忙碌疲惫的一天里,参与了关于混合后量子密码学的讨论,应付端点攻击找茬的人,还参与留言板讨论后,发现“威胁模型”对多数人仍是陌生概念,且多被当作时髦用语。有趣的相关画作有一幅由 Embyr 创作的…

2026/7/5 0:03:34 阅读更多 →
渗透测试入门指南:从零基础到实战环境搭建

渗透测试入门指南:从零基础到实战环境搭建

1. 从“看热闹”到“入门”:我理解的渗透测试到底是什么?每次看到新闻里说某个大公司的数据被“黑”了,或者某个网站被攻击导致服务瘫痪,你是不是和我一样,心里会冒出两个念头:一是“这黑客真厉害”&#x…

2026/7/5 0:07:38 阅读更多 →

周新闻

B站视频下载神器BiliTools:5分钟学会轻松保存任何B站内容

B站视频下载神器BiliTools:5分钟学会轻松保存任何B站内容

B站视频下载神器BiliTools:5分钟学会轻松保存任何B站内容 【免费下载链接】BiliTools A cross-platform bilibili toolbox. 跨平台哔哩哔哩工具箱,支持下载视频、番剧等等各类资源 项目地址: https://gitcode.com/GitHub_Trending/bilit/BiliTools …

2026/7/5 0:03:34 阅读更多 →
威胁模型全解析:从新手入门到实战应用,助你构建安全产品!

威胁模型全解析:从新手入门到实战应用,助你构建安全产品!

威胁模型的陌生现状在忙碌疲惫的一天里,参与了关于混合后量子密码学的讨论,应付端点攻击找茬的人,还参与留言板讨论后,发现“威胁模型”对多数人仍是陌生概念,且多被当作时髦用语。有趣的相关画作有一幅由 Embyr 创作的…

2026/7/5 0:03:34 阅读更多 →
渗透测试入门指南:从零基础到实战环境搭建

渗透测试入门指南:从零基础到实战环境搭建

1. 从“看热闹”到“入门”:我理解的渗透测试到底是什么?每次看到新闻里说某个大公司的数据被“黑”了,或者某个网站被攻击导致服务瘫痪,你是不是和我一样,心里会冒出两个念头:一是“这黑客真厉害”&#x…

2026/7/5 0:07:38 阅读更多 →

月新闻