HSM을 사용하여 HLK 서명
소개
이 항목에서는 타사 HSM(네트워크 기반 하드웨어 보안 모듈)을 사용하여 EV(확장 유효성 검사) 인증서를 저장할 때 발생할 수 있는 몇 가지 설정 및 구성 문제에 대해 설명합니다.
배경
HLK 패키징
HLKX 패키지 파일은 오픈 패키징 규칙을 사용합니다. 이 사양은 ISO 작업 그룹의 일부이며, 이는 HLKX 파일이 Signtool과 호환되지 않음을 의미합니다.
HLK 패키지 서명
HLK가 패키지에 서명하면 서명 및 관계가 HLK 데이터와 함께 패키지에 배치됩니다. 패키지의 데이터에 대한 서명의 유효성을 검사하는 데 System.IO.Packaging.PackageDigitalSignature
이(가) 사용하는 데이터입니다.
참고 항목
현재 HLK 패키지 서명은 System.Security.Cryptography.Xml.SignedXml 서명 에 사용되는 .NET 라이브러리에 의해 결정되는 RSA 및 DSA 인증서만 지원합니다.
암호화 서비스 공급자
CSP(암호화 서비스 공급자)에는 암호화 표준 및 알고리즘의 구현이 포함되어 있습니다. 최소한 CSP는 CryptoSPI(시스템 프로그램 인터페이스)에서 함수를 구현하는 DLL(동적 연결 라이브러리)로 구성됩니다. 대부분의 CSP에는 모든 자체 함수의 구현이 포함됩니다. 그러나 일부 CSP는 주로 Windows 서비스 제어 관리자가 관리하는 Windows 기반 서비스 프로그램에서 해당 기능을 구현합니다. 다른 사용자는 스마트 카드 또는 보안 공동 프로세서와 같은 하드웨어에서 함수를 구현합니다. CSP가 자체 함수를 구현하지 않는 경우 DLL은 통과 계층으로 작동하여 운영 체제와 실제 CSP 구현 간의 통신을 용이하게 합니다.
인증서 저장소 및 레지스트리
인증서 저장소의 인증서는 모두 최종 서명을 수행할 CSP DLL에 매핑됩니다. 아래 레지스트리 항목에서 볼 수 있습니다.
[HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Cryptography\Defaults\Provider\Microsoft Enhanced DSS and Diffie-Hellman Cryptographic Provider]
"Image Path"="%SystemRoot%\\system32\\dssenh.dll"
"SigInFile"=dword:00000000
"Type"=dword:0000000d
네트워크 기반 HSM에서 호스트되는 인증서를 사용하여 HLKX 패키지 서명
컨트롤러 구성
HSM 인증서로 서명하도록 HLK 컨트롤러를 설정하려면 시스템에 다음이 있어야 합니다.
- HSM의 CA(인증 기관)
- HSM의 CSP 파일
이러한 구성 요소를 사용하여 HSM 클라이언트를 구성하는 방법에 대한 지침은 HSM 공급자가 문서화해야 합니다.
HLK로 서명
컨트롤러가 올바르게 구성된 경우 HLK에서 로컬로 설치된 인증서와 마찬가지로 HSM에서 인증서를 가리키고 패키지에 서명할 수 있습니다.
HSM 구성 테스트
Signtool 사용
서명할 수 있는지를 이해하는 첫 번째 단계는 signtool을 사용하여 파일에 서명하는 것입니다. 이렇게 하면 서명 워크플로가 제대로 작동하는지 확인할 수 있습니다. 먼저 PE 파일(exe 또는 dll)에 서명합니다. 예를 들어 이름을 사용하여 서명합니다.
signtool sign /f HighValue.cer /csp "Hardware Cryptography Module" /kHighValueContainerMyControl.exe
signtool sign /n "My Company Certificate" MyFile.exe
또는 설치된 인증서의 SHA1 해시를 사용하여 서명하려면 다음을 수행합니다.
signtool sign /sha1 0cf1d2f7befc7d143678f86963aef5572b710cf2 MyFile.exe
인증서 이름은 주체 정보에 있으며 SHA1 해시는 지문에 있습니다. 해시를 사용하는 경우 해시에 있는 공백과 특수 문자를 모두 제거하여 형식이 위의 예제와 같이 표시됩니다. PFX(개인 정보 교환) 파일을 사용하여 서명할 수도 있습니다. PFX 파일에는 인증서에 공개 키만 포함된 프라이빗 키가 포함될 수 있으므로 이 작업은 수행하려는 작업이 아닐 가능성이 큽니다.
signtool sign /f certdata.pfx MyFile.exe
signtool을 사용하여 서명을 확인할 수 있습니다.
signtool verify /v /pa MyFile.exe
PFX 파일을 제외한 모든 파일을 사용하여 파일에 서명하고 확인할 수 있는 경우 HLK 패키지에 서명해 볼 수 있습니다. 서명할 수 없는 경우 문제 해결 섹션을 참조하세요.
PackageDigitalSignature 사용
코드 샘플 섹션에서 이 문서의 끝 부분에는 PackageDigitalSignature
을(를) 사용하여 서명하는 코드 예제가 있습니다. 이 문서를 받았을 때 전체 C# 파일도 받았을 것입니다. 이 예제를 사용하려면 서명되지 않은 패키지의 전체 경로와 서명에 사용할 인증서의 지문을 제공해야 합니다. 서명할 수 없는 경우 문제 해결 섹션을 참조하세요.
문제 해결
가장 가능성이 높은 원인은 HSM에서 시스템에 인증서 및 연결된 CSP가 설치되어 있지 않기 때문일 수 있습니다. 시도할 수 있는 몇 가지 작업은 다음과 같습니다.
- HSM 공급업체에서 지원하는 도구만 사용하여 이 시스템에 로그온할 수 있나요?
- HSM 공급업체가 이 시스템에 인증서 및 CSP를 설치하나요?
- 인증서 속성이란?
- HSM 공급업체는 signtool을 사용하여 지원 및 문서를 지원하나요? HSM과 함께 Signtool을 사용하여 파일에 서명할 수 있는 경우 시스템이 올바르게 구성되었으며 HLK가 HLKX 패키지에 서명할 수도 있음을 나타내는 표시기입니다.
- CspKeyContainerInfo.ProviderName에 대해 인쇄되는 예제 코드(HSM_example.cs)를 실행하는 경우
- 해당 공급자 이름이 벤더가 제공한 올바른 CSP DLL에 매핑됩니까? 이 정보는 위와 같이 레지스트리에서 찾을 수 있습니다.
코드 샘플
PackageDigitalSignatureManager
public static void Sign(string package, X509Certificate2 certificate)
{
// Open the package to sign it
Package packageToSign = Package.Open(package);
// Specify that the digital signature should exist
// embedded in the signature part
PackageDigitalSignatureManager signatureManager = new PackageDigitalSignatureManager(packageToSign);
signatureManager.CertificateOption = CertificateEmbeddingOption.InCertificatePart;
// We want to sign every part in the package
List<Uri> partsToSign = new List<Uri>();
foreach (PackagePart part in packageToSign.GetParts())
{
partsToSign.Add(part.Uri);
}
// We will sign every relationship by type
// This will mean the signature is invalidated if *anything* is modified in //the package post-signing
List<PackageRelationshipSelector> relationshipSelectors = new List<PackageRelationshipSelector>();
foreach (PackageRelationship relationship in packageToSign.GetRelationships())
{
relationshipSelectors.Add(new PackageRelationshipSelector(relationship.SourceUri, PackageRelationshipSelectorType.Type, relationship.RelationshipType));
}
try
{
signatureManager.Sign(partsToSign, certificate, relationshipSelectors);
}
finally
{
packageToSign.Close();
}
}