You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Android API≥24下DOM文档类型适配的安全提供商咨询

问题

我尝试使用javax.xml.crypto.dsig.XMLSignatureFactory构建XML文档,实例化时需向getInstance()方法传入安全提供商,即XMLSignatureFactory.getInstance("DOM", provider)。

常规做法是采用Apache Santuario库的XMLDSigRI():

private val xmlSigFactory = XMLSignatureFactory.getInstance("DOM", org.apache.jcp.xml.dsig.internal.dom.XMLDSigRI())

但该库依赖的java.util.Base64类在Android API<26环境下无法运行。我尝试使用BouncyCastle安全提供商(标识为BC),运行时抛出错误:

Caused by: javax.xml.crypto.NoSuchMechanismException: no such mechanism type: DOM for provider BC

换成SpongyCastle(标识为SC)也出现相同问题。我已通过以下代码遍历所有安全提供商,确认BC和SC均已加载:

for(p in Security.getProviders()) {
    Log.d("PROVIDER NAME", p.name)
    Log.d("PROVIDER INFO", p.info)
}

尝试修改库替换java.util.Base64的难度较大,现咨询:

  1. Android API≥24下是否有适配DOM文档类型的安全提供商?
  2. 若无,可行的替代方案是什么?
解决方案

适配API≥24的系统自带提供商

Android API 24及以上系统自带的AndroidOpenSSL提供商(名称为AndroidOpenSSL)原生支持DOM类型的XML签名机制,可直接使用:

private val xmlSigFactory = XMLSignatureFactory.getInstance("DOM", Security.getProvider("AndroidOpenSSL"))

验证方式:遍历提供商时,AndroidOpenSSL的信息会包含XMLDSIG相关支持声明,无需额外引入第三方库。

替代方案(系统提供商不可用时)

1. 局部替换Apache Santuario的Base64依赖

无需整体修改库,仅针对XMLDSigRI中用到java.util.Base64的代码片段进行替换:

  • 定位Santuario库中调用Base64.getEncoder()/getDecoder()的代码
  • 替换为Android兼容的android.util.Base64类(API 8及以上支持),对应映射:
    • Base64.getEncoder().encodeToString(bytes) → android.util.Base64.encodeToString(bytes, Base64.DEFAULT)
    • Base64.getDecoder().decode(str) → android.util.Base64.decode(str, Base64.DEFAULT)
  • 可通过自定义类继承或字节码工具(如ASM)实现,难度远低于整体改库。

2. 使用SpongyCastle专属XML签名API

SpongyCastle不直接支持JDK标准的DOM类型XMLSignatureFactory,但提供了独立的XML签名实现:

  • 引入SpongyCastle的spongycastle-xml依赖
  • 使用org.spongycastle.xml.XMLSignatureFactory替代JDK的javax.xml.crypto.dsig.XMLSignatureFactory
  • 该实现完全不依赖JDK的java.util.Base64,兼容Android API≥24。

内容的提问来源于stack exchange,提问作者filip1234

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.02 11:42:51