sgcSign 2026.5 — Authenticode, EU eIDAS 팩 및 9개 고용 프로파일

· 릴리스

최초 출시 후 단 한 달 만에 sgcSign 2026.5는 라이브러리의 대규모 확장을 제공합니다. 이번 릴리스는 Windows 바이너리용 Microsoft Authenticode 서명, 세 가지 새로운 코드 배포 서명자(ClickOnce, NuGet, VSIX), 완전한 EU eIDAS 준수 팩(ASiC 컨테이너, LOTL / EUTL 신뢰 목록, Cloud Signature Consortium 원격 서명), 9개의 사전 조정된 국가별 고용 프로파일, 불가리아 Peppol BIS Billing 3.0 프로파일, 네이티브 QR 코드 생성기, ECDSA P-256/384/521RSA-PSS 지원, 전체 CI/CD 통합, 그리고 광범위한 XAdES / PFX 적합성 수정 사항을 추가합니다.

이 게시물은 주요 사항을 살펴보며, 모든 새 컴포넌트에 대해 바로 붙여넣을 수 있는 Delphi 스니펫을 제공합니다.

Microsoft Authenticode

TsgcAuthenticodeSigner는 Authenticode 사양에 따라 Windows 휴대용 실행 파일(.exe, .dll, .sys)에 서명합니다. 서명자는 PE를 파싱하고 Authenticode 알고리즘으로 해시를 계산하며(체크섬과 기존 인증서 테이블은 건너뜀), SPC 간접 데이터 콘텐츠가 포함된 전체 PKCS#7 SignedData blob을 만든 다음 이를 바이너리의 인증서 테이블에 추가합니다.

SHA-1부터 SHA-512까지의 해시가 지원되고, RFC 3161 타임스탬프는 서명되지 않은 속성으로 포함되며, AppendSignature := True는 중첩 서명(예: 레거시 Windows 호환성을 위한 SHA-1 + SHA-256 이중 서명)을 생성합니다.

uses
  sgcSign_Authenticode, sgcSign_KeyProvider_PFX, sgcSign_TSAClient;

var
  oSigner: TsgcAuthenticodeSigner;
  oPFX: TsgcPFXKeyProvider;
  oTSA: TsgcTSAClient;
begin
  oPFX := TsgcPFXKeyProvider.Create(nil);
  oPFX.FileName := 'codesign.pfx';
  oPFX.Password := 'secret';

  oTSA := TsgcTSAClient.Create(nil);
  oTSA.URL := 'http://timestamp.digicert.com';

  oSigner := TsgcAuthenticodeSigner.Create(nil);
  try
    oSigner.KeyProvider := oPFX;
    oSigner.TSAClient   := oTSA;
    oSigner.Hash        := ahSHA256;     // ahSHA1 / ahSHA256 / ahSHA384 / ahSHA512
    oSigner.Level       := alT;          // alBES or alT (with timestamp)
    oSigner.Description := 'My Application';
    oSigner.URL         := 'https://www.example.com';
    oSigner.SignFile('MyApp.exe', 'MyApp-signed.exe');
  finally
    oSigner.Free; oTSA.Free; oPFX.Free;
  end;
end;

검증은 대칭적입니다. TsgcAuthenticodeVerifier.Verify는 결과, 계산된 해시와 포함된 해시, 서명자 주체/발급자, 그리고 타임스탬프 존재 여부를 포함하는 레코드를 반환합니다.

var
  oVer: TsgcAuthenticodeVerifier;
  oRes: TsgcAuthenticodeVerifyResult;
begin
  oVer := TsgcAuthenticodeVerifier.Create(nil);
  try
    oRes := oVer.Verify('MyApp-signed.exe');
    if oRes.Valid then
      ShowMessage('Signed by ' + oRes.SubjectName)
    else
      ShowMessage('Invalid: ' + oRes.ErrorMessage);
  finally
    oVer.Free;
  end;
end;

해시 전용 Authenticode 서명

대용량 CI 아티팩트(설치 프로그램, 런타임, 드라이버)는 전체 PE를 원격 서명자에 업로드하는 것이 부담스럽습니다. 새로운 해시 전용 서명 흐름을 사용하면 클라이언트가 로컬에서 Authenticode 해시를 계산하고 32바이트 다이제스트만 sgcSign Server로 전송할 수 있습니다. 서버는 분리된 PKCS#7 blob을 반환하고 클라이언트는 이를 다시 바이너리에 포함시킵니다. 이를 통해 대역폭이 제한된 에이전트에서 메가바이트 단위의 업로드를 몇 KB로 줄일 수 있습니다.

// Local: compute the hash with sgcSign_PE_Hasher, POST it to the server,
// receive the SignedData blob, then append it to the PE's certificate table.
var
  oSigner: TsgcAuthenticodeSigner;
  vHash, vPKCS7: TBytes;
begin
  // vHash := ComputePEHash('MyApp.exe', haSHA256);
  vPKCS7 := oSigner.SignHash(vHash, ahSHA256);
  // EmbedPKCS7IntoPE('MyApp.exe', vPKCS7, 'MyApp-signed.exe');
end;

동일한 작업이 서버의 POST /api/v1/sign/authenticode/hash 엔드포인트, sgcsign sign --prehash CLI 플래그, 그리고 .NET SDK의 TsgcSignClient.SignAuthenticodeHashAsync 메서드를 통해 노출됩니다.

ClickOnce, NuGet 및 VSIX 서명자

세 가지 새로운 서명자가 Microsoft 개발자 배포 생태계를 다룹니다.

TsgcClickOnceSigner는 enveloped W3C XML-DSig를 사용하여 .application 배포 매니페스트와 .exe.manifest 애플리케이션 매니페스트에 서명하며, Microsoft mage.exe의 출력과 일치합니다. 서명자는 인증서의 issuerKeyHashpublisherIdentity 노드를 다시 작성합니다.

uses sgcSign_ClickOnce;

var oCO: TsgcClickOnceSigner;
begin
  oCO := TsgcClickOnceSigner.Create(nil);
  try
    oCO.KeyProvider   := oPFX;
    oCO.Hash          := haSHA256;
    oCO.PublisherName := 'My Company';
    oCO.SignManifestFile('MyApp.application', 'MyApp-signed.application');
  finally
    oCO.Free;
  end;
end;

TsgcNuGetSigner.nupkg 작성자 패키지에 서명하여 CMS/PKCS#7 SignedData blob(서명 인증서 v2, 커밋 유형 "proof of origin")을 생성하며 선택적인 RFC 3161 카운터서명을 포함합니다.

uses sgcSign_NuGet;

var oNu: TsgcNuGetSigner;
begin
  oNu := TsgcNuGetSigner.Create(nil);
  try
    oNu.KeyProvider := oPFX;
    oNu.TSAClient   := oTSA;
    oNu.Hash        := haSHA256;
    oNu.SignPackageFile('MyLib.1.0.0.nupkg', 'MyLib.1.0.0.signed.nupkg');
  finally
    oNu.Free;
  end;
end;

TsgcVSIXSigner는 Visual Studio 확장에 대한 OPC(Open Packaging Convention) 디지털 서명을 구현하며, 파트별 XML-DSig 참조를 계산하고 [Content_Types].xml과 패키지 _rels/.rels를 다시 작성합니다.

uses sgcSign_VSIX;

var oVX: TsgcVSIXSigner;
begin
  oVX := TsgcVSIXSigner.Create(nil);
  try
    oVX.KeyProvider := oPFX;
    oVX.Hash        := haSHA256;
    oVX.SignPackageFile('MyExt.vsix', 'MyExt-signed.vsix');
  finally
    oVX.Free;
  end;
end;

세 가지 모두 기존 XAdES / PAdES / CAdES 서명자와 동일한 IsgcKeyProvider 인터페이스를 재사용하므로, 송장 서명용으로 구성된 AWS KMS, Azure Trusted Signing 또는 PKCS#11 토큰을 추가 작업 없이 바이너리 서명에 재사용할 수 있습니다.

EU eIDAS / 준수 팩

이번 릴리스는 eIDAS 팩을 도입합니다. 이 세 가지 새 유닛이 함께 Delphi 애플리케이션이 공식 EU 신뢰 프레임워크에 대해 서명을 검증하고 장기 보관용 컨테이너를 생성할 수 있게 합니다.

ASiC 컨테이너 (ETSI EN 319 162-1)

sgcSign_ASiC는 XAdES와 CAdES 형식 모두에서 ASiC-S(단일 문서) 및 ASiC-E(다중 문서) 컨테이너를 빌드하고 파싱합니다. 출력은 mimetype 항목이 먼저 오고 서명이 META-INF/ 아래에 배치된 결정적 ZIP입니다.

uses sgcSign_ASiC;

var
  oDocs: TsgcASiCDocumentArray;
  vBytes: TBytes;
begin
  SetLength(oDocs, 1);
  oDocs[0].Name := 'invoice.xml';
  oDocs[0].Data := TFile.ReadAllBytes('invoice.xml');

  // aSignatureXML comes from TsgcXAdESSigner (detached signature over the doc)
  vBytes := TsgcASiCContainer.BuildXAdES(apASiCE, oDocs, vXAdESSignature);
  TFile.WriteAllBytes('invoice.asice', vBytes);
end;

LOTL / EUTL 신뢰 목록

sgcSign_TrustList는 EU의 List of Trusted Lists를 다운로드하고, 회원국별 신뢰 목록 포인터를 따라가며, 각 TSPService 항목을 파싱합니다. 결과는 31개 회원국에 걸친 약 3,600개 서비스의 인메모리 카탈로그입니다. IsQualifiedAtTime 조회는 주어진 서명 시점에 모든 인증서를 "공인 TSP가 발급한"으로 분류합니다. 이는 eIDAS 25조에 따라 서명을 고급(AdES)에서 적격(QES)으로 업그레이드하는 데 필요한 작업입니다.

Cloud Signature Consortium (CSC v2)

TsgcCSCKeyProvider는 Cloud Signature Consortium API v2용 IsgcKeyProvider 구현입니다. 이는 Buypass, Certinomis, Globalsign EU, InfoCert, Namirial, Trust Pro 및 기타 QTSP가 사용하는 원격 적격 서명을 위한 유럽 표준입니다. 제공자는 Basic / OAuth2 / OTP 인증을 처리하고, 사용자의 자격 증명을 나열하며, 인증서 체인을 가져오고, SAD 인증을 사용하여 해시 전용 원격 서명을 수행합니다.

uses sgcSign_KeyProvider_CSC, sgcSign_XAdES;

var oCSC: TsgcCSCKeyProvider; oX: TsgcXAdESSigner;
begin
  oCSC := TsgcCSCKeyProvider.Create(nil);
  oCSC.BaseURL    := 'https://csc.example-qtsp.eu/csc/v2';
  oCSC.AuthMethod := cscOAuth2;
  oCSC.OAuthClientID     := 'my-client-id';
  oCSC.OAuthClientSecret := 'my-client-secret';
  oCSC.CredentialID      := oCSC.ListCredentials[0];
  oCSC.PIN := '1234';
  oCSC.OTP := '987654';      // pushed via SMS / app
  oCSC.LoadCredentialInfo;

  oX := TsgcXAdESSigner.Create(nil);
  oX.KeyProvider := oCSC;
  oX.Profile     := spEIDAS;
  oX.SignXML(vXML);
end;

9개의 고용 프로파일

9개의 사전 조정된 프로파일은 유럽 노동법 문서(고용 계약, 급여 명세서, 이전 계약)를 대상으로 합니다:

프로파일국가레벨C14NTSAOCSP
spEmploymentDE독일B-LTExclusive
spEmploymentIT이탈리아B-LTC14N 1.0
spEmploymentES스페인B-TExclusive아니오
spEmploymentFR프랑스B-TExclusive아니오
spEmploymentPL폴란드B-TExclusive아니오
spEmploymentAT오스트리아B-LTExclusive
spEmploymentBE벨기에B-LTExclusive
spEmploymentPT포르투갈B-LTExclusive
spEmploymentNL네덜란드B-TExclusive아니오

새로운 EU_Employment 데모는 전체 파이프라인(서명 → ASiC-E 패키지 → LOTL 검증 → QTSP 분류)을 제공합니다.

불가리아 Peppol BIS Billing 3.0

새로운 TsgcProfilePeppolBG 프로파일은 불가리아 UBL 2.1 송장(BGN 통화, 20% 부가가치세, BG VAT / EIK, BG IBAN, 스키마 ID 9926 엔드포인트)에 exclusive C14N을 사용하여 XAdES B-T로 서명합니다. Delphi 및 C++Builder 데모는 완전히 채워진 송장 템플릿을 제공합니다.

uses sgcSign_XAdES, sgcSign_Types;

var oSigner: TsgcXAdESSigner;
begin
  oSigner := TsgcXAdESSigner.Create(nil);
  try
    oSigner.KeyProvider := oPFX;
    oSigner.TSAClient   := oTSA;
    oSigner.Profile     := spPeppolBG;
    oSigner.SignXMLFile('invoice_bg.xml', 'invoice_bg_signed.xml');
  finally
    oSigner.Free;
  end;
end;

CI/CD 통합

sgcSign Server는 이제 모든 일반적인 파이프라인에 대해 일급 아티팩트를 제공합니다:

QR 코드 생성기

인쇄 가능한 송장에 QR 코드가 필요한 TicketBAI, VeriFactu 및 유사한 프로파일을 위해, 새로운 sgcSign_QRCode 유닛은 ISO/IEC 18004를 바이트 모드로 구현하는 순수 Pascal 생성기를 제공합니다. 네 가지 ECC 레벨 모두, 버전 1부터 40까지, GF(256) Reed-Solomon, 전체 마스크 패널티 점수 계산을 TBitmap 렌더러와 함께 제공합니다. 외부 DLL이 없으며 라이선스 문제도 없습니다.

uses sgcSign_QRCode, Graphics;

var
  oMatrix: TQRMatrix;
  oBmp: TBitmap;
begin
  oMatrix := GenerateQRCode(
    'https://tbai.eus/QURL/123456789-A?cr=42',
    qrECM);

  oBmp := TBitmap.Create;
  try
    RenderQRMatrix(oMatrix, oBmp, 5, 4);    // 5 px / module, 4-module border
    oBmp.SaveToFile('invoice_qr.bmp');
  finally
    oBmp.Free;
  end;
end;

ECDSA P-256 / P-384 / P-521 및 RSA-PSS

TsgcPEMKeyProvider는 이제 Windows BCrypt CNG(ECCPRIVATEBLOB)를 통해 EC 개인 키를 가져오고 XML-DSig용 원시 r||s 출력으로 서명합니다. 새로운 SignDataPSS 메서드는 BCRYPT_PAD_PSS를 사용하여 RSA-PSS 서명(SHA-256, salt = 32바이트)을 생성합니다. 이는 점점 더 많은 국가별 e-인보이싱 프로파일에서 요구되고 있습니다.

검증 측면에서는 TsgcSignatureVerifierBCRYPT_ECCPUBLIC_BLOB에서 EC 공개 키를 가져와 XAdES SignatureValue와 원시 VerifyData 코드 경로 모두에서 동일한 세 곡선에 대한 ECDSA 서명을 검증합니다.

이를 작동시키기 위해 TsgcX509Certificate는 이제 KeyUsage 확장을 파싱하고 KeyUsage 속성과 HasKeyUsageDigitalSignature / HasKeyUsageNonRepudiation 도우미를 통해 이를 노출합니다. 또한 새로운 PublicKeyParameters 속성은 원시 AlgorithmIdentifier 매개변수 TLV(EC 인증서의 명명된 곡선 OID)를 노출합니다.

Delphi 7용 WideString 오버로드

비 ACP 텍스트(폴란드 KSeF, 그리스 myDATA, 불가리아 Peppol 등)를 전달하는 호출자를 위해, 공개 서명 및 검증 API는 이제 TsgcXAdESSigner.SignXML, SignXMLDetached, SignXMLEnveloping(및 TsgcDocumentSignerTsgcSignatureVerifier의 일치하는 메서드)에 WideString 오버로드를 노출합니다. 이는 Delphi 7에서 ACP 라운드트립 없이 무손실 유니코드 입출력을 보장하며, Delphi 2009+에서 string 오버로드와 동등합니다.

적합성 및 안정성 수정

2026.5의 버그 수정 일괄 처리는 실제 세무 당국 엔드포인트에 대해 발견된 XAdES / PFX / 검증자 문제의 긴 목록을 해결합니다.

업그레이드

2026.5는 기존 2026.4 프로젝트에 대한 드롭인 업그레이드입니다. 주의해야 할 단일 동작 변경 사항은 TsgcDocumentSigner입니다: AdES 프로파일에 대해 일반 XML-DSig를 내보내는 데 의존했던 코드는 이제 올바르게 XAdES를 생성합니다. 이는 세무 당국이 요청한 것이지만, 통합 테스트가 레거시 출력에 고정되어 있었다면 골든 파일을 새로 고쳐야 합니다.

활성 구독을 보유한 고객은 고객 영역에서 새 빌드를 다운로드할 수 있습니다. 평가판 사용자는 esegece.com/products/sgcsign/sgcsign-download에서 업데이트된 설치 프로그램을 받을 수 있습니다.

질문, 피드백 또는 마이그레이션 도움이 필요하신가요? 문의하기 — 코드를 작성한 사람들로부터 직접 답변을 받으실 수 있습니다.