X.509证书生成

创建数字证书

用户对数字证书的认可决定于对证书颁发机构的信任,所以证书颁发机构决定了数字证书的可用范围。由于官方认可的数字证书颁发机构,比如VeriSign、Thawte(OpenSSL),具有普遍的信任度,在大部分情况下是理想的选择。但是对于学习研究或者开发测试,我们没有必要去购买这些商用证书,采用利用一些工具以手工的方式创建证书。

由于WCF的安全机制广泛使用到数字证实,我们很有必要学会手工创建数字证书。微软为我们提供了一个强大的创建数字证书的工具MakeCert.exe,我们可以借助这个工具采用命令行的方式创建我们需要的数字证书。MakeCert.exe具有很多命令行开关,限于篇幅的问题不可能对它们一一介绍,在这里仅仅对几个常用的开关作一下简单的介绍,有兴趣的读者可以查阅MSDN在线文档了解MakeCert.exe所有命令行开关的含义,对应的地址为http://msdn.microsoft.com/zh-cn/library/bfsktky3(v=vs.80).aspx

  • -n x509name:指定主题的证书名称。最简单的方法是在双引号中指定此名称,并加上前缀CN=,例如,"CN=My Name";
  • -pe:将所生成的私钥标记为可导出,这样可将私钥包括在证书中;
  • -sr location:数字证书的存储位置,具有两个可选值:CurrentUser(和LocalMachine。前者基于当前登录用户,后者基于本机;
  • -ss store:数字证书的存储区;
  • -sky keytype:指定主题的密钥类型,必须是 signature、exchange 或一个表示提供程序类型的整数。默认情况下,可传入1表示交换密钥,传入2表示签名密钥。

比如我通过下面的命令会创建一个主题名称为www.artech.com的数字证书,该证书具有交换密钥类型,并且包含私钥。

   1: MakeCert -n "CN=www.artech.com" -pe -sr LocalMachine -ss My -sky exchange
一旦上面的命令成功执行,生成的证书会自动保存到基于本机的个人(Personal)存储区中。你可以通过MMC的证书管理单元(Snap-in)查看该证书, 关于如何通过MMC查看证书,可以参考这个地址:http://msdn.microsoft.com/zh-cn/library/ms788967.aspx。下图是证书MMC管理单元的截图,你可以看到我们创建的数字证书已经被存储到了我们在命令行中指定的存储区,颁发机构被默认设定为Root Agency。


上一篇简单说了一下使用加密数据传输的好处,这一篇说一下如何使用使用X509证书方式(部署IIS)  (system :windows server2008 r2)

如何创建证书:

      makecert.exe -sr LocalMachine -ss My -a sha1 -n CN=JiangServer -sky exchange -pe     (服务端证书)

      makecert.exe -sr LocalMachine -ss My -a sha1 -n CN=JiangClient -sky exchange -pe      (客户端证书)

各种参数的介绍

属性解析

-sr

指定的证书存储区中的注册表位置。 
currentUser 
指定注册版存储位置为 HKEY_CURRENT_USER. 
localMachine 
指定注册版存储位置为 HKEY_LOCAL_MACHINE.

-ss

指定证书存储的位置。

-a

指定相关的算法,可以选择 MD5 算法或者 SHA1算法

-n

指定证书的名称。该名称遵循X.500命名标准。简单例子如 "CN=MyName" 格式,如果没有指定/n开关,证书默认的名称是"Joe's Software Emporium"。

-sky

证书键类型。可以设置为 exchange 或者 signature。

-pe

证书可导出

详细说明:见msdn。

   证书创建成功后!—

image

服务端config配置非常重要,如下:

复制代码
<?xml version="1.0" encoding="utf-8"?>
<configuration>

<system.web>
<compilation debug="true" targetFramework="4.0" />
</system.web>
<system.serviceModel>
<services>
<service name="WcfService.Service1" behaviorConfiguration="CustomBehavior">

<endpoint
binding="mexHttpBinding"
contract="IMetadataExchange"
address="mex" />
<endpoint address="" binding="wsHttpBinding" contract="WcfService.IService1" bindingConfiguration="CustomBinding"/>

</service>
</services>
<behaviors>
<serviceBehaviors>
<behavior name="CustomBehavior">
<!-- 为避免泄漏元数据信息,请在部署前将以下值设置为 false 并删除上面的元数据终结点 -->
<serviceMetadata httpGetEnabled="true"/>
<!-- 要接收故障异常详细信息以进行调试,请将以下值设置为 true。在部署前设置为 false 以避免泄漏异常信息 -->
<serviceDebug includeExceptionDetailInFaults="false"/>

<serviceCredentials>
<!-- 服务端采用证书详细配置 findValue :创建证书名称 storeName:证书储存详细位于哪 storeLocation :证书储存位于当前本机用户 X509FindType : x509查找证书主题名-->
<serviceCertificate findValue="JiangServer" storeName="My" storeLocation="LocalMachine" x509FindType="FindBySubjectName"/>
<!--客户端验证方式-->
<clientCertificate>
<authentication certificateValidationMode="None"/>
</clientCertificate>
</serviceCredentials>

</behavior>
</serviceBehaviors>
</behaviors>
<serviceHostingEnvironment multipleSiteBindingsEnabled="true" />

<bindings>
<wsHttpBinding>
<binding name="CustomBinding">
<!--验证方式-->
<security mode="Message">
<message clientCredentialType="Certificate"/>
</security>
</binding>
</wsHttpBinding>
</bindings>

</system.serviceModel>
<system.webServer>
<modules runAllManagedModulesForAllRequests="true"/>
</system.webServer>

</configuration>
复制代码



这样就基本简单的x509验证方式已经配置好了,发布到IIS中。运行如下:

-----------------------------------------------------------------------------------------------------------运行后报错---------------------------

“/”应用程序中的服务器错误。
--------------------------------------------------------------------------------

密钥集不存在。

说明: 执行当前 Web 请求期间,出现未经处理的异常。请检查堆栈跟踪信息,以了解有关该错误以及代码中导致错误的出处的详细信息。 

异常详细信息: System.Security.Cryptography.CryptographicException: 密钥集不存在。


源错误: 

执行当前 Web 请求期间生成了未经处理的异常。可以使用下面的异常堆栈跟踪信息确定有关异常原因和发生位置的信息。  

堆栈跟踪: 


[CryptographicException: 密钥集不存在。
]
   System.Security.Cryptography.Utils.CreateProvHandle(CspParameters parameters, Boolean randomKeyContainer) +450
   System.Security.Cryptography.Utils.GetKeyPairHelper(CspAlgorithmType keyType, CspParameters parameters, Boolean randomKeyContainer, Int32 dwKeySize, SafeProvHandle& safeProvHandle, SafeKeyHandle& safeKeyHandle) +158
   System.Security.Cryptography.RSACryptoServiceProvider.GetKeyPair() +231
   System.Security.Cryptography.X509Certificates.X509Certificate2.get_PrivateKey() +537
   System.ServiceModel.Security.SecurityUtils.EnsureCertificateCanDoKeyExchange(X509Certificate2 certificate) +78

[ArgumentException: 可能证书“CN=GAServer1”没有能够进行密钥交换的私钥,或者进程可能没有访问私钥的权限。有关详细信息,请参见内部异常。]

 

image

分析错误提示,应该是没有权限呀,我们打开”MMC” 打到我的们 My --证书中的 JiangServer 设置权限。

image

添加Everyone --读取

image

再次运行wcf,成功了!

image

现在服务端已经 Deployment!再创建客户端,引用wcf服务。引用wcf服务成功后,我要再次要Deployment   “App.config”文件,添加验证信息。

复制代码
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<system.serviceModel>
<bindings>
<wsHttpBinding>
<binding name="abc" closeTimeout="00:01:00"
openTimeout="00:01:00" receiveTimeout="00:10:00" sendTimeout="00:01:00"
bypassProxyOnLocal="false" transactionFlow="false" hostNameComparisonMode="StrongWildcard"
maxBufferPoolSize="524288" maxReceivedMessageSize="65536"
messageEncoding="Text" textEncoding="utf-8" useDefaultWebProxy="true"
allowCookies="false">
<readerQuotas maxDepth="32" maxStringContentLength="8192" maxArrayLength="16384"
maxBytesPerRead="4096" maxNameTableCharCount="16384" />
<reliableSession ordered="true" inactivityTimeout="00:10:00"
enabled="false" />
<security mode="Message">
<message clientCredentialType="Certificate"/>
</security>
</binding>
</wsHttpBinding>
</bindings>
<client>
<endpoint address="http://192.168.1.3/Service1.svc" binding="wsHttpBinding"
bindingConfiguration="abc" contract="ServiceReference1.IService1"
name="WSHttpBinding_IService1" behaviorConfiguration="CustomBehavior">
<identity>
<!--成功引用后,自动生成的码-->
<certificate encodedValue="AwAAAAEAAAAUAAAAIAUN/+3YklX/nz/t50hALxjci4IgAAAAAQAAALcBAAAwggGzMIIBYaADAgECAhBEsG++ZOulskOwScx8Gti4MAkGBSsOAwIdBQAwFjEUMBIGA1UEAxMLUm9vdCBBZ2VuY3kwHhcNMTExMjMwMDI1MjE1WhcNMzkxMjMxMjM1OTU5WjAWMRQwEgYDVQQDEwtKaWFuZ1NlcnZlcjCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEA8HGfOESdAJA6CfUCKxsjVx+G50jzbCykCQT2UzYLhmTZn0/jRt3AhwcJn4wO7tU5xNhZUXhLc/Vxk8apJT6Y7fSv9A02mbX5GShVTuRCpJJZN89VmEKAoWfV1n7iMsbUFBzAQm71+9K3KMAWs77ymYbBb6aVXyxfyYfuPrC/3xsCAwEAAaNLMEkwRwYDVR0BBEAwPoAQEuQJLQYdHU8AjWEh3BZkY6EYMBYxFDASBgNVBAMTC1Jvb3QgQWdlbmN5ghAGN2wAqgBkihHPuNSqXDX0MAkGBSsOAwIdBQADQQBVVrkT8SCHXE3KaXWMX8x5PplYazhf+ibhjkg8P3CjldB9h12BmNKtbo1on7GxrNJb0drOxYB2vqjbolQ82NZT" />
</identity>
</endpoint>
</client>
<!--添加以下配置-->
<behaviors>
<endpointBehaviors>
<behavior name="CustomBehavior">
<clientCredentials>
<!--客户端证书-->
<clientCertificate findValue="JiangClient" storeName="My" storeLocation="LocalMachine" x509FindType="FindBySubjectName"/>
<serviceCertificate>
<authentication certificateValidationMode="None"/>
</serviceCertificate>
</clientCredentials>
</behavior>
</endpointBehaviors>
</behaviors>
</system.serviceModel>
</configuration>

复制代码

启动客户端,调用成功!

image

注意:如果调用wcf失败,几个错误信息

1>   : 无法使用以下搜索标准找到 X.509 证书: StoreName“My”、StoreLocation“LocalMachine”、FindType“FindBySubjectName”、FindValue“JiangClient1”。

image

解决办法:导入证书(JiangClient1)或创建此证书,注意报的错误信息中的证书所储存位置

2 > : 未提供客户端证书。请在 ClientCredential 中指定一个客户端证书。

image

解决办法: 因为服务端使用了证书验证,所以要在客户端配置证书。

image

再次调用成功!以上就是我在设置X509证书时出现在问题。

再次用HttpAnalyzerStdV5查看是否已经加密。如下,已经加密了

image

转自http://www.cnblogs.com/server126/archive/2011/12/30/2307258.html

原文地址:https://www.cnblogs.com/jyzjh/p/5983575.html