贝贝花花包包店,精品555皮具,钱夹,皮夹

字体: | 推荐给好友 上一篇 | 下一篇

Windows2000 服务器端应用程序开发设计指南-安全连接(3)

发布: 2008-5-01 14:21 | 作者: Jeffrey Richter Jaso | 来源: 网络转载 | 查看: 154次

SSL与SSPI
 

我们已经利用Windows信任帐户讨论过使用NTLM及Kerberos之SSPI及验证的部份。您也可以经由数位凭证使用SSPI去做验证的动作。经由使用SSPI及SSL的Schannel安全性提供者可以达成此工作。若您打算使用SSL,则您的程序代码中必定要包含Security.h及SChannel.h标头档,并且应该把您的专案与Secur32.lib程序库文件做连结。

和目前为止曾讨论的通讯协定不同,SSL比较不集中于从客户端至服务器的验证部份,通常从服务器到客户端验证的部份开始。从客户端至服务器验证的方式也是可能的,在这种情况下,可以选择使用模拟(Impersonation)的方式。首先让我们看一些常见的方案。客户端想要与某些站台连接时,最大的可能是在Internet上。在传送站台的关键性资讯前,它想要证明自己正在与所要求的实体通讯。此时服务器会传送客户端的凭证。此凭证已被签章,其中并包含了公开/私密金钥之公开金钥。

客户端可以辨认该凭证是由谁发行的,并帮助客户端决定是否应信任这个凭证。假如它信任签署凭证的CA,则客户端可以相信凭证内的资讯是有效的。凭证经过验证后,客户端即可以读取凭证资讯,例如服务器的URL等,并把这些资讯与正在与它通讯的服务器做比较。假如对照的结果符合,则客户端可以确信它正在与正确的服务器联系。


说明

有许多的凭证模组议题尚未被业界开发。客户端软件如何能够真正信任凭证内的资讯?有较好的方法可以把信任的重担从客户端软件转移到使用者身上吗?如何转达资讯?什么样的根授权单位应被信任?使用者可以选择这些授权单位吗?所有的授权单位应该被凭证的任何类型信任吗?凭证授权单位也应该是特定群组的业界授权单位,例如doctors’ offices或预约的传递者吗?这些问题的回答将显露出成熟的技术。从现在开始,我们将集中在技术的讨论上。


根据您设计的安全通讯环境,可以决定您自己的凭证授权单位。Microsoft凭证服务可让您发行自己的凭证,而且只要您的客户端信任您的CA,就可以建立符合确切标准的凭证。假如您是自己的凭证授权单位,您甚至可以编写包含信任您的CA之内部根凭证的客户端软件。当客户端连接到您的服务器时,可以使用这个内含的信任来启始一个客户端的工作阶段,然后再为客户端产生凭证(在那里,客户端会产生私密金钥并传递公开金钥给您的服务器)。您的服务器会使用公开金钥从您自己的CA产生凭证,然后储藏这个资讯。此后每当客户端连接到您的服务器时,便可以使用彼此的公开金钥,以凭证的形式,快速地对彼此验证、协商工作阶段金钥,并开始交易。

假定客户端已经验证了服务器的凭证,客户端可以从凭证中取出公开金钥并且用它来对传送到服务器的对称性工作阶段金钥做加密。服务器是唯一持有对称私密金钥的实体,所以它可以将此工作阶段金钥做解密。此时客户端及服务器可以确定它们已经可以与适当的另一方做安全地通讯。

在标准情形下所要求的安全通讯是使浏览器或其他客户端跨越线路传送信用卡或其他敏感的资讯到服务器端。您可以使用SSPI为这种交易实作SSL机制。

SSL程序设计
 

您已经知道了许多应用于SSL通讯的相关SSPI。本节假定您已经具备使用Kerberos的SSPI及NTLM的知识;我们要开始建立目前为止本章所提及之大量资讯。

使用NTLM及Kerberos通讯协定时,您会在通讯的客户端及服务器端呼叫AcquireCredentialsHandle函数。然而,SSL必须经由传入特定的SSP验证结构,即SCHANNEL_CRED,至少为通讯的一端建立凭证。SCHANNEL_CRED结构与SEC_WINNT_AUTH_ IDENTITY结构(本章稍早的时候讨论过)相似,除了SCHANNEL_CRED包括凭证资讯外,它提供了使用者名称、密码及网域名称等资讯。

SCHANNEL_CRED结构的定义如下:

typedef struct _SCHANNEL_CRED {
DWORD dwVersion;
DWORD cCreds;
PCCERT_CONTEXT *paCred;
HCERTSTORE hRootStore;
DWORD cMappers;
struct _HMAPPER **aphMappers;
DWORD cSupportedAlgs;
ALG_ID * palgSupportedAlgs;
DWORD grbitEnabledProtocols;
DWORD dwMinimumCipherStrength;
DWORD dwMaximumCipherStrength;
DWORD dwSessionLifespan;
DWORD dwFlags;
DWORD reserved;
} SCHANNEL_CRED;

服务器通常在将它传递到AcquireCredentialsHandle之前即使用凭证来初始SCHANNEL_CRED。以下的程序代码片段显示使用它的方法:

// 开启本地端机器的个人凭证存放档
HCERTSTORE hMyCertStore =
CertOpenStore(
CERT_STORE_PROV_SYSTEM_A,
X509_ASN_ENCODING | PKCS_7_ASN_ENCODING,
0,
CERT_SYSTEM_STORE_LOCAL_MACHINE,
"MY");
if(hMyCertStore==NULL){
// 错误
}
// 填入凭证名称的属性结构
PSTR pszCommonName = "Jason’s Test Certificate";
CERT_RDN_ATTR certRDNAttr[1];
certRDNAttr[0].pszObjId = szOID_COMMON_NAME;
certRDNAttr[0].dwValueType = CERT_RDN_PRINTABLE_STRING;
certRDNAttr[0].Value.pbData = (PBYTE)pszCommonName;
certRDNAttr[0].Value.cbData = lstrlen(pszCommonName);
CERT_RDN certRDN = {1, certRDNAttr};
// 搜寻凭证内容
PCCERT_CONTEXT pCertContext =
CertFindCertificateInStore(
hMyCertStore,
X509_ASN_ENCODING | PKCS_7_ASN_ENCODING,
0,
CERT_FIND_SUBJECT_ATTR,
&certRDN,
NULL);
if (pCertContext == NULL){
// 错误
}
// 填入凭证资讯到SCHANNEL_CRED变数
SCHANNEL_CRED sslCredentials = {0};
sslCredentials.dwVersion = SCHANNEL_CRED_VERSION;
sslCredentials.cCreds = 1;
sslCredentials.paCred = &pCertContext;
sslCredentials.grbitEnabledProtocols = SP_PROT_SSL3;
// 取得凭证handle
CredHandle hCredentials;
TimeStamp tsExpires;
SECURITY_STATUS ss =
AcquireCredentialsHandle(
NULL,
UNISP_NAME,
SECPKG_CRED_INBOUND,
NULL,
&sslCredentials,
NULL, NULL,
&hCredentials,
&tsExpires );
if(ss != SEC_E_OK){
// 错误
}

说明

请注意,这个程序代码使用了下一节即将讨论的凭证函数,即撷取凭证名称为「Jason’s Test Certificate」的PCCERT_CONTEXT结构。

TAG: Windows2000 安全连接 应用程序 开发 服务器端 设计指南

51/512345>
 

评分:0

我来说两句

seccode