다음을 통해 공유


InitializeSecurityContext(협상) 함수

InitializeSecurityContext(Negotiate) 함수는 자격 증명 핸들에서 클라이언트 쪽 아웃바운드 보안 컨텍스트를 시작합니다. 함수는 클라이언트 애플리케이션과 원격 피어 간에 보안 컨텍스트 를 빌드하는 데 사용됩니다. InitializeSecurityContext(협상) 는 클라이언트가 원격 피어에 전달해야 하는 토큰을 반환하며, 피어는 AcceptSecurityContext(협상) 호출을 통해 로컬 보안 구현에 제출합니다. 생성된 토큰은 모든 호출자가 불투명한 것으로 간주해야 합니다.

일반적으로 InitializeSecurityContext(Negotiate) 함수는 충분한 보안 컨텍스트 가 설정될 때까지 루프에서 호출됩니다.

구문

SECURITY_STATUS SEC_Entry InitializeSecurityContext(
  _In_opt_    PCredHandle    phCredential,
  _In_opt_    PCtxtHandle    phContext,
  _In_opt_    SEC_CHAR       *pszTargetName,
  _In_        ULONG          fContextReq,
  _In_        ULONG          Reserved1,
  _In_        ULONG          TargetDataRep,
  _In_opt_    PSecBufferDesc pInput,
  _In_        ULONG          Reserved2,
  _Inout_opt_ PCtxtHandle    phNewContext,
  _Inout_opt_ PSecBufferDesc pOutput,
  _Out_       PULONG         pfContextAttr,
  _Out_opt_   PTimeStamp     ptsExpiry
);

매개 변수

phCredential[in, optional]

AcquireCredentialsHandle(협상)에서 반환된 자격 증명에 대한 핸들입니다. 이 핸들은 보안 컨텍스트를 빌드하는 데 사용됩니다. InitializeSecurityContext(협상) 함수에는 최소한 OUTBOUND 자격 증명이 필요합니다.

phContext[in, optional]

CtxtHandle 구조체에 대한 포인터입니다. InitializeSecurityContext(협상)에 대한 첫 번째 호출에서 이 포인터는 입니다NULL. 두 번째 호출에서 이 매개 변수는 첫 번째 호출에 의해 phNewContext 매개 변수에 반환된 부분적으로 형성된 컨텍스트에 대한 핸들에 대한 포인터입니다.

경고

InitializeSecurityContext(협상)에 대한 동시 호출에서 동일한 컨텍스트 핸들을 사용하지 마세요. 보안 서비스 공급자의 API 구현은 스레드로부터 안전하지 않습니다.

pszTargetName[in, optional]

SPN(서비스 사용자 이름) 또는 대상 서버의 보안 컨텍스트 를 나타내는 null로 종료된 문자열에 대한 포인터입니다.

애플리케이션은 재생 공격을 완화하기 위해 유효한 SPN을 제공해야 합니다.

fContextReq[in]

컨텍스트에 대한 요청을 나타내는 비트 플래그입니다. 모든 패키지가 모든 요구 사항을 지원할 수 있는 것은 아닙니다. 이 매개 변수에 사용되는 플래그에는 접두사로 ISC_REQ_(예: ISC_REQ_DELEGATE)가 있습니다. 이 매개 변수는 다음 특성 플래그 중 하나 이상일 수 있습니다.

의미
ISC_REQ_ALLOCATE_MEMORY 보안 패키지는 출력 버퍼를 할당합니다. 출력 버퍼 사용을 마치면 FreeContextBuffer 함수를 호출하여 해제합니다.
ISC_REQ_CONFIDENTIALITY EncryptMessage 함수를 사용하여 메시지를 암호화합니다.
ISC_REQ_CONNECTION 보안 컨텍스트는 메시지 서식을 처리하지 않습니다. 이 값은 기본값입니다.
ISC_REQ_DELEGATE 서버는 컨텍스트를 사용하여 다른 서버에 클라이언트로 인증할 수 있습니다. 이 플래그가 작동하려면 ISC_REQ_MUTUAL_AUTH 플래그를 설정해야 합니다. Kerberos에 유효합니다. 제한된 위임에 대해 이 플래그를 무시합니다.
ISC_REQ_EXTENDED_ERROR 오류가 발생하면 원격 당사자에게 알림이 표시됩니다.
ISC_REQ_INTEGRITY EncryptMessageMakeSignature 함수를 사용하여 메시지에 서명하고 서명을 확인합니다.
ISC_REQ_MUTUAL_AUTH 서비스의 상호 인증 정책이 충족됩니다.
주의: 이것은 반드시 상호 인증이 수행된다는 것을 의미하지는 않으며 서비스의 인증 정책이 충족된다는 것만을 의미합니다. 상호 인증이 수행되도록 하려면 QueryContextAttributes(협상) 함수를 호출합니다 .
ISC_REQ_NO_INTEGRITY 이 플래그를 설정하면 ISC_REQ_INTEGRITY 플래그가 무시됩니다.
ISC_REQ_REPLAY_DETECT EncryptMessage 또는 MakeSignature 함수를 사용하여 인코딩된 재생된 메시지를 검색합니다.
ISC_REQ_SEQUENCE_DETECT 시퀀스에서 수신된 메시지를 검색합니다.
ISC_REQ_STREAM 스트림 지향 연결을 지원합니다.

요청된 특성은 클라이언트에서 지원되지 않을 수 있습니다. 자세한 내용은 pfContextAttr 매개 변수를 참조하세요.

다양한 특성에 대한 자세한 내용은 컨텍스트 요구 사항을 참조하세요.

Reserved1[in]

이 매개 변수는 예약되어 있으며 0으로 설정해야 합니다.

TargetDataRep[in]

대상의 바이트 순서 지정과 같은 데이터 표현입니다. 이 매개 변수는 SECURITY_NATIVE_DREP 또는 SECURITY_NETWORK_DREP 수 있습니다.

pInput[in, optional]

패키지에 대한 입력으로 제공된 버퍼에 대한 포인터를 포함하는 SecBufferDesc 구조체에 대한 포인터입니다. 서버에서 클라이언트 컨텍스트를 시작하지 않는 한 이 매개 변수의 값은 함수에 대한 첫 번째 호출에 있어야 NULL 합니다. 함수에 대한 후속 호출 또는 서버에서 클라이언트 컨텍스트를 시작한 경우 이 매개 변수의 값은 원격 컴퓨터에서 반환된 토큰을 보유하기에 충분한 메모리로 할당된 버퍼에 대한 포인터입니다.

Reserved2[in]

이 매개 변수는 예약되어 있으며 0으로 설정해야 합니다.

phNewContext[in, out, optional]

CtxtHandle 구조체에 대한 포인터입니다. InitializeSecurityContext(협상)에 대한 첫 번째 호출에서 이 포인터는 새 컨텍스트 핸들을 받습니다. 두 번째 호출에서 phNewContextphContext 매개 변수에 지정된 핸들과 같을 수 있습니다. phNewContext는 되어서는 안 됩니다 NULL.

pOutput[in, out, optional]

출력 데이터를 수신하는 SecBuffer 구조체에 대한 포인터를 포함하는 SecBufferDesc 구조체에 대한 포인터입니다. 버퍼가 입력에 SEC_READWRITE 입력된 경우 출력에 있습니다. 시스템은 요청된 경우(ISC_REQ_ALLOCATE_MEMORY 통해) 보안 토큰에 대한 버퍼를 할당하고 보안 토큰에 대한 버퍼 설명자의 주소를 채웁니다.

pfContextAttr[out]

설정된 컨텍스트의 특성을 나타내는 비트 플래그 집합을 수신하는 변수에 대한 포인터입니다. 다양한 특성에 대한 설명은 컨텍스트 요구 사항을 참조하세요.

이 매개 변수에 사용되는 플래그에는 ISC_RET_DELEGATE 같은 ISC_RET 접두사로 지정됩니다. 유효한 값 목록은 fContextReq 매개 변수를 참조하세요.

최종 함수 호출이 성공적으로 반환될 때까지 보안 관련 특성에 대해 검사 않습니다. ASC_RET_ALLOCATED_MEMORY 플래그와 같이 보안과 관련이 없는 특성 플래그는 최종 반환 전에 확인할 수 있습니다.

참고

특정 컨텍스트 특성은 원격 피어와 협상하는 동안 변경 될 수 있습니다.

ptsExpiry[out, optional]

컨텍스트의 만료 시간을 수신하는 TimeStamp 구조체에 대한 포인터입니다. 보안 패키지는 항상 로컬 시간에 이 값을 반환하는 것이 좋습니다. 이 매개 변수는 선택 사항이며 NULL 수명이 짧은 클라이언트에 대해 전달되어야 합니다.

반환 값

함수가 성공하면 함수는 다음 성공 코드 중 하나를 반환합니다.

반환 코드 설명
SEC_E_OK 보안 컨텍스트가 성공적으로 초기화되었습니다. 다른 InitializeSecurityContext(협상) 호출이 필요하지 않습니다. 함수가 출력 토큰을 반환하는 경우, 즉 pOutput 의 SECBUFFER_TOKEN 길이가 0이 아닌 경우 해당 토큰을 서버로 보내야 합니다.
SEC_I_COMPLETE_AND_CONTINUE 클라이언트는 CompleteAuthToken 을 호출한 다음 출력을 서버에 전달해야 합니다. 그런 다음 클라이언트는 반환된 토큰을 기다렸다가 다른 호출에서 InitializeSecurityContext(협상)에 전달합니다.
SEC_I_COMPLETE_NEEDED 클라이언트는 메시지 빌드를 완료한 다음 CompleteAuthToken 함수를 호출해야 합니다.
SEC_I_CONTINUE_NEEDED 클라이언트는 출력 토큰을 서버에 보내고 반환 토큰을 기다려야 합니다. 반환된 토큰은 InitializeSecurityContext(협상)에 대한 다른 호출에서 전달됩니다. 출력 토큰은 비어 있을 수 있습니다.

함수가 실패하면 함수는 다음 오류 코드 중 하나를 반환합니다.

반환 코드 설명
SEC_E_INSUFFICIENT_MEMORY 요청된 작업을 완료하는 데 사용할 수 있는 메모리가 부족합니다.
SEC_E_INTERNAL_ERROR SSPI 오류 코드에 매핑되지 않은 오류가 발생했습니다.
SEC_E_INVALID_HANDLE 함수에 전달된 핸들이 잘못되었습니다.
SEC_E_INVALID_TOKEN 이 오류는 전송 중에 손상된 토큰, 잘못된 크기의 토큰 또는 잘못된 제한된 위임에 전달된 토큰과 같은 형식이 잘못된 입력 토큰 때문입니다. 클라이언트와 서버가 적절한 제한된 위임을 협상하지 않은 경우 잘못된 패키지에 토큰을 전달할 수 있습니다.
SEC_E_LOGON_DENIED 로그온에 실패했습니다.
SEC_E_NO_AUTHENTICATING_AUTHORITY 인증을 위해 연락할 수 있는 권한은 없습니다. 인증 당사자의 도메인 이름이 잘못되었거나, 도메인에 연결할 수 없거나, 트러스트 관계 오류가 발생할 수 있습니다.
SEC_E_NO_CREDENTIALS 제한된 위임에서 자격 증명을 사용할 수 없습니다.
SEC_E_TARGET_UNKNOWN 대상이 인식되지 않았습니다.
SEC_E_UNSUPPORTED_FUNCTION 잘못된 컨텍스트 특성 플래그(ISC_REQ_DELEGATE 또는 ISC_REQ_PROMPT_FOR_CREDS)가 fContextReq 매개 변수에 지정되었습니다.
SEC_E_WRONG_PRINCIPAL 인증 요청을 받은 보안 주체는 pszTargetName 매개 변수에 전달된 보안 주체와 다릅니다. 이는 상호 인증에 실패했음을 나타냅니다.

설명

호출자는 최종 컨텍스트 특성이 충분한지 여부를 결정합니다. 예를 들어 기밀성을 요청했지만 설정할 수 없는 경우 일부 애플리케이션은 연결을 즉시 종료하도록 선택할 수 있습니다.

보안 컨텍스트의 특성이 충분하지 않은 경우 클라이언트는 DeleteSecurityContext 함수를 호출하여 부분적으로 생성된 컨텍스트를 해제해야 합니다.

InitializeSecurityContext(Negotiate) 함수는 클라이언트에서 아웃바운드 컨텍스트를 초기화하는 데 사용됩니다.

두 다리 보안 컨텍스트의 경우 호출 시퀀스는 다음과 같습니다.

  1. 클라이언트는 phContext 가 로 설정된 함수를 NULL 호출하고 입력 메시지로 버퍼 설명자를 채웁니다.
  2. 보안 패키지는 매개 변수를 검사하고 불투명 토큰을 생성하여 버퍼 배열의 TOKEN 요소에 배치합니다. fContextReq 매개 변수에 ISC_REQ_ALLOCATE_MEMORY 플래그가 포함된 경우 보안 패키지는 메모리를 할당하고 TOKEN 요소의 포인터를 반환합니다.
  3. 클라이언트는 pOutput 버퍼에 반환된 토큰을 대상 서버로 보냅니다. 그런 다음 서버는 AcceptSecurityContext(협상) 함수에 대한 호출에서 토큰을 입력 인수로 전달합니다.
  4. AcceptSecurityContext(협상) 는 첫 번째 호출이 SEC_I_CONTINUE_NEEDED 반환된 경우 서버가 InitializeSecurityContext(Negotiate) 에 대한 두 번째 호출을 위해 클라이언트에 보내는 토큰을 반환할 수 있습니다.

상호 인증과 같은 다중 다리 보안 컨텍스트의 경우 호출 시퀀스는 다음과 같습니다.

  1. 클라이언트는 앞에서 설명한 대로 함수를 호출하지만 패키지는 SEC_I_CONTINUE_NEEDED 성공 코드를 반환합니다.
  2. 클라이언트는 출력 토큰을 서버에 보내고 서버의 회신을 기다립니다.
  3. 서버의 응답을 받으면 클라이언트는 InitializeSecurityContext(협상) 를 다시 호출하고 phContext 는 마지막 호출에서 반환된 핸들로 설정됩니다. 서버에서 받은 토큰은 pInput 매개 변수에 제공됩니다.
  4. InitializeSecurityContext(협상)에 대한 동시 호출에는 phContext 값을 사용하지 마세요. 보안 공급자의 구현은 스레드로부터 안전하지 않습니다.

서버가 성공적으로 응답한 경우 보안 패키지 는 SEC_E_OK 반환하고 보안 세션이 설정됩니다.

함수가 오류 응답 중 하나를 반환하는 경우 서버의 응답이 수락되지 않고 세션이 설정되지 않습니다.

함수가 SEC_I_CONTINUE_NEEDED, SEC_I_COMPLETE_NEEDED 또는 SEC_I_COMPLETE_AND_CONTINUE 반환하는 경우 2단계와 3단계가 반복됩니다.

보안 컨텍스트를 초기화하려면 fContextReq 매개 변수에 지정된 선택 사항뿐만 아니라 기본 인증 메커니즘에 따라 이 함수를 두 번 이상 호출해야 할 수 있습니다.

fContextReqpfContextAttributes 매개 변수는 다양한 컨텍스트 특성을 나타내는 비트 마스크입니다. 다양한 특성에 대한 설명은 컨텍스트 요구 사항을 참조하세요. pfContextAttributes 매개 변수는 성공적인 반환에 유효하지만 컨텍스트의 보안 측면과 관련된 플래그를 검사해야 최종 성공적인 반환에만 유효합니다. 중간 반환은 ISC_RET_ALLOCATED_MEMORY 플래그와 같이 설정할 수 있습니다.

ISC_REQ_USE_SUPPLIED_CREDS 플래그가 설정된 경우 보안 패키지pInput 입력 버퍼에서 SECBUFFER_PKG_PARAMS 버퍼 형식을 찾아야 합니다. 이는 일반적인 솔루션은 아니지만 적절한 경우 보안 패키지 와 애플리케이션을 강력하게 페어링할 수 있습니다.

ISC_REQ_ALLOCATE_MEMORY 지정한 경우 호출자는 FreeContextBuffer 함수를 호출하여 메모리를 해제해야 합니다.

예를 들어 입력 토큰은 LAN 관리자의 과제일 수 있습니다. 이 경우 출력 토큰은 챌린지에 대한 NTLM 암호화 응답입니다.

클라이언트가 수행하는 작업은 이 함수의 반환 코드에 따라 달라집니다. 반환 코드가 SEC_E_OK 경우 두 번째 InitializeSecurityContext(협상) 호출이 없고 서버의 응답이 필요하지 않습니다. 반환 코드가 SEC_I_CONTINUE_NEEDED 경우 클라이언트는 서버의 응답으로 토큰을 예상하여 InitializeSecurityContext(협상)에 대한 두 번째 호출에서 전달합니다. SEC_I_COMPLETE_NEEDED 반환 코드는 클라이언트가 메시지 작성을 완료하고 CompleteAuthToken 함수를 호출해야 했음을 나타냅니다. SEC_I_COMPLETE_AND_CONTINUE 코드는 이러한 작업을 모두 통합합니다.

InitializeSecurityContext(협상)가 첫 번째(또는 유일한) 호출에서 성공을 반환하는 경우 호출자는 인증 교환의 이후 레그에서 호출이 실패하더라도 반환된 핸들에서 DeleteSecurityContext 함수를 호출해야 합니다.

클라이언트는 성공적으로 완료된 후 InitializeSecurityContext(협상) 를 다시 호출할 수 있습니다. 이는 보안 패키지 에 재인증이 원한다는 것을 나타냅니다.

커널 모드 호출자에는 다음과 같은 차이점이 있습니다. 대상 이름은 VirtualAlloc을 사용하여 가상 메모리에 할당해야 하는 유니코드 문자열입니다. 풀에서 할당해서는 안 됩니다. pInputpOutput에서 전달되고 제공된 버퍼는 풀이 아닌 가상 메모리에 있어야 합니다.

요구 사항

요구 사항
지원되는 최소 클라이언트 Windows XP [데스크톱 앱만 해당]
지원되는 최소 서버 Windows Server 2003 [데스크톱 앱만 해당]
헤더 Sspi.h(Security.h 포함)
라이브러리 Secur32.lib
DLL Secur32.dll

추가 정보

SSPI 함수

AcceptSecurityContext(협상)

AcquireCredentialsHandle(협상)

CompleteAuthToken

DeleteSecurityContext

FreeContextBuffer

SecBuffer

SecBufferDesc