加密与编码算法全解:从原理到精通(Java & JS 实战版)

加密与编码算法全解:从原理到精通(Java & JS 实战版)

文章目录

导读:本文结合 Java 后端与 JavaScript (Node.js) 前后端代码,剖析如何正确实现 AES-GCM、RSA-OAEP 和 PBKDF2,避开常见安全陷阱。

1. 核心概念地图

类型功能是否可逆安全性典型用途
Base64编码(非加密)✅ 可逆❌ 无保密性邮件、JWT、图片内嵌
MD5 / SHA-1哈希摘要❌ 不可逆⚠️ 已不安全文件校验(仅限非敏感场景)
SHA-2 / SHA-3哈希摘要❌ 不可逆✅ 安全密码哈希、数字签名
对称加密(AES)加密✅ 可逆✅ 高(需正确使用)数据传输、数据库加密
非对称加密(RSA)加密/签名✅ 可逆✅ 高(需足够密钥长度)密钥交换、身份认证
关键区分编码 ≠ 加密(Base64 是编码)哈希 ≠ 加密(MD5/SHA 是单向函数)加密必须可逆(否则无法还原数据)

2. 对称加密:AES 的内部解剖与实战

AES (Advanced Encryption Standard) 是基于SP 网络(代换-置换网络)的。它是目前最流行的对称加密算法。

2.1 AES 单轮变换流程图

AES 加密不是一步完成的,而是需要多轮迭代(AES-128 为 10 轮)。下图展示了核心的数据处理流向:

是 Rounds 1-9

否 Final Round

输入: 128位明文块

AddRoundKey (与轮密钥异或)

SubBytes (S盒替换)

ShiftRows (行移位)

MixColumns (列混合)

AddRoundKey (与轮密钥异或)

SubBytes (S盒替换)

ShiftRows (行移位)

AddRoundKey (最终轮密钥异或)

输出: 128位密文块

轮次计数 < 9?

2.2 分组模式详解:ECB vs CBC

AES 只能处理 16 字节(128位)的块。对于长数据,需要模式来切分。下图对比了不安全的 ECB 模式与安全的 CBC 模式:

CBC 模式 - 安全

异或 XOR

AES加密

异或 XOR

AES加密

初始化向量 IV

明文块1

密文1

明文块2

密文2

ECB 模式 - 不安全

AES加密

AES加密

AES加密

明文块1

密文1

明文块1

密文块

明文块2

密文2

图解说明ECB:相同的明文块(如 P1_1 和 P1_2)生成了完全相同的密文块,这会暴露数据的统计规律(例如加密一张黑白图片,轮廓依然可见)。CBC:引入了随机初始化向量(IV),并将上一个密文块参与到下一个块的加密中。即使明文相同,只要 IV 不同,密文就完全不同。

2.3 实战:AES-GCM 加密与解密

推荐使用 AES-GCM 模式,因为它不仅加密数据,还生成认证标签,防止篡改。

Java (JDK 11+)

Java 标准库 javax.crypto 提供了完整的 AES-GCM 支持。

importjavax.crypto.Cipher;importjavax.crypto.spec.GCMParameterSpec;importjavax.crypto.spec.SecretKeySpec;importjava.security.SecureRandom;importjava.util.Base64;publicclassAesGcmExample{privatestaticfinalString AES_GCM_NO_PADDING ="AES/GCM/NoPadding";privatestaticfinalint GCM_TAG_LENGTH_BITS =128;// 必须是 128, 120 或 112privatestaticfinalint GCM_IV_LENGTH_BYTES =12;// 推荐长度 12 bytespublicstaticStringencrypt(byte[] plaintext,byte[] key)throwsException{// 1. 生成随机 IV (Nonce)byte[] iv =newbyte[GCM_IV_LENGTH_BYTES];newSecureRandom().nextBytes(iv);// 2. 初始化 CipherSecretKeySpec keySpec =newSecretKeySpec(key,"AES");GCMParameterSpec gcmSpec =newGCMParameterSpec(GCM_TAG_LENGTH_BITS, iv);Cipher cipher =Cipher.getInstance(AES_GCM_NO_PADDING); cipher.init(Cipher.ENCRYPT_MODE, keySpec, gcmSpec);// 3. 加密byte[] ciphertext = cipher.doFinal(plaintext);// 4. 拼接 IV 和 Ciphertext (IV 不需要保密,但必须和密文一起传输)byte[] encryptedBytes =newbyte[iv.length + ciphertext.length];System.arraycopy(iv,0, encryptedBytes,0, iv.length);System.arraycopy(ciphertext,0, encryptedBytes, iv.length, ciphertext.length);returnBase64.getEncoder().encodeToString(encryptedBytes);}publicstaticStringdecrypt(String encryptedStr,byte[] key)throwsException{// 1. 解码 Base64byte[] encryptedBytes =Base64.getDecoder().decode(encryptedStr);// 2. 分离 IV 和 Ciphertextbyte[] iv =newbyte[GCM_IV_LENGTH_BYTES];System.arraycopy(encryptedBytes,0, iv,0, iv.length);byte[] ciphertext =newbyte[encryptedBytes.length - GCM_IV_LENGTH_BYTES];System.arraycopy(encryptedBytes, iv.length, ciphertext,0, ciphertext.length);// 3. 初始化 Cipher 解密SecretKeySpec keySpec =newSecretKeySpec(key,"AES");GCMParameterSpec gcmSpec =newGCMParameterSpec(GCM_TAG_LENGTH_BITS, iv);Cipher cipher =Cipher.getInstance(AES_GCM_NO_PADDING); cipher.init(Cipher.DECRYPT_MODE, keySpec, gcmSpec);// 4. 解密 (如果被篡改,此处会抛出 AEADBadTagException)byte[] plaintext = cipher.doFinal(ciphertext);returnnewString(plaintext);}publicstaticvoidmain(String[] args)throwsException{byte[] key =newbyte[32];// AES-256 Key (在实际应用中请从 KMS 获取)newSecureRandom().nextBytes(key);String msg ="Top Secret Message";String encrypted =encrypt(msg.getBytes(), key);System.out.println("Encrypted: "+ encrypted);String decrypted =decrypt(encrypted, key);System.out.println("Decrypted: "+ decrypted);}}
JavaScript (Node.js)

Node.js 内置 crypto 模块处理 GCM 模式非常方便。

const crypto =require('crypto');constALGO_NAME='aes-256-gcm';constIV_LENGTH=12;// 12 bytesconstKEY_LENGTH=32;// 32 bytes for AES-256functionencrypt(text, key){// 1. 生成随机 IVconst iv = crypto.randomBytes(IV_LENGTH);// 2. 创建加密器const cipher = crypto.createCipheriv(ALGO_NAME, key, iv);// 3. 加密 (Buffer.concat 拼接)let encrypted = cipher.update(text,'utf8'); encrypted = Buffer.concat([encrypted, cipher.final()]);// 4. 获取 Auth Tag (必须随密文发送)const authTag = cipher.getAuthTag();// 5. 返回: IV + AuthTag + Ciphertext (通常拼接后转 Base64)return Buffer.concat([iv, authTag, encrypted]).toString('base64');}functiondecrypt(encryptedData, key){// 1. 解码 Base64const buffer = Buffer.from(encryptedData,'base64');// 2. 提取 IV, AuthTag, Ciphertextconst iv = buffer.subarray(0,IV_LENGTH);const authTag = buffer.subarray(IV_LENGTH,IV_LENGTH+16);// GCM Tag 默认 16 bytesconst ciphertext = buffer.subarray(IV_LENGTH+16);// 3. 创建解密器并设置 AuthTag (验证数据完整性的关键)const decipher = crypto.createDecipheriv(ALGO_NAME, key, iv); decipher.setAuthTag(authTag);// 4. 解密let decrypted = decipher.update(ciphertext); decrypted = Buffer.concat([decrypted, decipher.final()]);return decrypted.toString('utf8');}// 使用示例const key = crypto.randomBytes(KEY_LENGTH);// 生成随机密钥const msg ="Top Secret Message";const encrypted =encrypt(msg, key); console.log("Encrypted:", encrypted);const decrypted =decrypt(encrypted, key); console.log("Decrypted:", decrypted);

3. 非对称加密:RSA 的数理逻辑

RSA 的安全性依赖于大整数分解难题。

3.1 RSA 密钥生成流程图

下图展示了从选择质数到生成公私钥对的完整数学逻辑流程:

开始: 生成密钥对

随机选择两个大质数 p, q

计算模数 n = p * q

计算欧拉函数 phi = p-1 * q-1

选择公钥指数 e
条件: 1 < e < phi 且互质

计算私钥指数 d
条件: e * d ≡ 1 mod phi

生成结果

公钥
n, e

私钥
n, d

3.2 填充的重要性:OAEP

直接用 RSA 加密数据(教科书式 RSA)是极其危险的。必须使用填充OAEP (Optimal Asymmetric Encryption Padding) 是目前的标准。

为何需要 OAEP? 没有填充的 RSA 是确定性的(相同的明文永远得到相同的密文),且容易满足特定数学结构导致被破解。OAEP 引入了随机性,使加密变成概率性的。

3.3 实战:RSA-OAEP 加密与解密

注意:RSA 速度慢,通常只用来加密对称密钥,不直接加密大文件。

Java (JDK 11+)

使用 RSA/ECB/OAEPWithSHA-256AndMGF1Padding

importjavax.crypto.Cipher;importjava.security.KeyPair;importjava.security.KeyPairGenerator;importjava.security.SecureRandom;importjava.util.Base64;publicclassRsaOaepExample{publicstaticvoidmain(String[] args)throwsException{// 1. 生成 RSA 密钥对 (2048位)KeyPairGenerator keyGen =KeyPairGenerator.getInstance("RSA"); keyGen.initialize(2048,newSecureRandom());KeyPair keyPair = keyGen.generateKeyPair();String message ="Here is the AES Key: 1234567890123456";// 2. 加密 (使用公钥)// OAEPWithSHA-256AndMGF1Padding 是最安全的配置之一Cipher encryptCipher =Cipher.getInstance("RSA/ECB/OAEPWithSHA-256AndMGF1Padding"); encryptCipher.init(Cipher.ENCRYPT_MODE, keyPair.getPublic());byte[] encryptedBytes = encryptCipher.doFinal(message.getBytes());System.out.println("Encrypted: "+Base64.getEncoder().encodeToString(encryptedBytes));// 3. 解密 (使用私钥)Cipher decryptCipher =Cipher.getInstance("RSA/ECB/OAEPWithSHA-256AndMGF1Padding"); decryptCipher.init(Cipher.DECRYPT_MODE, keyPair.getPrivate());byte[] decryptedBytes = decryptCipher.doFinal(encryptedBytes);System.out.println("Decrypted: "+newString(decryptedBytes));}}
JavaScript (Node.js)

使用 crypto.publicEncryptoaepHash 选项。

const crypto =require('crypto');// 1. 生成密钥对const{ publicKey, privateKey }= crypto.generateKeyPairSync('rsa',{modulusLength:2048,publicKeyEncoding:{type:'spki',format:'pem'},privateKeyEncoding:{type:'pkcs8',format:'pem'}});const message ="Here is the AES Key: 1234567890123456";// 2. 加密 (使用公钥)const encrypted = crypto.publicEncrypt({key: publicKey,padding: crypto.constants.RSA_PKCS1_OAEP_PADDING,oaepHash:"sha256"// 指定 OAEP 的 Hash 算法}, Buffer.from(message)); console.log("Encrypted (len):", encrypted.length);// 3. 解密 (使用私钥)const decrypted = crypto.privateDecrypt({key: privateKey,padding: crypto.constants.RSA_PKCS1_OAEP_PADDING,oaepHash:"sha256"}, encrypted ); console.log("Decrypted:", decrypted.toString());

4. 数字签名:身份验证

数字签名是“私钥加密哈希”的现代严谨说法(实际操作略有不同,常用 PSS 填充)。

4.1 签名生成与验证流程

下图展示了发送方如何使用私钥签名,接收方如何使用公钥验证身份和完整性:

接收方发送方接收方发送方1. 准备数据2. 验证数据alt[Hash_A == Hash_B][Hash_A != Hash_B]计算原始消息的哈希值 Hash_A使用私钥加密 Hash_A 生成签名 Signature发送 [原始消息] + [数字签名]计算收到消息的哈希值 Hash_B使用公钥解密签名 得到 Hash_A✅ 验证通过(数据完整且来源真实)❌ 验证失败(数据已篡改或来源伪造)

4.2 实战:RSASSA-PSS 签名

Java 11+ 和 Node.js 均原生支持 PSS 填充,这是比 PKCS#1 v1.5 更安全的签名方案。

Java (JDK 11+)
importjava.security.*;importjava.util.Base64;publicclassRsaPssExample{publicstaticvoidmain(String[] args)throwsException{// 1. 生成密钥对KeyPairGenerator keyGen =KeyPairGenerator.getInstance("RSA"); keyGen.initialize(2048);KeyPair keyPair = keyGen.generateKeyPair();String message ="Important contract content";// 2. 签名 (使用私钥)// RSASSA-PSS 配置Signature signature =Signature.getInstance("RSASSA-PSS"); signature.setParameter(newPSSParameterSpec("SHA-256","MGF1",MGF1ParameterSpec.SHA256,32,1)); signature.initSign(keyPair.getPrivate()); signature.update(message.getBytes());byte[] signatureBytes = signature.sign();System.out.println("Signature: "+Base64.getEncoder().encodeToString(signatureBytes));// 3. 验证 (使用公钥)Signature verifier =Signature.getInstance("RSASSA-PSS"); verifier.setParameter(newPSSParameterSpec("SHA-256","MGF1",MGF1ParameterSpec.SHA256,32,1)); verifier.initVerify(keyPair.getPublic()); verifier.update(message.getBytes());boolean isValid = verifier.verify(signatureBytes);System.out.println("Signature valid? "+ isValid);}}
JavaScript (Node.js)
const crypto =require('crypto');const{ publicKey, privateKey }= crypto.generateKeyPairSync('rsa',{modulusLength:2048,publicKeyEncoding:{type:'spki',format:'pem'},privateKeyEncoding:{type:'pkcs8',format:'pem'}});const message ="Important contract content";// 1. 签名const sign = crypto.createSign('sha256'); sign.update(message); sign.end();const signature = sign.sign({key: privateKey,padding: crypto.constants.RSA_PKCS1_PSS_PADDING,saltLength: crypto.constants.RSA_PSS_SALTLEN_DIGEST// 盐长度等于摘要长度}); console.log("Signature (len):", signature.length);// 2. 验证const verify = crypto.createVerify('sha256'); verify.update(message); verify.end();const isValid = verify.verify({key: publicKey,padding: crypto.constants.RSA_PKCS1_PSS_PADDING,saltLength: crypto.constants.RSA_PSS_SALTLEN_DIGEST}, signature); console.log("Signature valid?", isValid);

5. 混合加密实战:HTTPS (TLS 1.2) 握手全流程

这是现代互联网安全的基础,结合了非对称加密(交换密钥)和对称加密(传输数据)。

ServerClientServerClient5. 验证证书 & 生成预主密钥7. [使用私钥解密] 得到预主密钥8. 双方共同计算会话密钥 = PRF(随机数C + 随机数S + 预主密钥)======== 建立安全通道 ========1. ClientHello(支持的加密套件, 随机数C)2. ServerHello(选定加密套件, 随机数S)3. Certificate(包含服务器公钥)4. ServerHelloDone6. [使用公钥加密] 预主密钥9. ChangeCipherSpec通知后续加密10. Finished(使用会话密钥加密的校验消息)11. ChangeCipherSpec12. Finished[使用 AES/会话密钥] 加密的应用数据[使用 AES/会话密钥] 加密的应用数据

:TLS 1.3 对此进行了优化,移除了 RSA 密钥交换,强制使用 ECDHE,仅需 1-RTT(往返延迟)。

5.1 实战:使用 OpenSSL 分析 HTTPS 握手

作为开发者,你可以使用命令行工具验证上述流程(无论你用 Java 还是 JS,底层的 TLS 逻辑都是一样的):

# 查看网站证书信息 openssl s_client -connect google.com:443 -showcerts # 查看协商出的加密套件和会话密钥参数(需开启 SSLKEYLOGFILE)# 环境变量: export SSLKEYLOGFILE=~/keys.log# 然后使用 Wireshark 打开 keys.log 即可解密 HTTPS 流量查看明文

6. 密码存储与哈希:PBKDF2 实战

千万不要用 MD5 存密码!请使用 KDF (Key Derivation Function)

Java (JDK 8+)

使用 SecretKeyFactoryPBKDF2WithHmacSHA256

importjavax.crypto.SecretKeyFactory;importjavax.crypto.spec.PBEKeySpec;importjava.security.SecureRandom;importjava.util.Base64;publicclassPasswordHashing{privatestaticfinalint ITERATIONS =100000;privatestaticfinalint KEY_LENGTH =256;// bitsprivatestaticfinalint SALT_LENGTH =16;// bytesprivatestaticfinalString ALGO ="PBKDF2WithHmacSHA256";publicstaticStringhashPassword(String password)throwsException{// 1. 生成随机盐SecureRandom random =newSecureRandom();byte[] salt =newbyte[SALT_LENGTH]; random.nextBytes(salt);// 2. 计算哈希PBEKeySpec spec =newPBEKeySpec(password.toCharArray(), salt, ITERATIONS, KEY_LENGTH);SecretKeyFactory factory =SecretKeyFactory.getInstance(ALGO);byte[] hash = factory.generateSecret(spec).getEncoded();// 3. 存储: salt + hash (转 Hex)returnbytesToHex(salt)+":"+bytesToHex(hash);}publicstaticbooleanverifyPassword(String storedHash,String inputPassword)throwsException{String[] parts = storedHash.split(":");byte[] salt =hexToBytes(parts[0]);byte[] storedHashBytes =hexToBytes(parts[1]);// 4. 使用同样的盐计算输入密码的哈希PBEKeySpec spec =newPBEKeySpec(inputPassword.toCharArray(), salt, ITERATIONS, KEY_LENGTH);SecretKeyFactory factory =SecretKeyFactory.getInstance(ALGO);byte[] inputHashBytes = factory.generateSecret(spec).getEncoded();// 5. 对比returnslowEquals(storedHashBytes, inputHashBytes);}// 辅助:防时序攻击比较privatestaticbooleanslowEquals(byte[] a,byte[] b){int diff = a.length ^ b.length;for(int i =0; i < a.length && i < b.length; i++){ diff |= a[i]^ b[i];}return diff ==0;}privatestaticStringbytesToHex(byte[] bytes){StringBuilder sb =newStringBuilder();for(byte b : bytes) sb.append(String.format("%02x", b));return sb.toString();}privatestaticbyte[]hexToBytes(String s){int len = s.length();byte[] data =newbyte[len /2];for(int i =0; i < len; i +=2){ data[i /2]=(byte)((Character.digit(s.charAt(i),16)<<4)+Character.digit(s.charAt(i+1),16));}return data;}}
JavaScript (Node.js)

使用 crypto.pbkdf2 (Async/Promise 版本)。

const crypto =require('crypto');constITERATIONS=100000;constKEY_LENGTH=32;// 32 bytes = 256 bitsconstDIGEST='sha256';constSALT_LENGTH=16;// 使用 Promise 包装异步操作functionhashPassword(password){returnnewPromise((resolve, reject)=>{const salt = crypto.randomBytes(SALT_LENGTH); crypto.pbkdf2(password, salt,ITERATIONS,KEY_LENGTH,DIGEST,(err, derivedKey)=>{if(err)returnreject(err);// 存储: salt + hash (转 hex)const stored = salt.toString('hex')+':'+ derivedKey.toString('hex');resolve(stored);});});}functionverifyPassword(storedHash, password){returnnewPromise((resolve, reject)=>{const[saltHex, hashHex]= storedHash.split(':');const salt = Buffer.from(saltHex,'hex'); crypto.pbkdf2(password, salt,ITERATIONS,KEY_LENGTH,DIGEST,(err, derivedKey)=>{if(err)returnreject(err);const derivedKeyHex = derivedKey.toString('hex');// 使用 crypto.timingSafeEqual 防止时序攻击const keyBuffer = Buffer.from(hashHex,'hex');const derivedBuffer = Buffer.from(derivedKeyHex,'hex');if(keyBuffer.length !== derivedBuffer.length){returnresolve(false);}try{const match = crypto.timingSafeEqual(keyBuffer, derivedBuffer);resolve(match);}catch(e){resolve(false);}});});}// 使用示例(async()=>{const pass ="my_secure_pass";const hash =awaithashPassword(pass); console.log("Stored in DB:", hash);const isValid =awaitverifyPassword(hash, pass); console.log("Check result:", isValid);})();

7. 技术深度补充:常见攻击与防御

为了达到“精通”,必须了解敌人如何攻击。

攻击类型目标算法原理简述防御方案
重放攻击通信协议攻击者截获有效的数据包(如转账请求),再次发送。使用 Nonce (随机数)Timestamp (时间戳)。GCM 模式的 Nonce 必须唯一。
中间人攻击 (MITM)RSA/TLS攻击者冒充服务器,发送自己的公钥给客户端。验证 数字证书链,必须由受信任的 CA 签发。
填充预言攻击RSA-CBC攻击者根据解密时的报错信息(Padding Error)逐步推断明文。解密时不立即报错,使用恒定时间算法;改用 RSA-OAEP
侧信道攻击硬件/AES通过分析 CPU 执行时间、功耗或电磁辐射来推断密钥。物理隔离;使用恒定时间实现的代码库。

8. 总结:现代安全架构设计图

如果你正在设计一个安全系统,请遵循以下垂直架构层级,每一层都依赖下一层的安全支撑:

密钥管理 Key Management

存储安全 Storage Security

传输安全 Transport Layer

接口安全 API Security

应用层 Application Layer

业务逻辑

敏感数据处理

输入验证

参数清洗

TLS 1.3 / HTTPS

数据库加密 AES-256

密码存储 Argon2/PBKDF2

非硬编码密钥

KMS / HSM / Vault

精通之路:理解上述每一个箭头和模块背后的数学原理与工程妥协,并有能力在性能安全性易用性之间找到最佳的平衡点。

Read more

Flutter 组件 simple_cluster 的适配 鸿蒙Harmony 实战 - 驾驭轻量级集群分发架构、实现鸿蒙端多节点任务调度与高性能负载均衡方案

Flutter 组件 simple_cluster 的适配 鸿蒙Harmony 实战 - 驾驭轻量级集群分发架构、实现鸿蒙端多节点任务调度与高性能负载均衡方案

欢迎加入开源鸿蒙跨平台社区:https://openharmonycrossplatform.ZEEKLOG.net Flutter 组件 simple_cluster 的适配 鸿蒙Harmony 实战 - 驾驭轻量级集群分发架构、实现鸿蒙端多节点任务调度与高性能负载均衡方案 前言 在鸿蒙(OpenHarmony)生态迈向“万物互联、万物协同”的深水区后,单一设备孤岛式的算力模式已经无法满足复杂的工业控制、分布式协同办公以及大规模 IoT 设备管理的需求。面对需要将一个繁重的计算任务(如:海量 Hex 数据的指纹比对)分发给附近的 5 台鸿蒙平板协同处理;面对需要管理数十个传感器节点的实时状态同步。 如果依靠传统的手动 Socket 连接管理。那么不仅会导致通讯代码极其臃肿且难以维护。更会因为缺乏确定性的负载均衡(Load Balancing)与节点心跳(Heartbeat)逻辑。引发整个系统的雪崩式失效方案。 我们需要一种“逻辑集群化、操作极简化”的算力平衡艺术。

By Ne0inhk
Flutter for OpenHarmony:swagger_dart_code_generator 接口代码自动化生成的救星(OpenAPI/Swagger) 深度解析与鸿蒙适配指南

Flutter for OpenHarmony:swagger_dart_code_generator 接口代码自动化生成的救星(OpenAPI/Swagger) 深度解析与鸿蒙适配指南

欢迎加入开源鸿蒙跨平台社区:https://openharmonycrossplatform.ZEEKLOG.net 前言 后端工程师扔给你一个 Swagger (OpenAPI) 文档地址,你会怎么做? 1. 对着文档,手写 Dart Model 类(容易写错字段类型)。 2. 手写 Retrofit/Dio 的 API 接口定义(容易拼错 URL)。 3. 当后端修改了字段名,你对着报错修半天。 这是重复劳动的地狱。 swagger_dart_code_generator 可以将 Swagger (JSON/YAML) 文件直接转换为高质量的 Dart 代码,包括: * Model 类:支持 json_serializable,带 fromJson/

By Ne0inhk
[特殊字符]颠覆MCP!Open WebUI新技术mcpo横空出世!支持ollama!轻松支持各种MCP Server!Cline+Claude3.7轻松开发论文检索MCP Server!

[特殊字符]颠覆MCP!Open WebUI新技术mcpo横空出世!支持ollama!轻松支持各种MCP Server!Cline+Claude3.7轻松开发论文检索MCP Server!

🔥🔥🔥本篇笔记所对应的视频:🚀颠覆MCP!Open WebUI新技术mcpo横空出世!支持ollama!轻松支持各种MCP Server!Cline+Claude3.7轻松开发MCP服务_哔哩哔哩_bilibili Open WebUI 的 MCPo 项目:将 MCP 工具无缝集成到 OpenAPI 的创新解决方案 随着人工智能工具和模型的快速发展,如何高效、安全地将这些工具集成到标准化的 API 接口中成为了开发者面临的重要挑战。Open WebUI 的 MCPo 项目(Model Context Protocol-to-OpenAPI Proxy Server)正是为了解决这一问题而设计的。本文将带您深入了解 MCPo 的功能、优势及其对开发者生态的影响。 什么是 MCPo? MCPo 是一个简单、可靠的代理服务器,能够将任何基于 MCP 协议的工具转换为兼容

By Ne0inhk