Java数字签名与证书全解析:从JCA原理到踩坑实战
1. 先说清楚数字签名和证书到底在解决什么问题搞Java开发的人早晚都会碰到数字签名和证书这两个概念。不管你是做接口对接、单点登录、支付回调验签还是处理电子合同、软件发布包校验背后都离不开这套机制。我第一次被问到为什么这里要加签名的时候下意识回答为了保证数据安全结果被反问了一句签名能加密数据吗这一下把我问住了。实际上数字签名解决的核心问题不是保密而是完整性和不可抵赖性。数据在传输过程中有没有被改过是不是某个特定的人或系统签发的这才需要签名和证书出场。证书Certificate则是用来绑定签名者身份和公钥的一份结构化文件最常见的就是X.509格式。你可以把证书理解成一张带钢印的身份证里面写着持有人是谁、公钥是什么、由谁颁发、有效期到什么时候。Java里处理这套体系的API集中在java.security和java.security.cert这两个包底层由JCAJava Cryptography Architecture统一管理。整个体系没有你想的那么玄乎但细节非常多一旦踩坑报错信息往往又隐晦又绕。这篇文章把我实际接触到的签名和证书相关的核心知识、代码实现、踩坑经历一起整理出来适合刚接触Java安全体系的开发同学也适合那种已经会调用Signature.getInstance(SHA256withRSA)但没搞明白背后原理的人。我会从原理讲到代码再讲到我真实遇到过的坑尽量把这条链路一次讲透。2. 理解JCA的Provider机制这是整个体系的入口2.1 JCA和Provider的关系Java不直接绑定某个具体的加密算法实现而是通过Provider机制动态加载。默认情况下JDK自带SUN、SunRsaSign、SunEC、SunJCE等Provider你调用Signature.getInstance(SHA256withRSA)的时候其实是让系统按照Provider的优先级去找哪个实现能支持这个算法。这个设计带来一个好处你可以替换底层密码学库比如把默认Provider换成增强型的安全库而不需要改动业务代码。坏处是如果你对Provider机制不熟会出现一种很典型的困惑我本地运行好好的换到客户的服务器上报NoSuchAlgorithmException十有八九是对方的JDK版本较老或者裁减过Provider。2.2 核心API类别Java的签名和证书体系主要涉及四块密钥对生成用KeyPairGenerator签名验签用Signature证书解析用CertificateFactory证书和私钥的统一管理容器则是KeyStore。它们的分工非常明确。KeyStore是个容易被忽略但极其重要的角色它本质上是一个加密的钥匙串文件用来存放私钥、信任的证书和密钥条目。常用的有JKS和PKCS12两种格式现在PKCS12是主流因为JKS是Java私有的PKCS12是跨语言标准很多非Java系统也能读取。2.3 算法的分层理解你会在代码里看到类似SHA256withRSA、SHA384withECDSA这样的算法名它的命名规则是摘要算法 签名算法。以SHA256withRSA为例它先用SHA-256对原文生成一个32字节的摘要然后用RSA私钥对这个摘要做加密形成签名。验签的时候验签方用RSA公钥解密签名得到摘要再对原文算一次SHA-256两个摘要一致就说明签名有效。这里有个关键点几乎所有实际使用的签名方案都是先摘要后签名而不是对整份大文件直接做非对称加密运算。因为非对称加密的计算开销很大对几百兆的文件逐字节做RSA运算根本不现实摘要之后只需要对固定长度的哈希值做签名效率高得多安全性也没打折。注意MD5withRSA和SHA1withRSA这类老算法在新版JDK中默认被标记为不安全很多环境下直接调用会抛异常。除非你在维护老系统否则一律使用SHA256withRSA或更高强度的组合。3. 证书的结构与证书链拿到一张X.509证书后怎么读3.1 X.509证书的基本字段先看一段实际读取证书的Java代码这是我平时排查问题最常用的工具代码import java.io.FileInputStream; import java.security.cert.CertificateFactory; import java.security.cert.X509Certificate; import java.util.Date; public class ReadCert { public static void main(String[] args) throws Exception { CertificateFactory factory CertificateFactory.getInstance(X.509); X509Certificate cert; try (FileInputStream fis new FileInputStream(server.crt)) { cert (X509Certificate) factory.generateCertificate(fis); } System.out.println(Subject: cert.getSubjectX500Principal()); System.out.println(Issuer: cert.getIssuerX500Principal()); System.out.println(Serial Number: cert.getSerialNumber()); System.out.println(Not Before: cert.getNotBefore()); System.out.println(Not After: cert.getNotAfter()); System.out.println(Signature Algorithm: cert.getSigAlgName()); System.out.println(Public Key: cert.getPublicKey().getAlgorithm()); } }这段代码几乎是排查证书问题的基础工具我反复用过很多次。Subject是这张证书代表的实体Issuer是颁发者前者和后者的关系决定了证书链的方向。拿常见的HTTPS证书来说浏览器访问某个站点时服务器返回的证书Subject是站点域名Issuer是某个CA机构而CA机构的证书Subject又和这个Issuer相同这样就形成了一条叶子证书 - 中间CA - 根CA的信任链。3.2 证书链校验的逻辑Java在发起TLS握手时会自动做证书链校验校验的核心逻辑有三步。第一从叶子证书开始逐级向上查找颁发者证书直到找到自签名的根证书。第二验证每一级的签名是否有效也就是用上一级证书里的公钥去验证下一级证书的签名。第三检查每一张证书的有效期和用途。这里面有一个容易踩的坑Java的TrustStore里默认只信任内置的根CA如果你的服务用的是私有CA签发的证书必须在启动参数里显式指定信任库否则握手直接失败报错往往是PKIX path building failed或者unable to find valid certification path to requested target。这个报错信息我见过太多次了很多人第一反应是证书坏了其实是信任链没建立起来。3.3 证书格式的混淆点PEM和DER是两种最常见的编码格式很多人被这两个词搞晕。DER是二进制编码PEM是在DER基础上做Base64编码并加上-----BEGIN CERTIFICATE-----这样的头尾标记。Java的CertificateFactory两种格式都能解析但同一个文件后缀名可能造成误导。我之前遇到过一台服务器上有个.cer文件实际内容是PEM格式另一个.pem文件反而是DER编码全靠代码去探测。分辨的方法很简单用文本编辑器打开能看到BEGIN字样就是PEM全是乱码就是DER。处理证书的时候我建议代码里做一次兼容处理先尝试按PEM解析失败再按DER解析这样能省掉很多格式问题的排查时间。4. 实操从密钥对生成到签名验签的完整流程4.1 生成密钥对和自签名证书在实际项目里我们经常需要自己生成密钥对和自签名证书做联调不需要去真实CA申请。JDK自带的keytool工具就能完成keytool -genkeypair -alias testkey \ -keyalg RSA -keysize 2048 \ -validity 365 \ -keystore keystore.p12 -storetype PKCS12 \ -storepass changeit \ -dname CNTest Server, OUDev, OExample, CCN这条命令会生成一个包含密钥对和自签名证书的PKCS12格式KeyStore。几个参数值得展开说。keysize我建议至少2048位1024位在当前安全要求下已经完全不可接受某些环境下JDK直接禁止生成1024位的RSA密钥。validity是证书有效天数联调环境可以设365天但生产环境的证书有效期一般不超过398天这是行业通行做法。dname里的CN字段必须认真填很多系统在验签时会把证书的CN和实际使用的服务域名做比对对不上就校验失败。自签名证书和CA签发的证书在Java里处理方式完全一样只是自签名证书的Issuer等于Subject。你可以把它理解成自己给自己发了一张身份证法律效力存疑但技术上完全够用来做内部系统之间的通信加密和签名验证。4.2 签名方的完整代码签名在Java里实现起来其实很短但每一步都有讲究。下面是我在项目里实际用过的签名工具类核心代码import java.nio.charset.StandardCharsets; import java.security.KeyStore; import java.security.PrivateKey; import java.security.Signature; import java.util.Base64; public class Signer { private final PrivateKey privateKey; public Signer(String keyStorePath, String storePass, String alias) throws Exception { KeyStore ks KeyStore.getInstance(PKCS12); try (var fis new java.io.FileInputStream(keyStorePath)) { ks.load(fis, storePass.toCharArray()); } this.privateKey (PrivateKey) ks.getKey(alias, storePass.toCharArray()); if (this.privateKey null) { throw new IllegalStateException(alias alias does not hold a private key); } } public String sign(String content) throws Exception { Signature signature Signature.getInstance(SHA256withRSA); signature.initSign(privateKey); signature.update(content.getBytes(StandardCharsets.UTF_8)); byte[] signedBytes signature.sign(); return Base64.getEncoder().encodeToString(signedBytes); } }这段代码的关键点有三个。第一从KeyStore取私钥的时候getKey方法需要传alias和密码取出来的对象要强转成PrivateKey但在强转之前最好判空否则alias写错时会得到一个null然后强转抛NullPointerException这个空指针在业务代码里往往比KeyStoreException更难排查。第二signature.update传入的字节必须和验签方约定的字符集一致强烈建议大家统一用UTF-8我曾经遇到过因为两端默认字符集不同导致签名验签失败的案例折腾了小半天才发现是getBytes()没指定编码。第三签名结果建议用Base64编码后再传输因为原始字节在JSON、XML里很难安全传递这一点很少被官方文档强调但实际做接口对接时几乎必用。4.3 验签方的完整代码import java.nio.charset.StandardCharsets; import java.security.PrivateKey; import java.security.Signature; import java.security.cert.X509Certificate; import java.util.Base64; public class Verifier { private final X509Certificate certificate; public Verifier(String certPath) throws Exception { var factory java.security.cert.CertificateFactory.getInstance(X.509); try (var fis new java.io.FileInputStream(certPath)) { this.certificate (X509Certificate) factory.generateCertificate(fis); } } public boolean verify(String content, String signedBase64) throws Exception { Signature signature Signature.getInstance(SHA256withRSA); signature.initVerify(certificate.getPublicKey()); signature.update(content.getBytes(StandardCharsets.UTF_8)); byte[] signedBytes Base64.getDecoder().decode(signedBase64); return signature.verify(signedBytes); } }验签方和签名方的代码结构高度对称唯一的本质区别是签名方用私钥验签方用公钥。这里的公钥从证书里取而不是直接传一个KeyPair或PublicKey对象这是有讲究的。因为你收到的对端公钥必须经过身份认证才能信任而证书本身就是传递可信公钥的标准载体。如果直接传公钥中间人完全可以替换公钥然后伪造签名整个验签体系就形同虚设。搞清楚这个逻辑你就能理解为什么接口对接规范里要求对方提供的是证书文件而不是一段裸的Base64公钥字符串。4.4 一个真实的排错经历我第一次做签名对接的时候对方把证书发过来我也验签成功了但第二天早上生产环境突然报验签失败。我查了半天最后发现对方在发证书给我的时候同时更新了他们的私钥和证书也就是说他们悄悄换了对而我这边还在用旧证书验签。从那以后我在所有对接文档里都会明确写一句话证书轮换必须提前通知并同步新证书否则验签会失败。这个坑在真实的跨公司对接里非常常见。另外还有一个细节signature.update可以调用多次等效于把所有内容按顺序拼接后一次性update。这个特性在分段校验大文件签名时很有用可以流式处理不用把整份文件加载进内存。5. 踩坑清单证书和签名实战中的高频坑5.1 证书链校验失败的真正原因PKIX path building failed是Java安全领域出现频率最高的报错之一但很多人不知道它背后有几类完全不同的原因。我用表格把排查顺序和对应的检查项整理出来这是我在多次排障中总结的优先级顺序排查顺序检查项现象与处理方式1对方公钥证书是否已导入信任库报错unable to find valid certification path需把根证书或对方证书加入TrustStore2证书链是否完整服务器只发了叶子证书没发中间CA需补齐证书链文件3系统时间是否正确证书有效期校验依赖当前时间服务器时钟偏差超过数分钟就可能导致连锁失败4证书用途扩展证书可能只用于签名不能用于TLS需检查KeyUsage和ExtendedKeyUsage扩展项5算法是否被JDK版本禁用老算法如SHA1withRSA在高版本JDK默认禁用需升级算法或调整安全策略我遇到过最隐蔽的一次是系统时间问题。那是某台新部署的测试服务器系统时间比真实时间快了将近一个小时结果所有依赖证书有效期校验的操作全部失败。事后反思排查时间问题应该放在最前面因为它会导致表层现象变成各种不同的证书错误极具迷惑性。5.2 时区、有效期和CRLJava的X509Certificate.getNotBefore()和getNotAfter()返回的是Date对象对应证书里的UTC时间。证书的有效期判断逻辑是当前时间必须在Not Before和Not After之间。这里有个容易忽视的问题证书里的时间字段本身有UTCTime和GeneralizedTime两种格式解析老证书时如果格式判断不严谨可能出现时间偏移。好在Java的证书解析已经处理了这个细节你需要关心的只是服务器本身的系统时间要准确。CRL证书撤销列表是另一个容易被忽视的环节。真实CA签发的证书如果因私钥泄露等原因需要提前作废CA会把证书序列号发布到CRL列表里Java在TLS握手时通过CertPathValidator的PKIXParameters配置可以启用CRL检查。默认情况下Java不强制检查CRL但如果业务场景对安全性要求高比如金融类接口建议显式开启。开启的代价是每次握手都要额外请求CRL服务器会有性能损耗一般会搭配OCSP缓存来缓解。5.3 算法强度与兼容性的平衡SHA256withRSA几乎是最稳妥的选择绝大多数运行环境都支持。但如果你对接的系统用的算法是SHA256withECDSA或RSA/ECB/OAEPWithSHA-256AndMGF1Padding就要特别注意JDK版本的兼容性。ECDSA在Java 7以后才默认支持有些老的服务器环境可能没有对应的Provider。另外Signature和Cipher虽然都涉及RSA但它们的用途完全不同Signature用于签名验签Cipher用于加密解密。很多人会把RSA加密和RSA签名混为一谈导致在对接时设计出错误的流程。这里分享一个简单的记忆方法加密保护机密性签名保护完整性和不可抵赖性两者使用的密钥方向完全相反加密用公钥解密用私钥签名用私钥验签用公钥。搞清楚这一点很多设计混乱的问题都能避免。关键建议新写的代码统一使用SHA256withRSA密钥长度2048位私钥存PKCS12格式的KeyStore证书用X.509传输时签名值做Base64编码。这套组合能覆盖绝大多数业务对接场景而且踩坑率极低。6. 再补充几个值得关注的设计细节6.1 签名内容的设计规范到底该签什么很多人在写签名接口时忽略了一个问题签名时使用的原文内容和验签方参与签名的内容必须完全一致。这个一致看起来简单但跨系统对接时变形点特别多。最常见的坑是字段顺序问题有些接口规范要求把所有参数按名称排序后拼接成字符串再签名有些要求保留原始JSON顺序。如果两端的排序规则不一致验签必然失败。我个人的习惯是在接口文档里直接写明参与签名的原文示例以及拼接规则最好给一个具体的字符串示例比如appIdtesttimestamp1700000000这样对方实现的时候不会产生歧义。还有一个容易被忽略的点空字段是否参与签名。有的系统要求空值字段也参与拼接有的要求跳过这个在文档里必须明确。6.2 时间戳与重放攻击的防护签名只能证明数据来源和完整性不能防御重放攻击。所谓重放攻击就是攻击者把一份合法的签名请求原封不动地再次发送这样接收方会认为这是一次新的有效请求。解决办法是在签名的内容中加入时间戳和随机数nonce接收方校验签名有效后还要检查时间戳是否在可接受的时间窗口内以及随机数是否已经使用过。在实际项目里我通常会在签名原文中加入timestamp字段接收方允许的时间偏移设置为5分钟。这个窗口太小会影响正常调用太大则增加重放风险。另外对于高安全场景还需要一张已使用nonce的缓存表来判断随机数是否重复内存型缓存如Redis就能满足要求注意给nonce设置和请求有效期一致的过期时间防止缓存无限增长。6.3 证书轮换这个定时炸弹证书和密钥不像普通配置项改完即时生效它有非常典型的失效滞后问题。我见过最典型的事故是运维在凌晨更新了服务器上的证书但是没有通知对接方导致第二天上班高峰期对方验签大量失败。所以证书轮换必须走变更流程提前通知所有调用方约定一个新旧证书并存期。在新证书上线后、旧证书失效前的这段时间接收方应该同时支持两个证书进行验签给调用方留出切换时间。6.4 密钥的存储安全最后必须说的是私钥的存储。私钥一旦泄露整个签名体系就废了而且这种泄露往往不会立即被发现。建议的私钥管理原则有三个一是私钥不要硬编码在代码里或放在配置文件里要用KeyStore文件加密存储或者使用专用的密钥管理服务二是KeyStore密码要有独立的生命周期管理不要和数据库密码混用三是签名服务和私钥的使用要留审计日志记录每次签名的调用方、时间和结果。安全领域的通用原则是不记录私钥本身但要记录一切和私钥使用相关的行为。7. 我对这套体系的一点个人体会做签名和证书对接这些年我从一开始只会照着网上的代码抄到现在能快速定位各种证书问题最大的体会是这套体系的功能本身并不复杂复杂的全是细节。一个字符集的差异、一个字段顺序的变化、一套过期的时间、一个缺失的中间证书都可能让两个系统之间出现莫名其妙的失败。如果让我给后来者一个最核心的建议那就是在联调阶段一定要双方互换签名原文示例和证书指纹。证书指纹即证书内容和签名信息做哈希得到的固定值可以快速确认对方的证书是否和预期一致避免你以为你在用A证书实际系统加载了B证书这种尴尬。查看证书指纹的命令很简单keytool -printcert -jarfile app.jar # 或者对单个证书文件 keytool -printcert -file server.crt输出里的SHA256:开头的指纹就是证书指纹双方比对一次就能锁定证书一致性。签名和证书这套东西入门容易精通难。但只要你把底层的信任模型想明白了把字符集、时间、证书链这些细节都做到位后面的路就会顺很多。希望这篇文章能帮你把之前模糊的概念串起来下次再遇到报错的时候能直接定位到正确的方向。

相关新闻

用Swing/AWT实现坦克大战:Java面向对象与游戏循环实战

用Swing/AWT实现坦克大战:Java面向对象与游戏循环实战

坦克大战这个项目,我在不同阶段做过三遍。第一遍是为了完成一门课程设计,当时抱着“能跑就行”的心态,代码堆在几个类里,勉强能动但极其脆弱;第二遍尝试了重构,把坦克、子弹、墙壁分别抽象出来,…

2026/10/17 11:59:37 阅读更多 →
中级开发者AI能力升级路线图:从工程化到RAG与微调

中级开发者AI能力升级路线图:从工程化到RAG与微调

1. 先别急着学新框架,重新给自己画一张能力坐标 这几年我面试过不少中级开发者,也带过一些从普通业务开发转向AI方向的团队同事。一个很明显的现象是:很多人并不是不努力,而是努力的方向太散了。今天刷到一篇讲大模型微调的文章&a…

2026/10/17 11:58:36 阅读更多 →
2026年转行网络安全还来得及吗?真实行情与务实入行路径全拆解

2026年转行网络安全还来得及吗?真实行情与务实入行路径全拆解

经常有人私信我:2026年了,现在转行网络安全到底还来不来得及?这个问题几乎每一年都有人问,但随着时间推进,答案其实一直在变。作为在这个行当里做了多年、一路踩过不少坑的人,我想把这几年观察到的行情、带…

2026/10/17 11:58:36 阅读更多 →

最新新闻

把“可爱”病毒集合变成恶意样本分析练习场:从静态特征到检测规则

把“可爱”病毒集合变成恶意样本分析练习场:从静态特征到检测规则

简介:CuteVirusCollection是一份小巧但“致命”的恶意代码集合,聚焦Windows XP/7/10环境下的小型病毒、蠕虫与崩溃实验,面向安全爱好者、编程学习者和隔离环境测试者。资源按灾害等级分为三层:一级狼包含无休止弹窗、随机鼠标移动…

2026/10/17 12:51:07 阅读更多 →
泰坦尼克号竞赛入门实战:特征工程与模型调优全流程

泰坦尼克号竞赛入门实战:特征工程与模型调优全流程

1. 为什么泰坦尼克是竞赛入门的“第一课”1.1 一个被低估的练手场很多人第一次听说数据科学竞赛,都是从泰坦尼克号幸存者预测这个项目开始的。它太经典了,经典到有人觉得“烂大街”,但我的看法恰恰相反:越是经典的入门题&#xff…

2026/10/17 12:51:07 阅读更多 →
Spark RDD依赖关系源码解析:从NarrowDependency到ShuffleDependency

Spark RDD依赖关系源码解析:从NarrowDependency到ShuffleDependency

1. 为什么读懂RDD依赖关系是Spark调优的真正起点很多人学Spark,一上来就猛啃shuffle、partition、cache这些词,结果跑着跑着任务就OOM,或者stage卡在99%不动,查日志全是ShuffleBlockFetcherIterator超时,最后只能靠加内…

2026/10/17 12:51:07 阅读更多 →
Qwen3-VL多模态模型工程落地:架构拆解、部署选型与性能调优

Qwen3-VL多模态模型工程落地:架构拆解、部署选型与性能调优

做多模态模型工程落地这几年,我最大的感受是:模型榜单上的分数和真实业务场景里的表现,从来都不是一回事。Qwen3-VL这代模型,我先后在文档解析、巡检图片识别、短视频内容理解几个项目里实际用过,从性能测试到线上部署…

2026/10/17 12:51:07 阅读更多 →
SAP批处理全解析:BDC与LSMW原理、实操与选型避坑指南

SAP批处理全解析:BDC与LSMW原理、实操与选型避坑指南

简介:SAP批处理工具BDC与LSMW的使用方法详解,面向SAP顾问、开发人员及负责数据迁移的运维/业务人员,解决大批量数据录入与系统间数据转换的常见痛点。文档以SHDB录屏为切入点,完整介绍BDC的录制脚本、审查调整字段、导出模板、邮件…

2026/10/17 12:51:07 阅读更多 →
Coze复杂应用实战:工作流设计与调试排错全攻略

Coze复杂应用实战:工作流设计与调试排错全攻略

做复杂应用这件事,最难的地方从来不是某个节点不会配,而是脑子里没有一张“流程图”。我见过太多人上来就拖节点,拖到一半发现逻辑绕不过去,整个工作流推倒重来。这个Coze教程的下篇,咱们不聊基础操作,直接…

2026/10/17 12:50:06 阅读更多 →

日新闻

DeepSeek选型与部署:V3/R1、Ollama、API全攻略

DeepSeek选型与部署:V3/R1、Ollama、API全攻略

简介:《DeepSeek使用方法.pdf》是一份面向DeepSeek入门及进阶用户的完整使用指南,重点围绕V3与R1两款模型的能力差异与适用场景展开,帮助读者根据任务类型与成本选择合适的模型。资源共1个PDF文件,压缩包大小约311KB,篇…

2026/10/17 0:00:25 阅读更多 →
200+Deepseek润色指令拆解:从底层原理到场景落地的完整指南

200+Deepseek润色指令拆解:从底层原理到场景落地的完整指南

简介:这是一份聚焦DeepSeek提示词优化的《200Deepseek润色指令》PDF文档,共收录两百余条可直接套用的润色指令,涵盖语法修正、风格统一、逻辑梳理、表达精炼等维度,并针对商务写作、学术论文、广告文案等场景给出差异化建议。文档…

2026/10/17 0:00:25 阅读更多 →
OpenCV轮廓法物体计数系统:轻量、可控、可落地的工业级实现

OpenCV轮廓法物体计数系统:轻量、可控、可落地的工业级实现

简介:本资源是一份基于OpenCV的本科课程设计完整报告,面向计算机视觉初学者、图像处理学习者及高校通信/信息类专业学生,解决物体智能计数与检测结果结构化记录的实际问题。项目覆盖图像预处理、轮廓检测、边界框绘制、轨迹栏交互式参数调节、…

2026/10/17 0:00:25 阅读更多 →

周新闻

流感时间序列预测实战:ARIMA/LSTM全流程拆解与避坑指南

流感时间序列预测实战:ARIMA/LSTM全流程拆解与避坑指南

简介:基于 ARIMA、LSTM、Transformer 等模型的流感时间序列预测 Python 源码,面向计算机相关专业课程设计与期末大作业学生,以及项目实战学习者。内容覆盖预处理、平稳性检验、定阶、残差分析、多模型对比预测的完整时序建模流程,…

2026/10/16 21:35:51 阅读更多 →
影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别

影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别

影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别 做影刀RPA自动化,十个新手有八个栽在"往输入框里填东西"这件事上:要么填不进去,要么填了一半,要么直接把原来内容追加在后面。这背后的根因&…

2026/10/17 1:44:59 阅读更多 →
影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容

影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容

影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容 1. 认识影刀:什么场景该用RPA采小说数据 起点中文网的页面结构相对稳定——分类榜单、书籍详情、章节内容三块独立页面,跳转链路清晰。这种场景非常适合影刀自动化&#x…

2026/10/16 15:04:24 阅读更多 →

月新闻

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/16 21:54:38 阅读更多 →
Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/16 3:49:43 阅读更多 →
黑夜航拍船只数据集训练YOLOV5模型全流程解析

黑夜航拍船只数据集训练YOLOV5模型全流程解析

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/16 14:23:36 阅读更多 →