Skip to content
Bitzsoft.Integrationsbitzsoft.integrations

Concept

密钥管理

连接器库中 AppSecret、API Key 和 OAuth Token 的安全存储、注入和防泄露约定。

Last updated

第三方服务集成需要管理大量密钥:AppId/AppSecret、API Key、OAuth Token、RSA 私钥。密钥泄露是最严重的安全风险。

密钥在哪里

appsettings.json
❌ 不应含明文密钥

user-secrets / Vault / KMS
✓ 生产密钥来源

厂商 Options
运行时持有密钥

Provider 实现
使用密钥调用 API

RequestLogHandler
自动脱敏敏感头

第三方 API

安全约定

密钥不进入日志

RequestLogHandler / SensitiveDataRedactor 自动脱敏敏感头和字段。脱敏策略覆盖:

位置脱敏方式
HTTP Header按名称匹配(AuthorizationX-API-Key 等)→ ***
Query String按参数名匹配(access_tokensecret 等)→ ***
Form Body按字段名匹配 → ***
JSON Body按路径匹配(递归遍历)→ ***
XML Body按元素名匹配 → ***

密钥不进入异常详情

// ✓ 正确——ProviderMessage 不含密钥
throw new PaymentException(
domain: "Payment",
provider: "Alipay",
message: "签名验证失败",
errorCode: "SIGN_FAILED");
// ❌ 错误——异常消息包含完整密钥
throw new Exception($"签名失败,私钥: {options.AppPrivateKey}");

密钥不进入健康检查

Health Check 只报告连接状态,不回显凭据:

// ✓ 只检查配置是否存在,不验证密钥有效性
public Task<HealthCheckResult> CheckHealthAsync(...)
{
if (string.IsNullOrEmpty(_options.AppId))
return Task.FromResult(HealthCheckResult.Unhealthy("AppId 未配置"));
return Task.FromResult(HealthCheckResult.Healthy());
}

字节数组密钥用后清除

签名器在 Dispose 时清除持有密钥的字节数组:

internal sealed class AlipaySigner : IDisposable
{
private byte[]? _privateKeyBytes;
public void Dispose()
{
if (_privateKeyBytes is not null)
{
Array.Clear(_privateKeyBytes); // ① 清除内存中的密钥
_privateKeyBytes = null;
}
}
}

密钥来源选择

环境推荐方式示例
本地开发dotnet user-secretsdotnet user-secrets set "Alipay:AppSecret" "..."
测试/预发布环境变量或 CI SecretALIPAY_APP_SECRET=...
生产Vault / KMS / 云密钥服务通过 IIntegrationCredentialResolver 注入

相关

100%

滚轮或按钮缩放 · 放大后拖动画面 · 双击切换 100% / 200%