自带密钥——10 个提供者

所有提供者均实现 IsgcKeyProvider 接口——相同的签名代码可用于本地文件、智能卡、HSM、云 KMS 或远程 QTSP。一行代码即可切换。

本地文件(PFX、PEM)
硬件(PKCS#11)
云 KMS(Azure、AWS、GCP)
QTSP(Certum、CSC v2)

TsgcPFXKeyProvider

PFX / PKCS#12 文件。本地密码保护密钥。适合开发环境、小规模部署以及证书以单个 .pfx/.p12 文件分发的工作流。

  • 通过 Windows CNG 使用 PKCS12_PREFER_CNG_KSP 导入——无论原始 CSP 为何,SHA-256/384/512 签名均可正常工作。
  • 自动遍历多证书 .pfx 文件,直至找到含私钥的证书。
pfx.pas
var
  vPFX: TsgcPFXKeyProvider;
begin
  vPFX := TsgcPFXKeyProvider.Create(nil);
  try
    vPFX.FileName := 'certificate.pfx';
    vPFX.Password := 'mypassword';
    vPFX.LoadFromFile;
    // vSigner.KeyProvider := vPFX;
  finally
    vPFX.Free;
  end;
end;

TsgcPEMKeyProvider

PEM 文件。加密 PKCS#8,原生支持 PBES2 / PBKDF2 / AES-CBC,以及传统 RSA 私钥 DEK-Info 格式。适合基于 OpenSSL 的流水线。

  • BEGIN CERTIFICATEBEGIN RSA PRIVATE KEYBEGIN PRIVATE KEYBEGIN ENCRYPTED PRIVATE KEY 均支持。
  • 自动检测合并 PEM(证书 + 密钥在同一文件)——将 PrivateKeyFile 留空即可。
pem.pas
var
  vPEM: TsgcPEMKeyProvider;
begin
  vPEM := TsgcPEMKeyProvider.Create(nil);
  try
    vPEM.CertificateFile := 'cert.pem';
    vPEM.PrivateKeyFile  := 'key.pem';
    vPEM.PrivateKeyPassword := 'secret';
    vPEM.LoadFromFile;
    // vSigner.KeyProvider := vPEM;
  finally
    vPEM.Free;
  end;
end;

TsgcWindowsCertStoreProvider

Windows 证书存储。本地计算机和当前用户存储。适合使用现有 AD 颁发证书的桌面应用,或 Windows 已管理证书生命周期的部署场景。

  • 签名通过 Windows CNG 执行——私钥永远不离开存储区。
  • 可通过主题 CN 子字符串或 SHA-1 指纹选择证书。
winstore.pas
var
  vStore: TsgcWindowsCertStoreProvider;
begin
  vStore := TsgcWindowsCertStoreProvider.Create(nil);
  try
    vStore.StoreName := 'MY';
    vStore.StoreLocation := cslCurrentUser;
    vStore.SelectCertificateBySubject('My Company');
    // vSigner.KeyProvider := vStore;
  finally
    vStore.Free;
  end;
end;

TsgcPKCS11Provider

PKCS#11 / 硬件令牌。智能卡、USB 令牌、HSM——SafeNet、YubiKey、Nitrokey、Thales。大多数 EU 司法管辖区的合格电子签名需要此类设备。

  • 支持 CKM_RSA_PKCSCKM_ECDSA_SHA256 机制。
  • EnumerateSlots / EnumerateCertificates 辅助函数用于在运行时选择正确的插槽。
pkcs11.pas
var
  vTok: TsgcPKCS11Provider;
begin
  vTok := TsgcPKCS11Provider.Create(nil);
  try
    vTok.LibraryPath := 'C:\token\pkcs11.dll';
    vTok.SlotIndex := 0;
    vTok.PIN := '1234';
    vTok.CertificateLabel := 'MyCert';
    vTok.Connect;
    // vSigner.KeyProvider := vTok;
  finally
    vTok.Free;
  end;
end;

TsgcAzureTrustedSigningProvider

Azure Trusted Signing。微软合格代码签名服务。无需购买 EV 证书即可使用 Authenticode——微软持有证书并为您预配签名密钥。

  • OAuth2 客户端凭据——租户 ID + 客户端 ID + 客户端密钥。
  • 私钥完全存储在 Azure 中,从不出现在构建代理上。
azure-ts.pas
var
  vAzure: TsgcAzureTrustedSigningProvider;
begin
  vAzure := TsgcAzureTrustedSigningProvider.Create(nil);
  try
    vAzure.TenantId := 'your-tenant-id';
    vAzure.ClientId := 'your-client-id';
    vAzure.ClientSecret := 'your-client-secret';
    vAzure.AccountName := 'mySigningAccount';
    vAzure.CertificateProfileName := 'default';
    vAzure.Connect;
    // vSigner.KeyProvider := vAzure;
  finally
    vAzure.Free;
  end;
end;

TsgcAWSKMSKeyProvider

AWS Key Management Service。亚马逊基于 HSM 的密钥托管服务。搭配 AWS 颁发的证书,实现云端签名而不暴露私钥。

  • 进程内计算 AWS 签名版本 4 身份验证。
  • KeyId 接受密钥 ID、密钥 ARN 或别名 ARN。
aws-kms.pas
var
  vAWS: TsgcAWSKMSKeyProvider;
begin
  vAWS := TsgcAWSKMSKeyProvider.Create(nil);
  try
    vAWS.AccessKeyId := 'AKIAIOSFODNN7EXAMPLE';
    vAWS.SecretAccessKey := 'wJalrXUtnFEMI/K7MDENG/...';
    vAWS.Region := 'us-east-1';
    vAWS.KeyId := 'arn:aws:kms:us-east-1:...:key/my-key';
    vAWS.Connect;
    // vSigner.KeyProvider := vAWS;
  finally
    vAWS.Free;
  end;
end;

TsgcGCloudKMSKeyProvider

Google Cloud KMS。与 AWS KMS 操作模型相同。服务账号 JSON 文件通过 JWT 交换获取 OAuth2 访问令牌,然后通过 Cloud KMS API 进行签名。

  • ProjectId + Location + KeyRing + Key + Version——与 GCP 资源层次结构一一对应。
  • 仅限非对称 KMS 密钥——在可用时使用 HSM 保护,否则使用软件保护。
gcloud-kms.pas
var
  vGCloud: TsgcGCloudKMSKeyProvider;
begin
  vGCloud := TsgcGCloudKMSKeyProvider.Create(nil);
  try
    vGCloud.ProjectId := 'my-project';
    vGCloud.LocationId := 'global';
    vGCloud.KeyRingId := 'my-key-ring';
    vGCloud.KeyId := 'my-signing-key';
    vGCloud.KeyVersion := '1';
    vGCloud.ServiceAccountJSON := 'C:\keys\sa.json';
    vGCloud.Connect;
    // vSigner.KeyProvider := vGCloud;
  finally
    vGCloud.Free;
  end;
end;

TsgcHashiCorpVaultKeyProvider

HashiCorp Vault。Vault 的 Transit 密钥引擎执行签名操作。最适合 Vault 已是技术栈一部分的自托管、策略驱动的密钥托管场景。

  • Transit 引擎仅管理密钥——通过 SetCertificateFromFile 提供证书。
  • 基于令牌的身份验证;挂载路径默认为 'transit'
vault.pas
var
  vVault: TsgcHashiCorpVaultKeyProvider;
begin
  vVault := TsgcHashiCorpVaultKeyProvider.Create(nil);
  try
    vVault.VaultAddress := 'https://vault.example.com:8200';
    vVault.Token := 's.myVaultToken';
    vVault.MountPath := 'transit';
    vVault.KeyName := 'my-signing-key';
    vVault.Connect;
    vVault.SetCertificateFromFile('C:\certs\signing-cert.pem');
    // vSigner.KeyProvider := vVault;
  finally
    vVault.Free;
  end;
end;

TsgcCertumSimplySignProvider

Certum SimplySign。波兰 QTSP。通过移动应用授权 PIN 实现合格电子签名,无需 USB 令牌。波兰 KSeF 和 ZUS 工作流的常用选择。

  • OAuth2 客户端凭据 + SimplySign 账号用户名/密码 + PIN。
  • ListCertificates 列出账号中所有可用的证书。
certum.pas
var
  vCertum: TsgcCertumSimplySignProvider;
begin
  vCertum := TsgcCertumSimplySignProvider.Create(nil);
  try
    vCertum.ClientId := 'your-client-id';
    vCertum.ClientSecret := 'your-client-secret';
    vCertum.Username := 'user@example.com';
    vCertum.Password := 'account-password';
    vCertum.PIN := '123456';
    vCertum.BaseURL := 'https://cloudsign.certum.pl';
    vCertum.Connect;
    // vSigner.KeyProvider := vCertum;
  finally
    vCertum.Free;
  end;
end;

TsgcCSCKeyProvider

Cloud Signature Consortium API v2。适用于所有实现 CSC v2 的 QTSP 的通用接口——包括 Universign、D-Trust sign-me、A-Trust、FNMT Cl@ve Firma、Evrotrust、Intesi Group。提供者将合格密钥保存在远程 QSCD 中;sgcSign 仅发送文档哈希值。

  • 三种身份验证模式:cscBasiccscOAuth2cscOTP(用于双因素身份验证的一次性密码)。
  • 按照 CSC v2 规范调用 credentials/authorize + signatures/signHash
csc-v2.pas
var
  vCSC: TsgcCSCKeyProvider;
  vCreds: TStringArray;
begin
  vCSC := TsgcCSCKeyProvider.Create(nil);
  try
    vCSC.BaseURL := 'https://api.qtsp.example/csc/v2';
    vCSC.AuthMethod := cscBasic;
    vCSC.Username := 'alice';
    vCSC.Password := 'secret';
    vCreds := vCSC.ListCredentials;
    vCSC.CredentialID := vCreds[0];
    vCSC.PIN := '123456';
    vCSC.OTP := '987654';
    vCSC.LoadCredentialInfo;
    // vSigner.KeyProvider := vCSC;
  finally
    vCSC.Free;
  end;
end;

一行代码切换提供者

每个提供者均实现 IsgcKeyProvider。签名代码无需知道密钥是存储在磁盘、令牌、Azure 还是 CSC v2 API 之后。

一个签名器,十个提供者

  • 用本地 PFX 开发,用 Windows 存储测试,部署到 Azure Trusted Signing。
  • 国家配置文件、签名级别、OCSP、时间戳——其余一切保持不变。
  • sgcSign Server 内部使用相同的提供者——先在本地集中,再扩展为守护进程。
swap-providers.pas
function SignWithAnyProvider(
  aProvider: IsgcKeyProvider; const aXML: string): string;
var
  vSigner: TsgcXAdESSigner;
begin
  vSigner := TsgcXAdESSigner.Create(nil);
  try
    vSigner.KeyProvider := aProvider;
    vSigner.Profile.LoadProfile(spEmploymentDE);
    Result := vSigner.SignXML(aXML);
  finally
    vSigner.Free;
  end;
end;

// Caller picks the provider; signer doesn't care.
SignWithAnyProvider(vPFX, vXML);
SignWithAnyProvider(vAzure, vXML);
SignWithAnyProvider(vCSC, vXML);

根据您的信任模型选择合适的提供者

从本地 .pfx 到另一大洲的 HSM——签名代码始终保持不变。