解决OpenSSH 8.8+与JSch兼容性问题:生成RSA密钥对与Java SSH连接配置
1. 项目概述当OpenSSH高版本遇上老牌Java客户端最近在搞一个老项目的自动化部署用Java写的里面用到了JSch这个库去连接服务器执行命令。服务器那边刚把OpenSSH升级到了8.8以上好家伙脚本一跑就报错提示“invalid privatekey”。一开始以为是密钥权限问题chmod 600搞了半天结果还是不行。后来一查日志发现是服务器拒绝了我们的RSA密钥交换。这才意识到不是脚本写错了是OpenSSH高版本的安全策略变了默认把一些老旧的、不够安全的算法给禁用了其中就包括我们常用的、用ssh-keygen默认参数生成的RSA密钥对。而JSch作为一个历史悠久的Java SSH2客户端在某些版本下默认还是用着老一套的格式两边就对不上号了。这个问题在CentOS升级OpenSSH、银河麒麟离线升级后尤其常见很多运维和开发都会踩坑。今天就来彻底拆解一下这个兼容性问题并手把手教你生成一套既能被高版本OpenSSH接受又能被JSch等老客户端正确识别的RSA密钥对。简单来说这事的核心矛盾在于OpenSSH 8.8 为了安全默认禁用ssh-rsa签名算法即SHA-1哈希而JSch特别是较旧版本默认可能只认识这种格式的密钥或者需要额外配置才能使用更安全的算法。我们的目标就是找到一个平衡点生成一个“新旧通吃”的密钥。别担心不需要你降级OpenSSH那会引入安全风险也不需要你大动干戈地改JSch源码关键在于密钥生成的那几个参数。2. 核心原理为什么“默认”的RSA密钥不兼容了要解决问题得先明白问题出在哪。这涉及到OpenSSH演进过程中的一次重要安全策略调整。2.1 OpenSSH 8.8的安全升级与算法弃用大约在2021年随着OpenSSH 8.8版本的发布官方宣布了一项重要变更默认禁用ssh-rsa公钥签名算法。这里的ssh-rsa特指使用SHA-1哈希函数进行签名的RSA算法。为什么这么做因为SHA-1哈希算法早在密码学界就被认为存在理论上的碰撞漏洞不再安全。虽然直接攻击SSH协议中的SHA-1签名仍然非常困难且成本高昂但出于“防患于未然”和推动生态向更安全算法迁移的原则OpenSSH团队决定在默认配置中关闭它。当你使用ssh-keygen -t rsa命令不加任何额外参数生成密钥时它默认使用的就是这种ssh-rsa签名格式。在高版本OpenSSH服务器sshd上默认的配置文件中PubkeyAcceptedAlgorithms或旧版叫PubkeyAcceptedKeyTypes选项通常不再包含ssh-rsa。这意味着当客户端比如JSch尝试使用一个仅声明支持ssh-rsa签名的私钥去连接时服务器会直接拒绝“哥们你这签名算法太老了我们这不支持。”2.2 JSch的默认行为与算法支持JSch是一个纯Java的SSH2实现非常经典被集成在很多Java应用、构建工具如Ant, Gradle的SSH插件和框架里。它的算法支持取决于其版本和编译时的配置。较旧的JSch版本例如0.1.x系列可能默认只支持ssh-rsa或者需要手动注册其他算法。它读取私钥时会期待一种特定的格式。较新的JSch版本例如0.2.x通常已经支持更安全的算法如rsa-sha2-256和rsa-sha2-512。但是支持算法和使用哪种算法去连接是两回事。JSch在与服务器协商时会发送自己支持的算法列表。如果服务器不支持它列表中的算法或者它自己没正确识别私钥对应的新格式连接就会失败。问题的另一个关键点是私钥的格式。ssh-keygen生成的私钥文件id_rsa本身包含元数据指明它用于什么签名算法。如果这个元数据标识的是旧的ssh-rsa即使密钥对本身数学上没问题高版本服务端也会因为算法标识不符而拒绝。2.3 兼容性问题的本质所以兼容性问题的本质是算法协商失败。我们需要生成一个密钥对这个密钥对在服务器端其对应的公钥算法如rsa-sha2-256必须被OpenSSH服务端的PubkeyAcceptedAlgorithms列表所接受。好消息是新算法默认是接受的。在客户端JSch其私钥格式必须能被JSch正确解析并且JSch在协商时必须能提供服务器可接受的、与该私钥匹配的签名算法。我们的解决方案将围绕“如何生成一个使用新签名算法标识的RSA密钥对”以及“如何确保JSch能使用它”来展开。3. 手把手生成兼容的RSA密钥对知道了原理操作就有的放矢了。我们不再使用简单的ssh-keygen -t rsa而是通过指定更明确的参数来生成密钥。3.1 关键命令与参数解析打开你的终端连接到你打算存放私钥的机器或者你的本地开发机执行以下命令ssh-keygen -t rsa -b 4096 -m PEM -C comment-for-your-key -f ~/.ssh/id_rsa_compatible让我们拆解每个参数的意义-t rsa: 指定密钥类型为RSA。这是基础我们仍然使用RSA算法因为它被广泛支持。-b 4096: 指定密钥长度为4096位。2048位是目前的最低安全标准但考虑到长期使用和更强的安全性直接使用4096位是更好的选择。这也向服务器表明这是一个“强”密钥。-m PEM:这是最关键的一个参数它指定私钥的存储格式为PEM。PEM格式是一种老式的、但被广泛支持的格式OpenSSL常用。高版本ssh-keygen默认的私钥格式是OpenSSH自己的新格式这种格式虽然包含更多元数据但某些旧版JSch可能无法识别。使用-m PEM可以强制生成一个兼容性更广的PEM格式私钥。这个私钥文件的内容以-----BEGIN RSA PRIVATE KEY-----开头。-C: 添加一个注释通常用邮箱或标识这个会保存在公钥末尾便于管理。-f: 指定生成的文件名。这里我们生成id_rsa_compatible和id_rsa_compatible.pub以区别于你可能已有的默认密钥。执行命令后它会询问你密钥的保存位置我们已经指定和密码短语passphrase根据你的安全要求设置即可。3.2 验证生成的密钥对生成后我们来检查一下成果。查看公钥算法ssh-keygen -l -f ~/.ssh/id_rsa_compatible.pub输出会类似4096 SHA256:abcdefg... comment-for-your-key (RSA)注意这里的哈希是SHA256这说明公钥本身是和SHA256关联的是一个好的迹象。更关键的是查看公钥文件本身cat ~/.ssh/id_rsa_compatible.pub你会看到一长串以ssh-rsa AAAAB3...开头的文本。等等开头还是ssh-rsa别急这个ssh-rsa在这里是密钥类型标识它和前面说的签名算法不是完全同一个概念。对于由新版本ssh-keygen即使指定了-m PEM生成的RSA密钥当它被添加到~/.ssh/authorized_keys时现代的OpenSSH服务端会根据客户端的能力自动选择使用rsa-sha2-256或rsa-sha2-512进行签名验证只要客户端声明支持。而-m PEM参数主要确保了私钥的兼容性。查看私钥格式head -n 1 ~/.ssh/id_rsa_compatible你应该看到-----BEGIN RSA PRIVATE KEY-----这证实了它是PEM格式。3.3 部署公钥到目标服务器将公钥部署到你需要连接的服务器上# 将公钥内容追加到服务器的授权密钥文件中 ssh-copy-id -i ~/.ssh/id_rsa_compatible.pub useryour_server_host或者手动复制公钥内容粘贴到服务器对应用户的~/.ssh/authorized_keys文件末尾。注意确保服务器上~/.ssh目录权限为700 (drwx------)authorized_keys文件权限为600 (-rw-------)。权限错误是导致认证失败的常见原因。4. 在Java项目中使用JSch加载兼容密钥密钥生成好了现在需要在Java代码中让JSch使用它。这里有几个关键点。4.1 添加JSch依赖首先确保你的项目引入了JSch。以Maven为例dependency groupIdcom.jcraft/groupId artifactIdjsch/artifactId version0.1.55/version !-- 建议使用较新版本如0.1.55 -- /version4.2 核心代码示例与配置以下是一个简单的连接示例展示了如何加载我们生成的PEM格式私钥并进行关键配置。import com.jcraft.jsch.*; public class SshWithCompatibleKey { public static void main(String[] args) { String host your.server.com; String user username; int port 22; String privateKeyPath /home/youruser/.ssh/id_rsa_compatible; // 你的PEM格式私钥路径 String passphrase null; // 如果你生成密钥时设置了密码短语在这里填写 JSch jsch new JSch(); Session session null; try { // 1. 加载PEM格式的私钥 // 这个方法专门用于加载OpenSSH格式的私钥但它也能处理PEM格式尤其是带有-m PEM生成的。 // 如果加载失败可能需要尝试其他方法见下文注意事项。 jsch.addIdentity(privateKeyPath, passphrase ! null ? passphrase.getBytes() : null); // 2. 创建会话并设置配置 session jsch.getSession(user, host, port); // **关键配置设置优先使用的签名算法** // 告诉JSch在协商时优先提供服务器更可能接受的rsa-sha2-256算法。 // 这个配置项的名称在不同JSch版本中可能略有不同server_host_key是常用键名。 java.util.Properties config new java.util.Properties(); config.put(server_host_key, rsa-sha2-256,rsa-sha2-512,ssh-rsa); // 将新算法放在前面 config.put(PubkeyAcceptedAlgorithms, rsa-sha2-256,rsa-sha2-512,ssh-rsa); // 显式指定接受的公钥算法 session.setConfig(config); // 3. 设置不严格检查主机密钥仅用于测试生产环境应配置已知主机 session.setConfig(StrictHostKeyChecking, no); // 4. 连接 session.connect(); System.out.println(SSH连接成功); // ... 这里可以打开Channel执行命令或进行SFTP操作 ... } catch (JSchException e) { e.printStackTrace(); System.err.println(SSH连接失败: e.getMessage()); // 特别关注异常信息可能包含算法协商失败的具体原因 if (e.getMessage().contains(algorithm negotiation)) { System.err.println(提示算法协商失败请检查JSch版本和服务器支持的算法。); } } finally { if (session ! null session.isConnected()) { session.disconnect(); } } } }4.3 代码关键点解析与避坑指南addIdentity方法这是加载私钥的标准方法。对于-m PEM生成的密钥它通常能正常工作。如果遇到“invalid privatekey”错误可能是因为JSch内部对PEM格式的解析有特定要求。一个备选方案是使用jsch.addIdentity(privateKeyPath)如果私钥有密码JSch会在连接时弹出密码输入对于自动化脚本不友好或者使用jsch.addIdentity(user, privateKey.getBytes(), publicKey.getBytes(), passphrase.getBytes())这个重载方法但需要你同时读取私钥和公钥文件内容。算法配置 (server_host_key)config.put(“server_host_key”, …)这一行至关重要。它改变了JSch在密钥交换Key Exchange阶段向服务器宣告自己支持的主机密钥算法的顺序。虽然名字叫server_host_key但它也影响了客户端认证阶段的算法偏好。将rsa-sha2-256和rsa-sha2-512放在ssh-rsa前面能提高协商到新算法的成功率。PubkeyAcceptedAlgorithms是更直接指定客户端接受哪些公钥算法的配置两者结合使用效果更好。JSch版本强烈建议使用0.1.55或更高版本。这些版本对新的签名算法有更好的支持。如果你被一个非常老的项目绑定在旧版本如0.1.54那么即使生成了新格式密钥JSch底层可能也不支持对应的算法这时可能需要考虑升级JSch或寻找其他兼容方案。调试信息如果连接仍然失败可以启用JSch的详细日志来查看协商过程JSch.setLogger(new com.jcraft.jsch.Logger() { public boolean isEnabled(int level) { return true; } public void log(int level, String message) { System.out.println(“JSch - “ message); } });查看日志输出中关于kex: algorithm、server_host_key、publickey认证算法的部分能清晰看到客户端和服务器各自支持什么最终协商出了什么。5. 服务器端配置检查与调整可选大多数情况下生成兼容密钥并正确配置JSch后问题就解决了。但如果你的服务器OpenSSH版本极高或者被严格加固过可能还需要检查一下服务器配置。5.1 检查服务器支持的算法在服务器上可以查看sshd当前支持的算法列表ssh -Q PubkeyAcceptedAlgorithms或者查看更详细的配置sudo sshd -T | grep pubkeyacceptedalgorithms确保输出中包含rsa-sha2-256和rsa-sha2-512。在OpenSSH 8.8中它们默认是包含的。5.2 临时启用旧算法不推荐如果因为某些不可抗拒的原因你必须让服务器接受旧的ssh-rsa算法例如一个完全无法升级或修改的古老客户端你可以临时或针对特定客户端修改服务器配置。请注意这会降低安全性仅作为最后手段。编辑/etc/ssh/sshd_config文件找到或添加一行PubkeyAcceptedAlgorithms ssh-rsa这个ssh-rsa表示在默认算法列表的基础上额外添加ssh-rsa算法。修改后重启sshd服务sudo systemctl restart sshd。重要警告长期启用ssh-rsa会降低系统安全性。这只应作为一个过渡方案并尽快将所有客户端和密钥升级到更安全的算法。6. 常见问题排查与实战心得在实际操作中你可能会遇到一些“坑”。这里记录了几个典型场景和解决方法。6.1 问题速查表问题现象可能原因排查步骤与解决方案invalid privatekey1. 私钥文件格式JSch无法识别。2. 私钥文件损坏或内容不完整。3. 密码短语错误。1. 确认使用ssh-keygen -m PEM生成。用head -n 1检查私钥是否为PEM格式。2. 重新生成密钥对。3. 检查代码中passphrase是否正确或尝试空密码。Algorithm negotiation failed客户端(JSch)和服务器支持的算法列表没有交集。1. 在JSch配置中显式设置server_host_key和PubkeyAcceptedAlgorithms包含rsa-sha2-256。2. 升级JSch到最新版本。3. 在服务器端运行ssh -Q PubkeyAcceptedAlgorithms确认支持新算法。连接成功但认证失败1. 公钥未正确部署到authorized_keys。2. 文件权限问题。3. SELinux/AppArmor等安全模块限制。1. 确认公钥内容已完整添加到服务器对应用户的~/.ssh/authorized_keys文件末尾。2. 检查服务器上.ssh目录权限为700authorized_keys为600。3. 查看系统日志/var/log/secure或/var/log/auth.log获取详细错误。JSch旧版本如0.1.54无法使用新密钥库本身不支持新算法。1.首选升级项目依赖的JSch版本到0.1.55。2.备选在服务器sshd配置中临时启用ssh-rsa安全风险。3.终极方案考虑使用其他支持新算法的Java SSH库如Apache MINA SSHD或SSHJ。6.2 实战心得与技巧密钥管理为不同的客户端或环境使用不同的密钥对并通过-f参数指定不同的文件名如id_rsa_for_jenkins,id_rsa_for_legacy_app。这样在出问题时容易隔离和替换。密码短语与自动化对于自动化脚本CI/CD流水线使用密码短语会增加复杂度因为需要提供密码。通常的做法是生成一个无密码短语的密钥但务必严格控制该私钥的访问权限文件权限600并仅用于特定、受控的自动化场景。绝对不要将无密码的私钥提交到代码仓库。JSch的替代品如果JSch的兼容性问题实在难以解决或者你的项目需要更现代的特性如Ed25519密钥可以考虑迁移到其他Java SSH库例如SSHJ。SSHJ的API更现代对新的算法支持通常更好。迁移虽然有一定成本但可能是一劳永逸的解决方案。测试连接在编写集成代码前先用命令行ssh -i /path/to/private_key userhost测试你的密钥对是否能成功连接。这能快速排除密钥本身和服务器授权的问题将问题范围缩小到客户端代码。关注日志无论是JSch的调试日志还是服务器端的认证日志/var/log/secure都是解决问题的金钥匙。养成第一时间查看日志的习惯错误信息往往直接指明了方向。通过以上步骤你应该能够成功搭建起高版本OpenSSH服务器与JSch客户端之间的安全桥梁。这个问题的解决本质上是一次安全策略升级下的适配工作理解其背后的算法协商机制就能举一反三应对未来可能出现的类似兼容性挑战。

相关新闻

K8s Secret 管理进阶:从 Base64 到 External Secrets Operator

K8s Secret 管理进阶:从 Base64 到 External Secrets Operator

K8s Secret 管理进阶:从 Base64 到 External Secrets OperatorK8s Secret 的 Base64 编码不是加密——任何人拿到 Secret 文件都能解码。你的密码其实在裸奔。一、场景痛点 你的 K8s 集群用原生 Secret 存数据库密码、API Key、TLS 证书。Secret 的数据是 Base64 编…

2026/7/29 16:09:18阅读更多 →
基于扩散模型的音频生成:与自回归方法的架构差异与取舍

基于扩散模型的音频生成:与自回归方法的架构差异与取舍

基于扩散模型的音频生成:与自回归方法的架构差异与取舍音频生成不是"文字生成换个数据格式"——扩散模型和自回归模型在音频上的取舍完全不同。一、场景痛点 你需要一个音频生成模型。自回归模型(如 MusicLM、AudioLM)生成的音频连…

2026/7/29 16:09:18阅读更多 →
10分钟掌握EPUB编辑器:在浏览器中制作专业电子书的完整指南

10分钟掌握EPUB编辑器:在浏览器中制作专业电子书的完整指南

10分钟掌握EPUB编辑器:在浏览器中制作专业电子书的完整指南 【免费下载链接】EPubBuilder 一款在线的epub格式书籍编辑器 项目地址: https://gitcode.com/gh_mirrors/ep/EPubBuilder 你是否曾经想要制作自己的电子书,却被复杂的EPUB格式和专业的桌…

2026/7/29 16:09:18阅读更多 →
2026国内AI写歌工具实测 零基础新手首选推荐

2026国内AI写歌工具实测 零基础新手首选推荐

近几年AI写歌的门槛越来越低,不少零基础的普通人也想尝试创作属于自己的歌曲。但网上工具推荐五花八门,有的吹海外工具神乎其神,实际国内用起来处处是坑;有的打着“完全免费”的旗号,点进去才发现要签到、拉新、看广告…

2026/7/29 17:31:39阅读更多 →
租赁系统架构设计:前后端分离 + 支付宝对接

租赁系统架构设计:前后端分离 + 支付宝对接

标签:租赁系统架构、前后端分离、PHP8、Vue3、小程序开发、支付接口集成、数字化租赁 免责声明:本文以承信租作为真实业务落地案例,仅做架构技术拆解、开发方案科普,纯全栈开发技术干货分享。 摘要 租赁行业线上业务覆盖小程序租…

2026/7/29 17:31:39阅读更多 →
界面控件DevExpress WinForms Sunburst组件,轻松可视化分层扁平数据!

界面控件DevExpress WinForms Sunburst组件,轻松可视化分层扁平数据!

DevExpress WinForms Sunburst控件允许用户以紧凑和视觉上吸引人的方式可视化分层和扁平数据。 DevExpress WinForms有180组件和UI库,能为Windows Forms平台创建具有影响力的业务解决方案。同时能完美构建流畅、美观且易于使用的应用程序,无论是Office风…

2026/7/29 17:31:39阅读更多 →
告别付费!PDF/HTML转高清长图,100%免费开源,600DPI超清画质!

告别付费!PDF/HTML转高清长图,100%免费开源,600DPI超清画质!

🚀 告别付费!PDF/HTML转高清长图,100%免费开源,600DPI超清画质! 痛点终结者:网上随便一搜“PDF转长图”,要么收费单次几十块,要么免费只给一页且模糊如马赛克,要么限制次…

2026/7/29 17:31:39阅读更多 →
如何用自动化脚本让B站抽奖中奖率提升300%:终极指南

如何用自动化脚本让B站抽奖中奖率提升300%:终极指南

如何用自动化脚本让B站抽奖中奖率提升300%:终极指南 【免费下载链接】LotteryAutoScript Bili动态抽奖助手 项目地址: https://gitcode.com/gh_mirrors/lo/LotteryAutoScript 还在为错过B站热门抽奖而烦恼吗?每天手动转发几十条动态却总是与大奖擦…

2026/7/29 17:31:39阅读更多 →
d2dx:暗黑破坏神2现代化的终极解决方案

d2dx:暗黑破坏神2现代化的终极解决方案

d2dx:暗黑破坏神2现代化的终极解决方案 【免费下载链接】d2dx D2DX is a complete solution to make Diablo II run well on modern PCs, with high fps and better resolutions. 项目地址: https://gitcode.com/gh_mirrors/d2/d2dx 还在为经典《暗黑破坏神2…

2026/7/29 17:29:39阅读更多 →
覆盖国产 + 海外 + 开源模型,OpenClaw 2.7.9 Windows/Mac 双端部署详解

覆盖国产 + 海外 + 开源模型,OpenClaw 2.7.9 Windows/Mac 双端部署详解

🔹 工具基础介绍 OpenClaw 是开源生态中一款实用性较强的本地智能工具,凭借本地离线运行、可视化图形操作和任务自动化三大核心特性,赢得了众多用户的青睐。与普通在线对话AI工具不同,它属于能够直接操控本机软硬件的智能数字员工…

2026/7/29 9:47:45阅读更多 →
伺服阀焊完微漏毁整机?精密激光焊接三关锁住高压

伺服阀焊完微漏毁整机?精密激光焊接三关锁住高压

所谓液压伺服阀体的精密激光焊接,是用激光束对阀座壳体(通常为不锈钢或铝合金)进行密封焊接,使阀体在21-35MPa的高压液压油或压缩气体中长期运行而不发生介质泄漏。液压伺服阀是高端液压系统的"大脑"。从航空航天飞行控…

2026/7/29 7:00:19阅读更多 →
D2DX:三步实现《暗黑破坏神2》高清宽屏体验的终极指南

D2DX:三步实现《暗黑破坏神2》高清宽屏体验的终极指南

D2DX:三步实现《暗黑破坏神2》高清宽屏体验的终极指南 【免费下载链接】d2dx D2DX is a complete solution to make Diablo II run well on modern PCs, with high fps and better resolutions. 项目地址: https://gitcode.com/gh_mirrors/d2/d2dx 你是否还在…

2026/7/29 7:58:51阅读更多 →
28. Agent 执行到一半想暂停?用 interrupt 给它设个“关卡“!

28. Agent 执行到一半想暂停?用 interrupt 给它设个“关卡“!

28. Agent 执行到一半想暂停?用 interrupt 给它设个“关卡“! 在构建复杂的 Agent 系统时,我们经常会遇到这样的场景:Agent 正在执行一个多步骤的任务,比如“下单购买商品”,但执行到一半时,我们…

2026/7/29 0:01:46阅读更多 →
自律同行,突破无界!NANK南卡正式官宣曾舜晞成为品牌代言人

自律同行,突破无界!NANK南卡正式官宣曾舜晞成为品牌代言人

近日,国际专注开放式技术研发的声学品牌Nank南卡,正式官宣实力艺人曾舜晞担任品牌代言人。消息一经发出便轰动全网。为什么耳机品牌不选择流量明星、老牌歌手?而且是选择曾舜晞?让我们一起来探索一下!比起短期的流量&a…

2026/7/29 0:01:46阅读更多 →
【RT-DETR多模态创新改进】CVPR 2025 | 独家特征融合创新改进篇 | 引入RLAB残差线性注意力模块,有效融合并强调多尺度特征,多种改进点,适合红外与可见光融合目标检测任务,有效涨点

【RT-DETR多模态创新改进】CVPR 2025 | 独家特征融合创新改进篇 | 引入RLAB残差线性注意力模块,有效融合并强调多尺度特征,多种改进点,适合红外与可见光融合目标检测任务,有效涨点

一、本文介绍 🔥本文在RT-DETR多模态融合目标检测中引入RLAB残差线性注意力模块,可在不同模态特征交互阶段进行多次残差细化,使可见光、红外等特征在尺度、语义和空间位置上更好对齐;随后将细化特征与解码器输出拼接并生成Q、K、V,通过线性注意力自适应强化关键通道、目…

2026/7/29 0:01:46阅读更多 →
YOLOv8推理性能优化:从1.2FPS到35FPS的全链路加速实践

YOLOv8推理性能优化:从1.2FPS到35FPS的全链路加速实践

如果你在部署 YOLOv8 时,发现推理速度只有可怜的 1-2 FPS,而别人的演示视频却能跑到 30 FPS 以上,那么问题很可能不在模型本身,而在于你的整个处理链路。很多开发者拿到一个训练好的 YOLOv8 模型后,会直接使用官方示例…

2026/7/28 20:22:24阅读更多 →
Coze与Dify对比指南:低代码AI应用开发从入门到实战

Coze与Dify对比指南:低代码AI应用开发从入门到实战

1. 从零到一:为什么你需要了解 Coze 和 Dify?如果你对 AI 应用开发感兴趣,但一看到“大模型”、“智能体”、“工作流”这些词就头疼,觉得门槛太高,那这篇文章就是为你准备的。很多开发者,包括我自己&#…

2026/7/29 4:31:51阅读更多 →
AI生图工具怎么选?2026年6月版实测对比

AI生图工具怎么选?2026年6月版实测对比

做自媒体的朋友应该都有体会:配图一直是个让人头疼的问题。2026年,AI生图工具已经非常成熟了,但工具太多反而不知道怎么选。以下是截至2026年6月我对主流AI生图工具的实测对比。Midjourney V8.1:速度之王2026年6月11日&#xff0c…

2026/7/29 14:26:42阅读更多 →