Interoperabilidade de SSPI/Kerberos com GSSAPI
É necessário ter cuidado ao usar o SSP (provedor de suporte de segurança) Kerberos se a interoperabilidade com GSSAPI for um requisito. As convenções de código a seguir permitem a interoperabilidade com aplicativos baseados em GSSAPI:
Você pode encontrar o código de exemplo no SDK (Software Development Kit) da plataforma em Samples\Security\SSPI\GSS. Além disso, o exemplo unix equivalente é distribuído nas distribuições MIT e Heimdal Kerberos, cliente E servidor GSS.
Nomes de Windows-Compatible
As funções GSSAPI usam um formato de nome conhecido como gss_nt_service_name conforme especificado no RFC. Por exemplo, sample@host.dom.com é um nome que pode ser usado em um aplicativo baseado em GSSAPI. O sistema operacional Windows não reconhece o formato gss_nt_service_name e o nome completo da entidade de serviço, por exemplo, exemplo/host.dom.com@REALM, deve ser usado.
Autenticação
A autenticação geralmente é tratada quando uma conexão é configurada pela primeira vez entre um cliente e um servidor. Neste exemplo, o cliente está usando a SSPI ( Interface do Provedor de Suporte de Segurança ) e o servidor está usando GSSAPI.
Para configurar a autenticação no cliente SSPI
- Obtenha credenciais de saída usando AcquireCredentialsHandle.
- Crie um nome de serviço com gss_import_name() e obtenha credenciais de entrada usando gss_acquire_cred.
- Obtenha um token de autenticação para enviar ao servidor usando InitializeSecurityContext (Kerberos).
- Envie o token para o servidor.
Para configurar a autenticação no servidor GSSAPI
Analise a mensagem do cliente para extrair o token de segurança. Use a função gss_accept_sec_context , passando o token como um argumento.
Analise a mensagem do servidor para extrair o token de segurança. Passe esse token de segurança para InitializeSecurityContext (Kerberos).
Envie um token de resposta para o cliente.
A função gss_accept_sec_context pode retornar um token que você pode enviar de volta para o cliente.
Se for necessário continuar, envie um token de resposta para o servidor; caso contrário, a configuração da autenticação será concluída.
Se for necessário continuar, aguarde o próximo token do cliente; caso contrário, a configuração da autenticação será concluída.
Integridade e privacidade da mensagem
A maioria dos aplicativos baseados em GSSAPI usa a função GSS_Wrap para assinar uma mensagem antes de enviá-la. Por outro lado, a função GSS_Unwrap verifica a assinatura. GSS_Wrap está disponível na versão 2.0 da API e agora é amplamente usada e especificada em padrões da Internet que descrevem o uso da GSSAPI para adicionar segurança aos protocolos. Anteriormente, as funções GSS SignMessage e SealMessage eram usadas para integridade e privacidade da mensagem. GSS_Wrap e GSS_Unwrap são usados para integridade e privacidade com o uso da privacidade controlada pelo valor do argumento "conf_flag".
Se um protocolo baseado em GSSAPI for especificado para usar as funções gss_get_mic e gss_verify_mic , as funções SSPI corretas serão MakeSignature e VerifySignature. Lembre-se de que MakeSignature e VerifySignature não interoperarão com GSS_Wrap quando conf_flag estiver definido como zero ou com GSS_Unwrap. O mesmo vale para misturar EncryptMessage (Kerberos) definido apenas para assinatura e gss_verify_mic.
Observação
Não use as funções MakeSignature ou VerifySignature quando GSS_Wrap e GSS_Unwrap forem chamados.
O SSPI equivalente a GSS_Wrap é EncryptMessage (Kerberos) para integridade e privacidade.
O exemplo a seguir mostra como usar EncryptMessage (Kerberos) para assinar dados que serão verificados por GSS_Unwrap.
No cliente SSPI:
// Need three descriptors, two for the SSP and
// one to hold the application data.
in_buf_desc.cBuffers = 3;
in_buf_desc.pBuffers = wrap_bufs;
in_buf_desc.ulVersion = SECBUFFER_VERSION;
wrap_bufs[0].cbBuffer = sizes.cbSecurityTrailer;
wrap_bufs[0].BufferType = SECBUFFER_TOKEN;
wrap_bufs[0].pvBuffer = malloc(sizes.cbSecurityTrailer);
// This buffer holds the application data.
wrap_bufs[1].BufferType = SECBUFFER_DATA;
wrap_bufs[1].cbBuffer = in_buf.cbBuffer;
wrap_bufs[1].pvBuffer = malloc(wrap_bufs[1].cbBuffer);
memcpy(wrap_bufs[1].pvBuffer, in_buf.pvBuffer, in_buf.cbBuffer);
wrap_bufs[2].BufferType = SECBUFFER_PADDING;
wrap_bufs[2].cbBuffer = sizes.cbBlockSize;
wrap_bufs[2].pvBuffer = malloc(wrap_bufs[2].cbBuffer);
maj_stat = EncryptMessage(&context,
SignOnly ? KERB_WRAP_NO_ENCRYPT : 0,
&in_buf_desc, 0);
// Send a message to the server.
No servidor GSSAPI:
// Received message is in recv_buf.
maj_stat = gss_unwrap(&min_stat, context, &recv_buf, &msg_buf,
&conf_state, (gss_qop_t *) NULL);
(void) gss_release_buffer(&min_stat, &recv_buf);
// Original message is in msg_buf.
O SSPI equivalente a GSS_Unwrap é DecryptMessage (Kerberos). Aqui está um exemplo que mostra como usar DecryptMessage (Kerberos) para descriptografar dados que foram criptografados por GSS_Wrap.
No servidor GSSAPI:
// Seal the message.
send_buf.value = msg;
send_buf.length = msglen;
// If encrypt_flag = 1, privacy; encrypt_flag = 0, integrity.
maj_stat = gss_wrap(&min_stat, context, encrypt_flag,
GSS_C_QOP_DEFAULT, &send_buf, &state, &msg_buf);
// The message to send is in msg_buf.
No cliente SSPI:
wrap_buf_desc.cBuffers = 2;
wrap_buf_desc.pBuffers = wrap_bufs;
wrap_buf_desc.ulVersion = SECBUFFER_VERSION;
// This buffer is for SSPI.
wrap_bufs[0].BufferType = SECBUFFER_STREAM;
wrap_bufs[0].pvBuffer = xmit_buf.pvBuffer;
wrap_bufs[0].cbBuffer = xmit_buf.cbBuffer;
// This buffer holds the application data.
wrap_bufs[1].BufferType = SECBUFFER_DATA;
wrap_bufs[1].cbBuffer = 0;
wrap_bufs[1].pvBuffer = NULL;
maj_stat = DecryptMessage(
&context,
&wrap_buf_desc,
0, // no sequence number
&qop
);
// This is where the data is.
msg_buf = wrap_bufs[1];
// Check QOP of received message.
// If QOP is KERB_WRAP_NO_ENCRYPT, the message is signed only;
// otherwise, it is encrypted.
Comentários
https://aka.ms/ContentUserFeedback.
Em breve: Ao longo de 2024, eliminaremos os problemas do GitHub como o mecanismo de comentários para conteúdo e o substituiremos por um novo sistema de comentários. Para obter mais informações, consulteEnviar e exibir comentários de