Visual Studio 2005 ClickOnce 응용 프로그램 설치를 서명에 사용된 인증서가 만료된 후에도 업데이트하려고 하면 오류 메시지가 나타난다

기술 자료 번역 기술 자료 번역
기술 자료: 925521 - 이 문서가 적용되는 제품 보기.
모두 확대 | 모두 축소

이 페이지에서

현상

설치를 서명하는 데 사용된 인증서가 만료된 후에도 Microsoft Visual Studio 2005 ClickOnce 응용 프로그램을 업데이트하려고 하면 다음 오류 메시지가 나타날 수 있습니다.
구독이 배포 ID와 일치하지 않습니다.

원인

이 문제는 발생합니다 모든 ClickOnce 배포를 디지털 인증서로 서명해야 합니다. 만료된 인증서 ClickOnce 응용 프로그램을 서명하는 데 사용할 수 없습니다. 업데이트가 만료된 인증서를 갖는 응용 프로그램을 배포하려면 응용 프로그램이 새 인증서를 할당해야 합니다. 새 인증서를 원래 인증서를 일치하지 않는 경우 "현상" 절에서 설명한 오류 메시지가 나타납니다.

해결 방법

이 문제를 해결하려면 다음 방법 중 하나를 사용하십시오.

방법 1

ClickOnce 응용 프로그램을 Microsoft에 설치된 클라이언트 컴퓨터가 업데이트 .NET Framework 2.0 서비스 팩 1 (SP1) 또는 이후 버전.

Windows Vista

.NET Framework 3.5 또는 .NET Framework 3.5 SP 1 적용됩니다.

참고 .NET Framework 3.5 3.0 .NET Framework 2.0 따라 증분 빌드 여러 가지 새로운 기능이 들어 있습니다. .NET Framework 3.5 .NET Framework 2.0 SP1 및 .NET Framework 3.0 SP1은 포함됩니다.

Microsoft 다운로드 센터에서 다음 파일을 다운로드 할 수 있습니다:

그림 축소그림 확대
Download
Download the .NET Framework 3.5 package now.

그림 축소그림 확대
Download
Download the .NET Framework 3.5 Service Pack 1 package now.

Microsoft 지원 파일을 다운로드하는 방법에 대한 자세한 내용은 Microsoft 기술 자료의 다음 문서를 참조하십시오.
119591온라인 서비스로부터 Microsoft 지원 파일을 구하는 방법
Microsoft는 이 파일에 대한 바이러스를 검색합니다. Microsoft는 파일을 게시한 날짜에 사용할 수 있었던 최신 바이러스 검색 소프트웨어가 사용됩니다. 해당 파일을 무단으로 변경할 수 없는 보안이 향상된 서버에 보관됩니다.

Windows XP

.NET Framework 2.0 SP1 또는 .NET Framework 2.0 서비스 팩 2 (SP2) 적용됩니다.

다음 파일은 Microsoft 다운로드 센터에서 사용할 수 있습니다.

그림 축소그림 확대
Download
Download the .NET Framework 2.0 Service Pack 1 (x86) package now.

그림 축소그림 확대
Download
Download the .NET Framework 2.0 Service Pack 1 (x64) package now.

그림 축소그림 확대
Download
Download the .NET Framework 2.0 Service Pack 2 package now.

Microsoft 지원 파일을 다운로드하는 방법에 대한 자세한 내용은 Microsoft 기술 자료의 다음 문서를 참조하십시오.
119591온라인 서비스로부터 Microsoft 지원 파일을 구하는 방법
Microsoft는 이 파일에 대한 바이러스를 검색합니다. Microsoft는 파일을 게시한 날짜에 사용할 수 있었던 최신 바이러스 검색 소프트웨어가 사용됩니다. 해당 파일을 무단으로 변경할 수 없는 보안이 향상된 서버에 보관됩니다.

방법 2

만료된 인증서를 사용하여 서명된 ClickOnce 응용 프로그램을 제거하십시오. 그런 다음 새 인증서를 사용하는 업데이트된 ClickOnce 응용 프로그램을 다시 설치하십시오.

방법 3

인증서를 업데이트하는 명령줄 어셈블리를 만듭니다. 이렇게 하려면 다음과 같이 하십시오.

Microsoft는 묵시적인 보증 없이 목적으로만 프로그래밍 예제를 제공합니다. 이 포함되지만, 상품성 또는 특정 목적에의 적합성에 대한 묵시적인된 보증이 제한되지 않습니다. 이 문서에서는 만들려면 및 프로시저를 디버깅하는 데 사용되는 도구 및 여기서 설명하는 프로그래밍 언어에 익숙한 사용자를 대상으로 합니다. Microsoft 지원 엔지니어는 특정 절차에 대한 기능을 설명할 수 있습니다. 그러나 이러한 추가 기능을 제공하거나 특정 요구 사항에 맞도록 프로시저를 구성하지는 이 예제를 수정하여지 않습니다.
  1. Visual Studio 2005에서 [파일] 메뉴에서 [새로 만들기 를 클릭한 다음 프로젝트 를 클릭하십시오.
  2. Visual C++Win32 콘솔 응용 프로그램 차례로, 이름 상자에 RenewCert 클릭한 다음 확인 을 누릅니다.
  3. Win32 응용 프로그램 마법사 대화 상자에서 마침 을 클릭하십시오.
  4. In the RenewCert.cpp file, replace the existing code with the following code:
    #include "stdafx.h"
    
    void ReadPFXFile(LPCWSTR fileName, CRYPT_DATA_BLOB *pPFX)
    
    {
    
                HANDLE hCertFile = NULL;
    
                DWORD cbRead = 0;
    
                DWORD dwFileSize = 0, dwFileSizeHi = 0;
    
                hCertFile = CreateFile(fileName, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, NULL);
    
                dwFileSize = GetFileSize(hCertFile, &dwFileSizeHi);
    
                pPFX->pbData = (BYTE *) CryptMemAlloc(dwFileSize*sizeof(BYTE));
    
                pPFX->cbData = dwFileSize;
    
                ReadFile(hCertFile, pPFX->pbData, pPFX->cbData, &cbRead, NULL);
    
                CloseHandle(hCertFile);
    
    }
    
    void GetPrivateKey(CRYPT_DATA_BLOB pPFX, LPCWSTR szPassword, HCRYPTPROV *hCPContext)
    
    {
    
                HCERTSTORE hCertStore = NULL;
    
                PCCERT_CONTEXT hCertContext = NULL;
    
                DWORD dwKeySpec = AT_SIGNATURE;
    
                BOOL bFreeCertKey = TRUE;
    
                hCertStore = PFXImportCertStore(&pPFX, szPassword, CRYPT_EXPORTABLE);
    
                hCertContext = CertEnumCertificatesInStore(hCertStore, NULL);
    
                CryptAcquireCertificatePrivateKey(hCertContext, 0, NULL, hCPContext, &dwKeySpec, &bFreeCertKey);
    
                CertCloseStore(hCertStore, CERT_CLOSE_STORE_FORCE_FLAG);
    
    }
    
    void PrintContainerName(HCRYPTPROV hCPContext)
    
    {
    
                DWORD containerNameLen = 0;
    
                CHAR *szContainerName = NULL;
    
                CryptGetProvParam(hCPContext, PP_CONTAINER, NULL, &containerNameLen, 0);
    
                szContainerName = (CHAR *)CryptMemAlloc(sizeof(BYTE)*containerNameLen);
    
                CryptGetProvParam(hCPContext, PP_CONTAINER, (BYTE *)szContainerName, &containerNameLen, 0);
    
                printf("This certificate's container name is: %s", szContainerName);
    
    }
    
    void MakeNewCert(HCRYPTPROV hCPContext, LPCWSTR szCertName, LPCWSTR szPassword, CRYPT_DATA_BLOB *pPFX)
    
    {
    
                CERT_NAME_BLOB certNameBlob = {0,NULL};
    
                PCCERT_CONTEXT hCertContext = NULL;
    
                SYSTEMTIME certExpireDate;
    
                HCERTSTORE hTempStore = NULL;
    
                CertStrToName(X509_ASN_ENCODING | PKCS_7_ASN_ENCODING, szCertName, CERT_OID_NAME_STR, NULL, NULL, &certNameBlob.cbData, NULL);
    
                certNameBlob.pbData = (BYTE *)CryptMemAlloc(sizeof(BYTE)*certNameBlob.cbData);
    
                CertStrToName(X509_ASN_ENCODING | PKCS_7_ASN_ENCODING, szCertName, CERT_OID_NAME_STR, NULL, certNameBlob.pbData, &certNameBlob.cbData, NULL);
    
                GetSystemTime(&certExpireDate);
    
                certExpireDate.wYear += 5;
    
                hCertContext = CertCreateSelfSignCertificate(hCPContext, &certNameBlob, 0, NULL, NULL, NULL, &certExpireDate, NULL);
    
                hTempStore = CertOpenStore(CERT_STORE_PROV_MEMORY, 0, NULL, CERT_STORE_CREATE_NEW_FLAG, 0);
    
                CertAddCertificateContextToStore(hTempStore, hCertContext, CERT_STORE_ADD_NEW, NULL);
    
                PFXExportCertStoreEx(hTempStore, pPFX, szPassword, NULL, EXPORT_PRIVATE_KEYS);
    
                pPFX->pbData = (BYTE *)CryptMemAlloc(sizeof(BYTE)*pPFX->cbData);
    
                PFXExportCertStoreEx(hTempStore, pPFX, szPassword, NULL, EXPORT_PRIVATE_KEYS);
    
                CryptMemFree(certNameBlob.pbData);
    
                CertCloseStore(hTempStore, CERT_CLOSE_STORE_FORCE_FLAG);
    
                CertFreeCertificateContext(hCertContext);
    
    }
    
    void WritePFX(CRYPT_DATA_BLOB pPFX, LPCWSTR szOutputFile)
    
    {
    
                HANDLE hOutputFile = NULL;
    
                DWORD cbWritten = 0;
    
                hOutputFile = CreateFile(szOutputFile, GENERIC_READ | GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_FLAG_SEQUENTIAL_SCAN, NULL);
    
                WriteFile(hOutputFile, pPFX.pbData, pPFX.cbData, &cbWritten, NULL);
    
                CloseHandle(hOutputFile);
    
    }
    
    int _tmain(int argc, _TCHAR* argv[])
    
    {
    
                LPCWSTR szCertFileName = NULL;
    
                CRYPT_DATA_BLOB pPFX;
    
                LPCWSTR szPassword = NULL;
    
                HCRYPTPROV hCPContext = NULL;
    
                LPCWSTR szCertName = L"CN=NewCert";
    
                CRYPT_DATA_BLOB pPfxOutputBlob = {0,NULL};
    
                LPCWSTR szOutFile = NULL;
    
                // Parse the command line.
    
                if(argc == 1)
    
                {
    
                            printf("renewcert <PFX File> <new cert filename> <new cert friendly name> [optional]<password>\n");
    
                            printf("Example: renewcert oldcert.pfx newcert.pfx \"CN=MyNewCert\" MySuperSecretPassword");
    
                            return 0;
    
                }
    
                if(argc >= 2)
    
                            szCertFileName = argv[1];
    
                if(argc >= 5)
    
                            szPassword = argv[4];
    
                // Uncomment this block to add <new cert filename> and <new cert friendly name> as parameters
    
                // NOTE: <new cert friendly name> must be of format "CN=<name>"
    
                if(argc >= 3)
    
                            szOutFile = argv[2];
    
                if(argc >= 4)
    
                            szCertName = argv[3];
    
                ReadPFXFile(szCertFileName, &pPFX);
    
                GetPrivateKey(pPFX, szPassword, &hCPContext);
    
                //PrintContainerName(hCPContext);
    
                // Uncomment this section to make a new PFX rather than just printing the container name.
    
                // Make sure you also uncomment the command line parameter section above.
    
                MakeNewCert(hCPContext, szCertName, szPassword, &pPfxOutputBlob);
    
                WritePFX(pPfxOutputBlob, szOutFile);
    
                // Clean up.
    
                CryptReleaseContext(hCPContext, 0);
    
                CryptMemFree(pPfxOutputBlob.pbData);
    
                CryptMemFree(pPFX.pbData);
    
                return 0;
    
    }
    
  5. stdafx.h 파일을 기존 코드를 다음 코드로 바꿉니다:
    // stdafx.h : include file for standard system include files,
    
    // or project specific include files that are used frequently, but
    
    // are changed infrequently.
    
    //
    
    #pragma once
    
    #define WIN32_LEAN_AND_MEAN                     // Exclude rarely used material from Windows headers.
    
    #include <stdio.h>
    
    #include <tchar.h>
    
    #include <windows.h>
    
    #include <wincrypt.h>
    
  6. 프로젝트 메뉴에서 이 프로젝트에 대한 속성 페이지를 열려면 속성 클릭하십시오.
  7. 링커 노드를 확장한 다음 입력 을 클릭하십시오.
  8. 추가 종속성, 오른쪽의 빈 창을 클릭한 다음 추가 종속성 대화 상자를 열려면 줄임표 단추 (...)를 클릭하십시오.
  9. 빈 창이 Crypt32.lib 를 입력한 다음 확인 을 누릅니다.
  10. 적용 을 누른 다음 속성 페이지를 닫고 확인 누릅니다.
  11. 빌드 메뉴에서 솔루션 빌드 를 클릭하십시오.
  12. 솔루션을 빌드한 후에 인증서를 업데이트하려면 다음 명령을 실행할:
    renewcert <OldCertificate>.pfx <NewCertificate>.pfx \"CN=<NewCertificateName>\" <Password>
    <OldCertificate> 이전 인증서 자리 표시자입니다 <NewCertificate> 새 인증서 자리 표시자입니다 <NewCertificateName> 이름 새 인증서 및 <Password> 암호 자리 표시자입니다.

추가 정보

이 문제를 재현하는 방법

  1. Visual Studio 2005 시작하십시오.
  2. 파일 메뉴에서 새로 만들기를 클릭한 다음 프로젝트 를 클릭합니다.
  3. Visual C#Windows 응용 프로그램 을 클릭합니다. 그리고 이름 상자에 WindowsApplication1 클릭한 다음 확인 을 누릅니다.
  4. 솔루션 탐색기에서 WindowsApplication1 마우스 오른쪽 단추로 클릭한 다음 속성 을 클릭하십시오.
  5. 서명 을 클릭한 다음 곧 만료될 인증서를 할당하십시오.
  6. 솔루션 탐색기에서 WindowsApplication1 마우스 오른쪽 단추로 게시 를 클릭하십시오. 게시 마법사를 시작합니다.
  7. 에 있는 응용 프로그램을 게시할 위치를? 페이지 유효한 URL을 입력한 후 다음 을 클릭합니다. URL을 다음과 같은 형식을 사용하십시오.
    http://ServerName/FolderName
  8. 에 있는 응용 프로그램을 오프라인으로 사용할 수 있습니까? 페이지, 적절한 옵션을 클릭합니다.

    슬라이드 노트
    • 사용자가 네트워크 연결이 끊어졌을 때 응용 프로그램을 실행할 수 있도록 하려면 예, 이 응용 프로그램을 온라인 또는 오프라인으로 사용할 수 를 클릭하십시오. 시작 메뉴에서 응용 프로그램에 대한 바로 가기를 만듭니다.
    • 아니오, 이 응용 프로그램을 사용할 경우에만 온라인 응용 프로그램을 게시 위치에서 직접 실행하려면 클릭하십시오. 마법사는 시작 메뉴에서 바로 가기를 만들지 않습니다.
  9. 계속하려면 다음 을 클릭하십시오.
  10. 응용 프로그램을 게시하려면 마침 을 클릭하십시오.
  11. http://ServerName ClickOnce 응용 프로그램 설치/FolderName/publish.htm URL입니다.
  12. 인증서가 만료된 후에도 6 위해 응용 프로그램을 게시하려면 10단계를 반복하십시오.
  13. http://ServerName ClickOnce 응용 프로그램 업데이트를 설치하려고/FolderName/publish.htm URL입니다.

속성

기술 자료: 925521 - 마지막 검토: 2009년 3월 12일 목요일 - 수정: 4.1
본 문서의 정보는 다음의 제품에 적용됩니다.
  • Microsoft Visual Studio 2005 Standard Edition
  • Microsoft Visual Studio 2005 Professional Edition
  • Microsoft Visual Studio 2005 Express Edition
키워드:?
kbmt kbtshoot kberrmsg kbbug kbprb KB925521 KbMtko
기계 번역된 문서
중요: 본 문서는 전문 번역가가 번역한 것이 아니라 Microsoft 기계 번역 소프트웨어로 번역한 것입니다. Microsoft는 번역가가 번역한 문서 및 기계 번역된 문서를 모두 제공하므로 Microsoft 기술 자료에 있는 모든 문서를 한글로 접할 수 있습니다. 그러나 기계 번역 문서가 항상 완벽한 것은 아닙니다. 따라서 기계 번역 문서에는 마치 외국인이 한국어로 말할 때 실수를 하는 것처럼 어휘, 구문 또는 문법에 오류가 있을 수 있습니다. Microsoft는 내용상의 오역 또는 Microsoft 고객이 이러한 오역을 사용함으로써 발생하는 부 정확성, 오류 또는 손해에 대해 책임을 지지 않습니다. Microsoft는 이러한 문제를 해결하기 위해 기계 번역 소프트웨어를 자주 업데이트하고 있습니다.

피드백 보내기

 

Contact us for more help

Contact us for more help
Connect with Answer Desk for expert help.
Get more support from smallbusiness.support.microsoft.com