许可证与合规风险:误用GPL/AGPL加密库
加密SDK接入,技术选型只是第一步。
真正让你夜不能寐的,往往不是算法跑得不够快,而是——你用的那个库,到底能不能用在企业产品里?
我见过不止一个团队,花了好几个月接入一个开源的加密库,代码写完了,审查过了,结果法务突然跳出来说:这库是GPL的,不能放。改动,重来,工期泡汤。
咱今天就来聊聊这件事。
GPL/AGPL 的核心陷阱
先明确一件事。
GPL 和 AGPL 不是普通的开源许可证。它们属于“强著佐权”(Strong Copyleft)许可证。说白了,它们的要求是:
- 如果你在项目里用了GPL的代码,那么你的整个项目——无论是否直接修改——都必须以GPL协议开源。
- AGPL更激进,它把GPL对“分发”的限制,延伸到了“网络交互”。你架个Web服务,只要用到了AGPL代码,你就必须把完整源码给所有用户。
对企业产品来说,这就非常麻烦了。
你不可能把自研的核心算法、业务逻辑、数据库结构全都公开出去。那不是开源,那是裸奔。
为什么加密库成了“重灾区”?
我遇到过几个真实案例。
有一个团队做金融安全产品,需要RSA和AES的加密实现。他们图省事,直接从GitHub上拉了个高星仓库,star数两千多,看起来靠谱。结果呢?
这个库的许可证是 GPL-3.0-only。他们没有注意到。代码直接静态链接进了主程序。等到内部合规审查时,法务直接叫停。
为什么加密库容易踩这个坑?三个原因:
- 加密库往往是“基础设施”——你很少为一个加密算法单独写一个微服务,基本都是直接链接进去。
- GPL/AGPL库伪装成“宽松许可”——很多开发者只看README不看LICENSE文件。
- 修改了也不行——GPL的传染性不因为你“改了几行代码”就消失。
商业授权 vs 开源许可证
这里有个表格,我把常见的加密库许可类型做了个对比。你对照着看,心里就有底了。
| 许可证 | 类型 | 企业内部使用 | 分发产品 | 网络服务 | 建议 |
|---|---|---|---|---|---|
| BSD-2/3 | 宽松 | ✓ | ✓ | ✓ | 常用首选 |
| MIT | 宽松 | ✓ | ✓ | ✓ | 常用首选 |
| Apache-2.0 | 宽松 | ✓ | ✓ | ✓ | 商业友好 |
| LGPL-2.1/3.0 | 弱著佐权 | ✓ | 动态链接可豁免 | ✓ | 需谨慎 |
| GPL-2.0/3.0 | 强著佐权 | ✓ | ✗(要求全量开源) | ✓ | 避免使用 |
| AGPL-3.0 | 最强著佐权 | ✓ | ✗ | ✗(网络交互也要求开源) | 远离 |
这里有个小细节。
LGPL允许你在动态链接的情况下,不把主程序开源。但是很多加密SDK是纯C写的,你不可能在Java或Go里动态链接C库的细节……所以LGPL有时也救不了你。
最常见的“高危函数”清单
我个人的习惯是:在项目初期,就列一张“高风险函数调用”清单。凡是涉及第三方库的加密接口调用,都必须提前过一遍许可证。
我给你列一个参考清单,这些函数在GPL/AGPL加密库中的出现频率极高:
// 这些函数所在的库,你必须检查许可证
EVP_CIPHER_CTX_new() // 许多GPL的OpenSSL替代品
RSA_generate_key_ex() // GnuTLS 或 LibreSSL 变体
EC_KEY_new_by_curve_name() // 有些mbedTLS分支是GPL的
SHA256_Init() // 旧版OpenSSL之外的实现
EVP_PKEY_encrypt() // 不要只看函数名,看库来源
你注意看,上面这些函数本身没有问题。问题在于:你调用的这个实现库的许可证是什么。
同一个函数名,可以在BSD库里有,也可以在GPL库里有。
避坑指南:我踩过的两个坑
踩坑一:静态链接的GPL加密库
我曾经…在一个嵌入式项目中,用了OpenSSL的某个GPL分支实现。当时没在意,直接把整个静态库链接进去了。产品量产之后,客户要求做开源合规审计。结果发现,我们的整个固件都必须以GPL开源。
后果:
- 重写加密层,改用mbedTLS(Apache-2.0)。
- 推迟交付2个月。
- 直接经济损失接近七位数。
避坑二:AGPL的Web API加密库
另一个项目,做API网关的加密模块。后端调用了一个AGPL-3.0的加密解析库。法务发现后说:不行,AGPL要求所有通过此API访问的用户都能获得源码。我们当时是SaaS产品,用户通过浏览器用我们的服务,这不就相当于所有人都必须得到源码吗?
最终,我们换成了Google的Tink库(Apache-2.0),合规通过。
商用授权需要注意什么?
有些库是“双许可证”模式。
比如知名的加密库 OpenSSL,它的原始版本是OpenSSL许可证(类似Apache),但是很多公司会基于它修改发布GPL版本。你从GitHub上拉下来的,不一定是官方版。
再比如 wolfSSL,它提供GPL和商业授权两种选择。如果你的产品是闭源商业软件,你需要购买商业授权,否则就只能用GPL。
购买商业授权要注意三点:
- 授权范围:看清楚是“按产品授权”还是“按公司授权”。有些授权只覆盖某一个产品线。
- 衍生作品覆盖:商业授权是否覆盖了你的团队对库的修改?有些许可不包含修改后的派生作品。
- 审计条款:有些商业授权附带审计权。对方有权检查你的代码是否遵守协议。我遇到过被审计的情况,差点翻车。
我的合规检查清单
这部分是我项目的内部标准,分享给你。
合规检查清单(必做项)
- 确认每个第三方加密库的完整许可证文本,不只看README。
- 区分“直接依赖”和“传递依赖”——尤其是静态链接的依赖,容易遗漏。
- 建立许可证白名单:包含BSD-2/3、MIT、Apache-2.0、ISC;禁止:GPL、AGPL。
- 每次引入新库,必须触发法务审核流程,不能工程师自己做决定。
- 保留所有库的下载记录和版本信息,便于审计追溯。
一个典型的GPL感染流程图
我画一个简单的关系图,帮你理解代码是怎么被“感染”的。
你从这张图可以清楚的看到:只要你的产品是静态链接GPL加密库,并且对外分发(不论是出售还是免费发布),你的整个程序就必须以GPL开源。
AGPL更狠,你做个SaaS服务,用户通过网络访问你的功能,也算“分发”。
我反复强调这条路径,是因为太多人“觉得没事”。
最后说一个真实的“商业授权”弯路
有个朋友的公司,几年前做硬件密码机。
他们选了某知名加密库的商业授权版。花了十几万买授权。结果呢?合同里有一条:“本授权仅适用于固件版本v2.x.x,升级至v3.x.x需重新授权。”
他们开发到一半,发现必须用新版本修复安全漏洞。但是新版本不在授权范围。再付一次钱?还是换库?最后被迫推迟了三个月,重新做了技术选型。
所以你买商业授权时,一定要看清楚:
- 授权是永久性的还是订阅制?
- 是否覆盖所有版本升级?
- 是否包含安全补丁的授权?
建议你在采购阶段,就让法务和工程师一起参与。别让商务单独谈。很多条款,法务看不出来技术限制,工程师看得出来。
核心建议
- 白名单机制:只允许BSD、MIT、Apache-2.0、ISC的加密库。见到GPL/AGPL一律走特殊审批流程。
- 依赖树扫描:利用工具(比如FOSSA、BlackDuck、Snyk)自动扫描所有传递依赖的许可证。
- 双许可证保留备选:万一需要,立刻切换到商业授权,而不是临时找替代库。
- 法务介入:别自己决定。我看到过太多“我觉得这个库的GPL条款只针对库本身”的误解。
嗯,许可证这件事,越早重视,成本越低。