ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

AI 生成内容如何证明来源:C2PA、Content Credentials 与签名校验

AI 生成内容如何证明来源:C2PA、Content Credentials 与签名校验 生成式 AI 把图片、视频和音频的生产成本降到了很低也把一个老问题推到了前台看到一份数字内容时我们怎样知道它从哪里来、经过哪些工具、是否在发布后被替换过仅靠文件名、网页说明或“AI 生成”水印回答不了这个问题。文件名可以改网页描述可以复制肉眼可见的水印可以裁掉检测模型也只能给出概率不能重建可靠的生产链。C2PACoalition for Content Provenance and Authenticity提供了另一条路线。它不试图猜一张图是不是由 AI 生成而是让生产工具在创建和编辑时写入结构化声明用内容摘要把声明与资产绑定再用数字证书对声明签名。验证端由此可以检查声明是否仍与当前文件匹配、签名是否有效、证书能否连接到认可的信任锚、编辑历史是否存在可验证的前序材料。本文以截至写作时的正式规范 C2PA 2.4 为依据。2.4 于 2026 年 4 月发布引入了 Content Credential JSON 派生表示、仓库回执声明等能力也继续沿用 C2PA 2.x 的 X.509 信任模型。需要先把结论说在前面C2PA 验证的是来源声明、内容绑定和签名链不负责判断画面描述的事件是否真实。来源链验证成功不等于内容事实为真。一个可信机构完全可能发布错误信息一张没有内容凭证的照片也不因此必然是假图。C2PA 提供的是可审计证据不是“真相判定器”。1. 先区分三个经常混淆的问题面对一张网络图片人们常把三个问题揉在一起。第一个问题是“文件有没有在某个时间点之后被改动”它属于完整性校验第二个问题是“谁或哪个设备、软件对这份声明负责”它属于身份与信任第三个问题是“图片里的事情是否真的发生”它属于事实核查。三个问题有关联却不能互相替代。普通 SHA-256 可以回答完整性问题。发布方把原文件摘要放在可信网站用户重新计算摘要二者一致就说明字节没有变化。但摘要本身不携带编辑行为、所用工具和输入材料也没有统一展示方式。数字签名在摘要之上增加签名者身份持有私钥的一方签名验证者使用证书中的公钥校验。然而如果每家产品自定义签名容器、元数据字段和验证结果跨平台仍然无法互操作。C2PA 的价值是把资产绑定、声明结构、签名封装、证书要求、验证状态和用户体验放进同一套开放规范。它允许相机在拍摄时建立第一份凭证编辑软件把原图作为 ingredient 写入下一份凭证发布系统再补充发布动作。消费者最终看到的不是一个孤立标签而是一条可逐段检查的来源链。“AI 检测器”处理的是另一个问题。检测器从像素、频谱或语言分布推测生成概率会受到模型更新、压缩、截图、混合编辑和分布漂移影响。C2PA 则读取生产者主动提供并签名的证据。前者可能发现未声明的生成内容后者能明确记录已声明的生成过程它们可以互补但任何一方都不应被包装成百分之百准确的真假裁判。2. Content Credential 到底包含什么Content Credential 可以理解为与数字资产关联的一组可验证来源数据。技术上资产通常包含一个 Manifest Store其中可保存多份 C2PA Manifest被当前资产选中的那一份叫 active manifest。Manifest 内部主要包含 Claim、Assertions、Claim Signature 以及对前序材料的引用。Claim 是签名覆盖的核心结构。它列出本次声明引用了哪些 assertions、采用什么哈希算法、由什么 claim generator 生成。C2PA 2.4 建议在claim_generator_info中声明规范版本但这个字段只是信息提示验证器不能因为看到“2.4.0”就跳过实际结构和签名校验。Assertions 是具体陈述。例如 actions assertion 可以记录创建、打开、调整尺寸或生成式处理等动作ingredient assertion 可以指向作为输入的原图、音轨或其他媒体metadata assertion 可以保存规范允许的元数据缩略图、数据类型和软绑定信息也有各自结构。声明“由训练算法生成”是一条来源陈述不是对输出质量和事实正确性的担保。Claim Signature 通常采用 COSE Sign1 结构由符合规范要求的 X.509 证书和私钥生成。签名保护 ClaimClaim 又通过带哈希的引用保护 Assertions。资产本体通过 hard binding 与 Manifest 关联所以替换像素、音频帧或受保护字节后内容绑定校验会失败。这个层层引用的结构避免了“只签元数据却没有签文件”的漏洞。有效且受信有效但未知签发者绑定或签名失败没有凭证相机或生成模型创建资产Claim Generator组织 Assertions计算 Hard Binding绑定资产字节私钥签署 Claim附证书链与时间戳嵌入或外置C2PA Manifest Store分发平台保存资产Manifest Consumer读取与验证策略判定展示来源与编辑历史展示来源未知警告可能被篡改显示无可用来源信息Manifest 可以嵌入 JPEG、PNG、MP4、PDF 等受支持格式也可以作为外部资源被引用。嵌入方式便于凭证随文件流转但某些社交平台会重新编码并删除元数据外置方式便于集中管理却依赖网络地址和仓库可用性。C2PA 的 durable Content Credential 通过软绑定增强找回能力例如使用不可见水印或指纹去仓库查询 Manifest。软绑定适合恢复线索硬绑定仍承担精确完整性校验两者不能互换。3. 签名可信要经过四层判断开发者最容易犯的错误是看到“signature valid”就把页面标成“真实”。生产验证至少要区分四层状态。第一层是well-formed。验证器能否解析容器、Manifest、Claim、Assertions 和签名结构格式错误、字段类型错误或无法解析的对象在这一层失败。能够解析只说明语法成立不说明内容绑定或签名有效。第二层是valid manifest 与 valid asset。验证器重新计算 Assertions 哈希、Claim 引用和资产 hard binding确认摘要匹配并检查 COSE 签名。如果当前文件被重新压缩、裁切或替换而没有生成新的 Manifest资产绑定会失败。如果 Claim 被修改签名会失败。这层回答的是“自签名以来这份受保护内容和声明是否保持一致”。第三层是trusted。有效签名可以来自未知测试证书或企业私有 CA。只有证书链连接到验证器认可的信任锚并通过用途、有效期、撤销和相关策略检查验证器才应把它归为受信来源。C2PA 提供 Trust List 和 TSA Trust List企业也可以为内部工作流配置自己的信任锚。测试证书签出的文件可以完整且签名有效但不应在公网产品中显示为已知可信签发者。第四层是业务可信判断。消费者根据签名者、声明内容、使用场景和其他证据决定是否采信。例如新闻编辑部可能信任合作通讯社的签名却不接受未知个人证书保险理赔系统还要核对拍摄时间、设备登记、案件编号和反欺诈信号。C2PA 规范不替业务做这个决定。因此界面至少要能表达“无凭证”“凭证结构损坏”“签名或内容绑定失败”“签名有效但签发者未知”“签名有效且来自受信签发者”。把这些状态压成绿色和红色两个图标会把未知误报成恶意也会把签名有效误报成事实真实。4. 一条完整的签发链怎样建立设想一个电商团队使用生成模型制作商品背景图。原始商品照片来自摄影棚背景由模型生成设计师随后调整色彩并导出。合理的来源链不是在最终 JPEG 上补一句“AI 生成”而是让每个关键环节形成可验证关系。摄影棚设备先给原图签发 Manifest记录采集工具和创建动作。生成服务把原图作为 ingredient并记录生成式处理的 digital source type、使用的软件身份和必要的动作信息。设计工具导入生成结果时验证前序凭证再在导出时建立新的 Manifest把前一版本作为 ingredient记录颜色调整和裁切。发布系统可以保持最后一份凭证不变也可以基于企业发布证书增加更新 Manifest 或发布声明。每个环节只陈述自己能够负责的事实。生成服务可以证明“这个服务在此时处理了该输入并产生与摘要匹配的输出”但不应声称“图中商品百分之百与实物一致”设计工具可以声明做过裁切却不能替摄影师担保拍摄地点。最小、准确、可追责的声明比一份包罗万象但无法核实的声明更有价值。签发服务还必须保护私钥。开发环境可以使用 SDK 提供的测试证书生产环境不应把 PEM 私钥放在代码仓库、容器镜像或共享磁盘。更稳妥的架构是让密钥留在 KMS 或 HSM业务服务提交待签摘要由受控签名接口完成加密运算。私钥访问要有工作负载身份、最小权限、速率限制和审计日志证书轮换不能覆盖旧记录需要结合可信时间戳维持历史签名的可验证性。5. 用 Python 创建并读取内容凭证CAI 开源 SDK 提供 Rust、Python、Node.js 等实现。下面以 Python 3.10 以上环境演示核心流程。安装库python-mvenv .venv .venv\Scripts\activate pipinstallc2pa-python签名需要符合要求的证书链和私钥。下面代码适合本地实验certs.pem和private_key.pem应使用官方测试夹具或专门的开发证书不能拿自签名证书冒充生产可信证书。生产私钥应改由 KMS 或 HSM 托管。# sign_asset.pyfrom__future__importannotationsimportjsonfrompathlibimportPathfromc2paimport(Builder,C2paSignerInfo,C2paSigningAlg,Context,Reader,Signer,)defsign_image(source:Path,target:Path,cert:Path,key:Path)-dict:signer_infoC2paSignerInfo(algC2paSigningAlg.ES256,sign_certcert.read_bytes(),private_keykey.read_bytes(),ta_urlbhttp://timestamp.digicert.com,)signerSigner.from_info(signer_info)contextContext.from_dict({verify:{verify_after_sign:True},builder:{claim_generator_info:{name:catalog-image-pipeline,version:1.0.0,specVersion:2.4.0,}},},signersigner,)manifest{title:source.name,format:image/jpeg,claim_generator_info:[{name:catalog-image-pipeline,version:1.0.0}],assertions:[{label:c2pa.actions.v2,data:{actions:[{action:c2pa.created,digitalSourceType:(http://c2pa.org/digitalsourcetype/trainedAlgorithmicMedia),}],allActionsIncluded:True,},}],}builderBuilder(json.dumps(manifest),contextcontext)withsource.open(rb)assrc,target.open(wb)asdst:builder.sign(image/jpeg,src,dst)readerReader(str(target),contextcontext)returnjson.loads(reader.json())if__name____main__:resultsign_image(Path(source.jpg),Path(signed.jpg),Path(certs.pem),Path(private_key.pem),)print(json.dumps(result,ensure_asciiFalse,indent2))这段代码的重点不是某个字段名称而是“签后立即验”。verify_after_sign可以尽早发现证书、算法、结构或写入错误重新用 Reader 打开目标文件则覆盖了落盘后的真实读取路径。线上还应把源文件摘要、目标文件摘要、证书序列号、签名任务编号和 SDK 版本写入审计系统以便事故发生时重放。示例直接读取 PEM 私钥只是为了展示接口。不要把它照搬到公网服务。生产签名接口应该只接收规范化后的 Manifest 和资产引用拒绝调用方自由指定证书、时间戳地址或任意外部 URL并限制单次文件大小和媒体解析资源避免解析炸弹与服务端请求伪造。6. 验证结果不能只判断“有没有错误”SDK 返回的是 Manifest Store 和 validation status。不同版本、不同资产会出现不同状态码应用层不应把所有非空状态列表都当成同一种失败。更安全的方法是保留原始验证报告再根据业务策略归类。以下代码展示一个与具体 UI 解耦的最小策略层# provenance_policy.pyfrom__future__importannotationsfromdataclassesimportdataclassfromenumimportEnumfromtypingimportAny,IterableclassVerdict(str,Enum):NO_CREDENTIALno_credentialINVALIDinvalidVALID_UNKNOWN_SIGNERvalid_unknown_signerTRUSTED_PROVENANCEtrusted_provenancedataclass(frozenTrue)classDecision:verdict:Verdict reasons:tuple[str,...]may_auto_publish:boolFATAL_PREFIXES(claimSignature.,assertion.dataHash.mismatch,assertion.hashedURI.mismatch,hardBindings.,)defstatus_codes(items:Iterable[dict[str,Any]])-tuple[str,...]:returntuple(str(item.get(code,unknown))foriteminitemsifnotitem.get(success,False))defclassify(report:dict[str,Any])-Decision:manifestsreport.get(manifests)or{}activereport.get(active_manifest)ifnotmanifestsornotactive:returnDecision(Verdict.NO_CREDENTIAL,(资产没有可读取的 Content Credential,),False,)codesstatus_codes(report.get(validation_status)or())fataltuple(codeforcodeincodesifany(code.startswith(prefix)forprefixinFATAL_PREFIXES))iffatal:returnDecision(Verdict.INVALID,fatal,False)# 字段名由接入层根据实际 SDK 报告规范化不能只看签名成功。trustedbool(report.get(policy,{}).get(trusted_signer))ifnottrusted:returnDecision(Verdict.VALID_UNKNOWN_SIGNER,codesor(签名有效但签发者不在业务信任列表,),False,)returnDecision(Verdict.TRUSTED_PROVENANCE,codesor(来源链和内容绑定通过当前策略验证,),True,)def_self_check()-None:assertclassify({}).verdictisVerdict.NO_CREDENTIAL broken{manifests:{m1:{}},active_manifest:m1,validation_status:[{code:claimSignature.mismatch,success:False}],}assertclassify(broken).verdictisVerdict.INVALIDif__name____main__:_self_check()这里故意把 SDK 报告规范化和业务策略分开。SDK 负责按照规范验证结构、摘要、签名、时间戳和证书策略层负责决定哪些签发者可用于自动发布、哪些只能展示、哪些必须阻断。实际接入时应根据所用 SDK 版本的真实状态码建立显式映射未知错误默认降级为人工复核而不是用字符串中是否包含valid这种脆弱判断。may_auto_publishTrue的含义也只能是“满足当前发布来源策略”不能显示成“内容真实”。如果业务还要求商品图不得夸大、新闻图片不得移花接木就必须运行相应的事实核查、素材授权、人工复核和内容安全流程。来源验证只完成其中一项控制。7. 篡改实验应该怎么做没有负向实验的签名功能不能算完成。最小测试矩阵至少包含五类样本。第一类是正常签发文件。验证器应找到 active manifest资产绑定、Assertions 哈希和签名均通过如果使用测试证书结果应表现为签名有效但来源未知而不是受信。第二类是签发后改动像素并以原文件结构保存验证应报告 hard binding 或相关摘要不匹配。第三类是直接修改 Manifest 中的动作文本Claim 签名或 assertion hash 应失败。第四类是完整删除 Manifest。系统应报告无凭证而不是篡改。因为很多合法旧内容从未使用 C2PA缺失只代表没有这类来源证据。第五类是用另一张测试证书签发。签名本身可以有效但业务信任列表不包含该证书时不能自动通过。再增加证书过期、撤销、时间戳不可用、外部 Manifest 超时和 ingredient 链断裂等样本就能覆盖生产环境主要分支。测试时不要只截图 UI。保存原始文件、验证器版本、信任列表版本、完整 JSON 报告和最终策略判定。C2PA 2.4 中的 crJSON 是供配置评估、互操作测试和验证报告使用的派生视图本身不是可独立验证的原始凭证。归档 crJSON 有助于审计但不能用它替换原资产、Manifest Store 和签名材料。8. 时间戳、撤销与证书轮换证书有有效期私钥也可能泄露。如果只判断“现在证书是否过期”大量历史内容会在证书轮换后突然失去可验证性。RFC 3161 可信时间戳可以证明签名在某个时间已经存在并帮助验证器结合当时的证书状态判断。C2PA 2.x 还规定了相关时间戳和撤销处理流程。生产签名服务应配置受认可的 TSA并监控时间戳请求失败率。是否允许“签名成功但时间戳失败”的结果进入发布链要由风险等级决定。内部草稿可以标记后重试面向公众的高价值媒体通常应阻断。不要在 TSA 故障时悄悄写入本机时间它既不能提供独立证明也可能因时钟漂移造成错误历史。证书轮换要保留三个维度新任务从切换时刻开始使用新证书旧资产继续保留原签名验证端同时加载必要的当前和历史信任材料。发现私钥疑似泄露时应立即停止签名、吊销或采取证书策略规定的处置、定位受影响时间窗并依据可信时间戳区分泄露前后的签名。直接重新签署所有旧资产会抹平原始时间线不应作为默认补救。9. 编辑、截图和平台转码后的凭证会怎样数字媒体在传播中经常被压缩和截图。硬绑定对字节或规范定义的媒体结构敏感所以未经 C2PA 感知的编辑往往使原凭证失效或丢失。正确的编辑器不是“保留旧签名并假装没变化”而是验证输入把输入作为 ingredient在输出上生成新的 Manifest记录自己的动作并签名。这样历史链继续存在当前输出也有独立绑定。截图更复杂。截图产生的是新资产不能继承被截图内容的原签名。截图工具可以创建自己的凭证声明屏幕采集动作并把可获得的来源作为 ingredient 或引用但消费者仍要看清“谁截取了什么”。如果平台只保留截图而丢失原文件原凭证不能凭空证明截图没有经过其他处理。软绑定可以在嵌入数据被清除后帮助找回 Manifest例如基于指纹查询近似资产或者通过不可见水印定位仓库记录。但软绑定可能出现碰撞、误匹配或水印受损找回的 Manifest 还必须继续经过绑定和签名验证。产品不能因为“搜到了相似图”就展示完整绿色可信标识。10. 用户界面必须忠实表达不确定性C2PA 不只是后端加密功能。用户最终如何理解验证结果取决于界面。首页可以展示简洁状态但要允许用户展开查看签发者、签发时间、创建与编辑动作、输入材料以及验证问题。状态文案应描述证据不应替用户下事实结论。例如“来源信息已验证由某发布工具签署文件自签署后未检测到受保护内容变化”比“这是真图”准确“凭证无法验证内容绑定不匹配”比“这是 AI 假图”准确“未找到内容凭证”比“来源不可信”准确。用户还应知道签名者是软件产品、设备还是组织身份。C2PA 的基础信任模型聚焦签署 Claim 的机器身份若要表达个人或组织身份需要结合 CAWG 等相应规范与业务校验不能从软件证书名称自行推断作者实名。在批量审核后台原始状态码、证书路径和 ingredient 关系可以提供给专业人员在公众界面应该用分层披露减少认知负担。无论哪种界面都不要隐藏失败原因也不要把“未知”涂成成功。错误的绿色徽章会比没有徽章更危险因为它制造了错误确定性。11. 生产架构中的安全边界一套可上线的系统通常拆成签发服务、验证服务、策略服务、凭证仓库和审计存储。签发服务接触私钥网络权限最小验证服务处理不可信媒体应放在隔离进程或沙箱限制文件大小、解码时长、内存和外部请求策略服务维护信任列表、允许的签发者与业务规则审计存储保存不可变事件但应避免无期限保存用户原始隐私媒体。外部 Manifest 获取必须防止 SSRF。验证器不能盲目访问资产内声明的任意内网地址应限制协议、目标域、重定向次数、响应大小和超时并通过专用出口代理访问。离线或高安全环境可以关闭远程获取将外部凭证先进入受控仓库。解析图片、视频和压缩容器时还要防止畸形文件与资源耗尽SDK 最新并不等于外围媒体库没有漏洞。信任列表是安全配置不是普通业务数据。更新前要验证签名或发布渠道记录版本和生效时间支持快速回滚。业务自定义信任锚要区分环境测试根证书绝不能混入生产。策略变化后不要静默改写历史判定应该保留“当时按哪个列表得出什么结果”同时允许用新策略重新评估。隐私同样重要。来源历史可能暴露设备、地点、人员或内部工作流。发布者应遵循最小披露原则只写实现用途所需的 Assertions消费者不应因为技术上能够读取就无限收集。需要删除敏感声明时应使用规范允许的编辑和新 Manifest 表达而不是二进制修改旧 Claim 后继续沿用旧签名。12. 与事实核查和 AI 检测怎样协作一个稳妥的内容可信系统应把多类证据并列而不是互相覆盖。C2PA 回答来源链和完整性反向图片搜索寻找更早版本与传播上下文新闻事实核查验证时间、地点、人物和事件取证工具分析剪辑痕迹AI 检测器提供有限概率信号人工审核处理冲突和高风险判断。假设某张图片具有完整、受信的 C2PA 链签发者确实是知名机构文件也没有被篡改但标题把旧照片描述成今天的事件。C2PA 会正确验证“该机构曾签署这张旧照片”却无法证明当前标题为真。反过来一位目击者用不支持 C2PA 的老设备拍下真实事件文件没有凭证也不能因此判假。这两个例子说明来源证据提高可问责性却不会消除认识世界所需的调查。策略引擎应允许这些信号保持独立。不要用一个总分把所有问题混成 87 分可信因为使用者看不出分数来自受信签名、事实核查还是模型判断。更好的输出是结构化证据面板来源链状态、内容绑定状态、签发者信任状态、事实核查状态、检测器结果及其版本。做自动化决策时再按具体场景设定明确门槛。13. 如何验收一条跨工具来源链单文件签名成功只是起点真正的互操作验收要让资产经过至少两个独立工具。可以准备一张测试原图由采集端生成第一份 Manifest再让编辑端导入它、执行一次可见裁切并输出第二份凭证最后由另一套验证器读取结果。验收人员应确认第二份凭证把第一份资产列为 ingredient当前资产绑定通过两个阶段的动作没有被合并成一段无法区分的文字并且每个签名分别连接到预期的信任配置。随后做断链实验。删除前序原图但保留最终文件验证器仍应能够检查最终文件自己的绑定和签名同时明确指出 ingredient 能否解析而不是把整条链简单判成一个模糊错误。再把原图替换为同名文件ingredient 摘要必须不匹配。若系统只凭文件名或 URL 认定前序材料一致就说明来源关系没有建立在密码学绑定上。还要测试跨版本读取。新版本生成器不得写入规范中已经弃用的结构但验证器为了兼容历史资产可能仍需读取旧结构。接入层应该记录生成器、验证器和规范声明版本遇到未知 assertion 时保留原始数据并给出受控提示不能因为一个非关键扩展无法展示就忽略已经发现的签名错误也不能因为核心签名通过就假定所有扩展语义可信。验收报告应把“规范验证”和“产品策略”分成两栏。前一栏列出 Manifest、Assertions、内容绑定、签名、时间戳和证书路径的结果后一栏列出签发者是否在企业允许列表、动作是否符合发布政策、是否需要事实核查。这样即使策略以后变化也能基于原始验证证据重新判断而不是重新猜测当时为什么显示绿色标识。对于将同一素材分发到多个渠道的团队还应分别保存各渠道下载样本因为不同转码链可能产生完全不同的凭证保留结果不能用源站验证成功代替终端验收。14. 上线前检查清单上线前可以沿着生产链逐项检查生成和编辑工具是否准确记录动作与 ingredient签名私钥是否位于 KMS 或 HSM证书是否符合 C2PA 要求并连接到目标信任体系是否配置可信时间戳签后是否立即验证平台转码是否保留凭证或生成新的来源链验证器是否区分无凭证、无效、未知签发者和受信来源外部 Manifest 获取是否有网络隔离原始报告和策略版本是否可审计界面是否避免使用“真图”“假图”这类越界结论。还要做真实传播链测试。把签发样本依次上传到实际 CDN、内容管理系统、移动端和社交平台再下载验证。实验室里通过不代表经过缩略图、格式转换和元数据清理后仍可用。发现某个环节剥离凭证时应决定由该环节生成新 Manifest、保留原文件下载入口还是部署软绑定恢复而不是在前端假装凭证还在。最后建立运行指标签发成功率、签后验证失败率、时间戳失败率、凭证保留率、未知签发者比例、外部 Manifest 获取时延、策略阻断量和人工复核结果。指标异常时要能追溯到 SDK 版本、证书、信任列表和分发节点。只有可监控、可重放、可解释内容凭证才从展示功能变成可靠基础设施。15. 总结C2PA 的核心不是给 AI 图片贴标签而是建立一条由结构化声明、内容绑定、数字签名、证书信任和时间戳组成的可验证来源链。Content Credential 记录内容从哪里来、经历了哪些被声明的动作验证器检查这些声明是否仍与资产匹配、签名是否有效、签发者是否属于当前信任体系业务系统再结合场景决定展示、阻断或人工复核。它真正解决的是“谁对什么声明负责以及声明和资产有没有被改”不是“画面讲述的事情一定真实”。把这条边界写进架构、代码、测试、策略和 UI才能避免用密码学制造新的误导。对事实真伪的判断仍需要上下文、交叉证据和人工调查。验证来源链不等于判断内容真假但没有可靠来源链很多事实核查会失去关键起点。参考资料C2PA Content Credentials Technical Specification 2.4C2PA 2.4 Security ConsiderationsC2PA and Content Credentials Explainer 2.4C2PA Guiding PrinciplesC2PA Conformance Program and Trust ListsCAI Open Source SDK DocumentationCAI SDK: Signing with Local CredentialsOfficial c2pa-python Repository
返回列表