- c - 在位数组中找到第一个零
- linux - Unix 显示有关匹配两种模式之一的文件的信息
- 正则表达式替换多个文件
- linux - 隐藏来自 xtrace 的命令
我正在尝试使用 .Net 的 sslStream 类创建 TLS1.1/TLS1.2 服务器。默认情况下,该流接受的唯一密码套件似乎是:
TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256
TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA
TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA
我想启用这些的非 ECDHE 版本(即 TLS_RSA_WITH_AES_128_CBC_SHA256)。我在谷歌上搜索了一下,人们谈论通过修改默认的 SChannel 设置来更改密码套件——通过“SSL 密码套件顺序”或使用 CNG 函数:http://msdn.microsoft.com/en-us/library/windows/desktop/bb870930(v=vs.85).aspx
但是,我试过了,但我什么也做不了。使用上面链接的 C++ 代码列出启用的密码套件与 BCryptEnumContextFunctions()
显示我想要的密码套件在默认情况下已启用。我什至将 TLS_RSA_WITH_AES_128_CBC_SHA256 添加为最高优先级套件,并且 sslStream 仍然拒绝来自仅支持该密码的客户端的 TLS 连接(异常(exception):“客户端和服务器无法通信,因为它们不具备通用算法”)知道什么是发生在这里?
(顺便说一句,如果我的客户支持其中一个 ECDHE 密码套件,一切都很好)
其他人如何在 .Net 4.5 中实现 TLS?我应该看看开源解决方案吗? SChannel 的包装器如何更直接地使用 CNG api?
最佳答案
我联系了 Microsoft 的技术支持,在使用他们专有的跟踪功能后,我发现我在服务器上安装的证书没有将其私钥标记为“交换 key ”。显然,证书库中每个公钥的私钥对应物都有特定的用途,这是允许的。在我的例子中,私钥只允许用于签名,不允许在 SSL/TLS 握手期间用于加密对称 key 。这意味着我的服务器只能支持 ECDHE 密码套件。
事实证明,您无法在证书 MMC 管理单元中检查私钥的启用使用。更糟糕的是,使用 sslStream 类,除了一般异常“客户端和服务器无法通信,因为它们不具备通用算法”之外,也无法确定握手失败的任何信息。
最后要提到的是我最初是如何设法安装带有受限私钥的服务器证书的。原来我是那样生成的。我使用 CertEnroll COM 接口(interface)以编程方式生成我导出的证书签名请求,具有证书颁发机构签名,并安装了证书颁发机构的响应。我用来生成证书签名请求的 C# 代码不小心创建了一个仅供签名使用的私钥。
根据我的经验,CertEnroll 接口(interface)很难使用,而且很难在线找到工作示例。因此,为了其他人的引用,我包括了我的 C# 代码,该代码生成一个 base64 编码的证书签名请求,用于 SSL/TLS 握手。在我的例子中,行 objPrivateKey.KeySpec = X509KeySpec.XCN_AT_KEYEXCHANGE;
丢失了。
using CERTENROLLLib;
using CERTCLILib;
public string GenerateRequest(string Subject, StoreLocation Location)
{
//code originally came from: http://blogs.msdn.com/b/alejacma/archive/2008/09/05/how-to-create-a-certificate-request-with-certenroll-and-net-c.aspx
//modified version of it is here: http://stackoverflow.com/questions/16755634/issue-generating-a-csr-in-windows-vista-cx509certificaterequestpkcs10
//here is the standard for certificates: http://www.ietf.org/rfc/rfc3280.txt
//the PKCS#10 certificate request (http://msdn.microsoft.com/en-us/library/windows/desktop/aa377505.aspx)
CX509CertificateRequestPkcs10 objPkcs10 = new CX509CertificateRequestPkcs10();
//assymetric private key that can be used for encryption (http://msdn.microsoft.com/en-us/library/windows/desktop/aa378921.aspx)
CX509PrivateKey objPrivateKey = new CX509PrivateKey();
//access to the general information about a cryptographic provider (http://msdn.microsoft.com/en-us/library/windows/desktop/aa375967.aspx)
CCspInformation objCSP = new CCspInformation();
//collection on cryptographic providers available: http://msdn.microsoft.com/en-us/library/windows/desktop/aa375967(v=vs.85).aspx
CCspInformations objCSPs = new CCspInformations();
CX500DistinguishedName objDN = new CX500DistinguishedName();
//top level object that enables installing a certificate response http://msdn.microsoft.com/en-us/library/windows/desktop/aa377809.aspx
CX509Enrollment objEnroll = new CX509Enrollment();
CObjectIds objObjectIds = new CObjectIds();
CObjectId objObjectId = new CObjectId();
CObjectId objObjectId2 = new CObjectId();
CX509ExtensionKeyUsage objExtensionKeyUsage = new CX509ExtensionKeyUsage();
CX509ExtensionEnhancedKeyUsage objX509ExtensionEnhancedKeyUsage = new CX509ExtensionEnhancedKeyUsage();
string csr_pem = null;
// Initialize the csp object using the desired Cryptograhic Service Provider (CSP)
objCSPs.AddAvailableCsps();
//Provide key container name, key length and key spec to the private key object
objPrivateKey.ProviderName = providerName;
objPrivateKey.Length = KeyLength;
objPrivateKey.KeySpec = X509KeySpec.XCN_AT_KEYEXCHANGE; //Must flag as XCN_AT_KEYEXCHANGE to use this certificate for exchanging symmetric keys (needed for most SSL cipher suites)
objPrivateKey.KeyUsage = X509PrivateKeyUsageFlags.XCN_NCRYPT_ALLOW_ALL_USAGES;
if (Location == StoreLocation.LocalMachine)
objPrivateKey.MachineContext = true;
else
objPrivateKey.MachineContext = false; //must set this to true if installing to the local machine certificate store
objPrivateKey.ExportPolicy = X509PrivateKeyExportFlags.XCN_NCRYPT_ALLOW_EXPORT_FLAG; //must set this if we want to be able to export it later.
objPrivateKey.CspInformations = objCSPs;
// Create the actual key pair
objPrivateKey.Create();
// Initialize the PKCS#10 certificate request object based on the private key.
// Using the context, indicate that this is a user certificate request and don't
// provide a template name
if (Location == StoreLocation.LocalMachine)
objPkcs10.InitializeFromPrivateKey(X509CertificateEnrollmentContext.ContextMachine, objPrivateKey, "");
else
objPkcs10.InitializeFromPrivateKey(X509CertificateEnrollmentContext.ContextUser, objPrivateKey, "");
//Set hash to sha256
CObjectId hashobj = new CObjectId();
hashobj.InitializeFromAlgorithmName(ObjectIdGroupId.XCN_CRYPT_HASH_ALG_OID_GROUP_ID, ObjectIdPublicKeyFlags.XCN_CRYPT_OID_INFO_PUBKEY_ANY, AlgorithmFlags.AlgorithmFlagsNone, "SHA256");
objPkcs10.HashAlgorithm = hashobj;
// Key Usage Extension -- we only need digital signature and key encipherment for TLS:
// NOTE: in openSSL, I didn't used to request any specific extensions. Instead, I let the CA add them
objExtensionKeyUsage.InitializeEncode(
CERTENROLLLib.X509KeyUsageFlags.XCN_CERT_DIGITAL_SIGNATURE_KEY_USAGE |
CERTENROLLLib.X509KeyUsageFlags.XCN_CERT_KEY_ENCIPHERMENT_KEY_USAGE
);
objPkcs10.X509Extensions.Add((CX509Extension)objExtensionKeyUsage);
// Enhanced Key Usage Extension
objObjectId.InitializeFromValue("1.3.6.1.5.5.7.3.1"); // OID for Server Authentication usage (see this: http://stackoverflow.com/questions/17477279/client-authentication-1-3-6-1-5-5-7-3-2-oid-in-server-certificates)
objObjectId2.InitializeFromValue("1.3.6.1.5.5.7.3.2"); // OID for Client Authentication usage (see this: http://stackoverflow.com/questions/17477279/client-authentication-1-3-6-1-5-5-7-3-2-oid-in-server-certificates)
objObjectIds.Add(objObjectId);
objObjectIds.Add(objObjectId2);
objX509ExtensionEnhancedKeyUsage.InitializeEncode(objObjectIds);
objPkcs10.X509Extensions.Add((CX509Extension)objX509ExtensionEnhancedKeyUsage);
// Encode the name in using the Distinguished Name object
// see here: http://msdn.microsoft.com/en-us/library/windows/desktop/aa379394(v=vs.85).aspx
objDN.Encode(
Subject,
X500NameFlags.XCN_CERT_NAME_STR_SEMICOLON_FLAG
);
// Assign the subject name by using the Distinguished Name object initialized above
objPkcs10.Subject = objDN;
//suppress extra attributes:
objPkcs10.SuppressDefaults = true;
// Create enrollment request
objEnroll.InitializeFromRequest(objPkcs10);
csr_pem = objEnroll.CreateRequest(
EncodingType.XCN_CRYPT_STRING_BASE64
);
csr_pem = "-----BEGIN CERTIFICATE REQUEST-----\r\n" + csr_pem + "-----END CERTIFICATE REQUEST-----";
return csr_pem;
}
关于c# - .NET 4.5 中 sslStream 的密码选择,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22825663/
#include using namespace std; class C{ private: int value; public: C(){ value = 0;
这个问题已经有答案了: What is the difference between char a[] = ?string?; and char *p = ?string?;? (8 个回答) 已关闭
关闭。此题需要details or clarity 。目前不接受答案。 想要改进这个问题吗?通过 editing this post 添加详细信息并澄清问题. 已关闭 7 年前。 此帖子已于 8 个月
除了调试之外,是否有任何针对 c、c++ 或 c# 的测试工具,其工作原理类似于将独立函数复制粘贴到某个文本框,然后在其他文本框中输入参数? 最佳答案 也许您会考虑单元测试。我推荐你谷歌测试和谷歌模拟
我想在第二台显示器中移动一个窗口 (HWND)。问题是我尝试了很多方法,例如将分辨率加倍或输入负值,但它永远无法将窗口放在我的第二台显示器上。 关于如何在 C/C++/c# 中执行此操作的任何线索 最
我正在寻找 C/C++/C## 中不同类型 DES 的现有实现。我的运行平台是Windows XP/Vista/7。 我正在尝试编写一个 C# 程序,它将使用 DES 算法进行加密和解密。我需要一些实
很难说出这里要问什么。这个问题模棱两可、含糊不清、不完整、过于宽泛或夸夸其谈,无法以目前的形式得到合理的回答。如需帮助澄清此问题以便重新打开,visit the help center . 关闭 1
有没有办法强制将另一个 窗口置于顶部? 不是应用程序的窗口,而是另一个已经在系统上运行的窗口。 (Windows, C/C++/C#) 最佳答案 SetWindowPos(that_window_ha
假设您可以在 C/C++ 或 Csharp 之间做出选择,并且您打算在 Windows 和 Linux 服务器上运行同一服务器的多个实例,那么构建套接字服务器应用程序的最明智选择是什么? 最佳答案 如
你们能告诉我它们之间的区别吗? 顺便问一下,有什么叫C++库或C库的吗? 最佳答案 C++ 标准库 和 C 标准库 是 C++ 和 C 标准定义的库,提供给 C++ 和 C 程序使用。那是那些词的共同
下面的测试代码,我将输出信息放在注释中。我使用的是 gcc 4.8.5 和 Centos 7.2。 #include #include class C { public:
很难说出这里问的是什么。这个问题是含糊的、模糊的、不完整的、过于宽泛的或修辞性的,无法以目前的形式得到合理的回答。如需帮助澄清此问题以便重新打开它,visit the help center 。 已关
我的客户将使用名为 annoucement 的结构/类与客户通信。我想我会用 C++ 编写服务器。会有很多不同的类继承annoucement。我的问题是通过网络将这些类发送给客户端 我想也许我应该使用
我在 C# 中有以下函数: public Matrix ConcatDescriptors(IList> descriptors) { int cols = descriptors[0].Co
我有一个项目要编写一个函数来对某些数据执行某些操作。我可以用 C/C++ 编写代码,但我不想与雇主共享该函数的代码。相反,我只想让他有权在他自己的代码中调用该函数。是否可以?我想到了这两种方法 - 在
我使用的是编写糟糕的第 3 方 (C/C++) Api。我从托管代码(C++/CLI)中使用它。有时会出现“访问冲突错误”。这使整个应用程序崩溃。我知道我无法处理这些错误[如果指针访问非法内存位置等,
关闭。这个问题不符合Stack Overflow guidelines .它目前不接受答案。 我们不允许提问寻求书籍、工具、软件库等的推荐。您可以编辑问题,以便用事实和引用来回答。 关闭 7 年前。
已关闭。此问题不符合Stack Overflow guidelines 。目前不接受答案。 要求我们推荐或查找工具、库或最喜欢的场外资源的问题对于 Stack Overflow 来说是偏离主题的,因为
我有一些 C 代码,将使用 P/Invoke 从 C# 调用。我正在尝试为这个 C 函数定义一个 C# 等效项。 SomeData* DoSomething(); struct SomeData {
这个问题已经有答案了: Why are these constructs using pre and post-increment undefined behavior? (14 个回答) 已关闭 6
我是一名优秀的程序员,十分优秀!