2011-09-26 3 views
3

서명의 인증서가 특정 루트 인증서로 다시 연결되는지 확인하려고합니다.이 인증서는 이 아니며 Windows가 신뢰하는이 아닙니다.이 인증서는 해당 응용 프로그램의 개인 인증서입니다.인증서 체인을 비공개 루트로 가져 오기

현재이 작업을 수행하기 위해 루트로 사용하려는 특정 인증서 만 신뢰하는 체인 엔진을 만들어서 다른 체인을 생성 할 수 없습니다.

HCERTSTORE hPrivateRootStore = CertOpenStore(CERT_STORE_PROV_FILENAME, dwEncoding, 
    NULL, CERT_STORE_OPEN_EXISTING_FLAG | CERT_STORE_READONLY_FLAG, 
    _T("C:\\Test\\PrivateRoot.cer")); 
CERT_CHAIN_ENGINE_CONFIG config; 
memset(&config, 0, sizeof(config)); 
config.cbSize = sizeof(config); 
config.hRestrictedTrust = hPrivateRootStore; 
config.dwFlags = CERT_CHAIN_CACHE_ONLY_URL_RETRIEVAL | CERT_CHAIN_ENABLE_SHARE_STORE; 
HCERTCHAINENGINE hEngine; 
CertCreateCertificateChainEngine(&config, &hEngine); 
CERT_CHAIN_PARA params; 
memset(&params, 0, sizeof(params)); 
params.cbSize = sizeof(params); 
PCCERT_CHAIN_CONTEXT chains = NULL; 
if (CertGetCertificateChain(hEngine, pCertContext, NULL, hStore, &params, 
    0, NULL, &chains)) 
    ... 

(오류 명확성을 위해 생략 검사, pCertContexthStore 서명 된 바이너리 파일에서 서명과 관련 인증서를 추출 CryptQueryObject에서왔다.)

불행하게도,이 작동하지 않는 것; 사용자 지정 체인 엔진을 사용함에도 불구하고 OS 저장소를 검색하는 것으로 보이며 체인을 찾지 못하거나 OS에서 신뢰하는 다른 루트를 찾습니다. OS 루트 저장소에 개인 루트 인증서를 추가하여 원하는 체인 만 얻을 수 있습니다.

심지어는 을 빈 메모리 저장소로 설정하려고했는데, hRestrictedTrust이 아닌 값을 갖는 것이 시스템 저장소를 다시 가져 오지만 아무런 차이가 없다고 제안하기 때문입니다.

누락되었거나 더 좋은 방법이 있습니까?

편집 : 하나 개의 표준 CA 루트 OS에서 신뢰 : 조금 더 상황을주고, 내가 다시 두 개의 서로 다른 뿌리 서명 인증서 체인이 드라이버 서명 인증서에 비슷한 할 노력하고있어 하나의 내부 루트 (OS에서는 드라이버로도 신뢰할 수 있지만 내 경우에는 내 앱에서만 신뢰할 수 있습니다). 십자가는 "메인"사슬의 중반 어딘가에서 발생합니다. 서로 다른 "실제"CA로 서명 된 여러 파일이있을 수 있지만 여전히 내 내부 인증서로 다시 연결됩니다.

+0

좀 더 조사한 후, Win7에서'hExclusiveRoot' 회원이'CERT_CHAIN_ENGINE_CONFIG'에 추가 된 것을 발견했습니다. 나는 관련된 설명이'CertCreateCertificateChainEngine'이 이전 버전의 시스템 저장소를 무시할 수있는 메커니즘을 제공하지 않는다는 것을 분명히합니다. (실제적으로 도대체 무슨 일인지 궁금하게 생각합니다. 그러나 그것은 별개의 문제입니다.) 그래서, 새로운 질문 : 가능한 루트를 다시 열거 할 다른 방법이 있습니까? 'CertVerifyCertificateChainPolicy'와 호환되는 무언가는 좋을 것입니다. – Miral

+0

분석하려는 인증서 파일의 형식은 무엇입니까? –

+0

피사체가 Authenticode로 서명 된 바이너리이며, 원하는 루트는 앱에 컴파일 된 .cer이며 'PCCERT_CONTEXT'로로드됩니다. – Miral

답변

2

나는 이제 반쯤 구운 해결 방법을 발견했습니다. 그것은 약간 못 생겼지 만 다소 효과가 있습니다. 나는 기본적인 생각을 Chromium's test suite에서 얻었다; Crypt32에 연결하여 시스템 저장소를 열어 체인을 만들 때 내 사용자 지정 저장소를 가져오고 원하는 인증서 만 포함하도록합니다.

좋은이가 대신 보통 때를 무엇 인 (CA 인증서에서 중지의, 내 사용자 지정 인증서 "과거"실제 CA 인증서 체인의 모든 길을 갈 CertGetCertificateChain을 강제하는 것이다 신뢰할 수 있음).

나쁜 점은 체인을 구축하고 다른 CA 인증서를 신뢰하지 않는다는 것입니다. 체인의 루트가 원하는 인증서임을 명시 적으로 확인함으로써이 문제를 해결할 수 있지만 이상적인 것은 아니며 문제가 발생할 수 있는지 확실하지 않습니다.

더 나은 해결책을 찾으십시오. 나는 분명히 내가 어딘가 잘못된 길을 가고 있다는 인상을 받고있다.

좋아, 새로운 계획. 이제 체인을 수동으로 걷는 중입니다. (내가 알고있는 모든 인증서는 부호가있는 hStore에있을 것입니다.exe), 기본 구조는 다음과 같습니다.

  • 기본 "is not tamered"인증을 사용하십시오.
  • 사용 CryptQueryObjecthStore에서 서명 인증서를 찾을 수있는 .EXE
  • 사용 CryptMsgGetParamCertFindCertificateInStore에서 인증서 저장소 hStore을 얻었다.
  • 서명 인증서에서 시작하여 잠재적 인 발급자 인증서를 찾으려면 과 CERT_FIND_SUBJECT_NAME을 루프로 사용하십시오. 자기 서명 인증서를 누르거나 원하는 루트를 찾을 때까지 뒤로 걷기를 계속하십시오 (CertComparePublicKeyInfo을 통해 일치를 확인하십시오).
  • 특정 분기를 포기하면 CertVerifySubjectCertificateContext에 서명이 일치하지 않는다고 표시됩니다.

내가 시도했던 이전의 접근법보다 깨끗해 보입니다. 생각/의견/대안?

(어떤 점에서 어떤 식 으로든 더 많은 의미를 부여하는 것으로 보이는 것은 이와 같은 인증서를 체인화하는 대신 사용자 정의 역 서명 [타임 스탬프와 유사]을 추가하는 것이지만 그 작업에 대한 정보는 찾을 수 없습니다 또는 찬성/반대 의견이 무엇인지 알고 싶습니다.)

관련 문제