C# 如何强制CipherSpec使用.net内核从RHEL连接到IBM MQ的特定值。摆脱CompCode:2原因:2059

C# 如何强制CipherSpec使用.net内核从RHEL连接到IBM MQ的特定值。摆脱CompCode:2原因:2059,c#,linux,openssl,ibm-mq,.net-standard-2.0,C#,Linux,Openssl,Ibm Mq,.net Standard 2.0,我们正在尝试连接到IBMMQ服务器V9.1.0.x。来自RHEL 8.3,使用nuget的.net core 3.1和IBMMQDotnetClient 9.2.0.1标准库 我们无法获取CompCode:2原因:2059错误 我们知道原因是什么:在ssl协商过程中,密码规范被设置为TLS_RSA_和_AES_128_CBC_SHA256,但通道被设置为TLS_RSA_和_AES_256_CBC_SHA256。 ERR*.TRC CommentInsert2(带AES的TLS\U RSA\U 2

我们正在尝试连接到IBMMQ服务器V9.1.0.x。来自RHEL 8.3,使用nuget的.net core 3.1和IBMMQDotnetClient 9.2.0.1标准库

我们无法获取CompCode:2原因:2059错误

我们知道原因是什么:在ssl协商过程中,密码规范被设置为TLS_RSA_和_AES_128_CBC_SHA256,但通道被设置为TLS_RSA_和_AES_256_CBC_SHA256。
ERR*.TRC

CommentInsert2(带AES的TLS\U RSA\U 256\U CBC\U SHA256)
CommentInsert3(带AES的TLS\U RSA\U 128\U CBC\U SHA256)
AMQ9631E:SSL握手期间协商的CipherSpec与 通道所需的密码规范

我们在Windows上也遇到了同样的问题,但正在进行
禁用TlsCipherSuite-将TLS\U RSA\U命名为AES\U 128\U CBC\U SHA256
已解决此问题

我们已经做了什么:

  • 我们正在将SSL_CIPHER_SPEC_属性指定为TLS_RSA_WITH_AES_256_CBC_SHA256
  • 不幸的是,它被忽略了,因为我们正在使用托管客户端(MQC.TRANSPORT\u MQSERIES\u managed),它是托管库的唯一有效选项。所有安全调用都传输到内部安全提供程序(Windows上的Schanel/SSL流和Linux上的OpenSsl)。
    我们知道我们应该在Linux上更改密码策略,您知道如何:

  • 在RHEL上禁用TLS\U RSA\U和\U AES\U 128\U CBC\U SHA256
  • 更新
    禁用TlsCipherSuite-名称TLS\U RSA\U WITH_AES\u 128\u CBC\u SHA256
    是一个Powershell cmd

    更新1

    在Linux(RHEL8.3)上,在握手过程中,我的框架如下所示:

        Cipher Suite: TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384 (0xc02c)  
        Cipher Suite: TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 (0xc030)  
        Cipher Suite: TLS_DHE_RSA_WITH_AES_256_GCM_SHA384 (0x009f)  
        Cipher Suite: TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256 (0xcca9)  
        Cipher Suite: TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256 (0xcca8)  
        Cipher Suite: TLS_DHE_RSA_WITH_CHACHA20_POLY1305_SHA256 (0xccaa)  
        Cipher Suite: TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256 (0xc02b)
        Cipher Suite: TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 (0xc02f)
        Cipher Suite: TLS_DHE_RSA_WITH_AES_128_GCM_SHA256 (0x009e)
        Cipher Suite: TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384 (0xc024)
        Cipher Suite: TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384 (0xc028)
        Cipher Suite: TLS_DHE_RSA_WITH_AES_256_CBC_SHA256 (0x006b)
        Cipher Suite: TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256 (0xc023)
        Cipher Suite: TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256 (0xc027)
        Cipher Suite: TLS_DHE_RSA_WITH_AES_128_CBC_SHA256 (0x0067)
        Cipher Suite: TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA (0xc00a)
        Cipher Suite: TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA (0xc014)
        Cipher Suite: TLS_DHE_RSA_WITH_AES_256_CBC_SHA (0x0039)
        Cipher Suite: TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA (0xc009)
        Cipher Suite: TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA (0xc013)
        Cipher Suite: TLS_DHE_RSA_WITH_AES_128_CBC_SHA (0x0033)
        Cipher Suite: TLS_RSA_WITH_AES_256_GCM_SHA384 (0x009d)
        Cipher Suite: TLS_RSA_WITH_AES_128_GCM_SHA256 (0x009c)
        **Cipher Suite: TLS_RSA_WITH_AES_256_CBC_SHA256 (0x003d)**
        **Cipher Suite: TLS_RSA_WITH_AES_128_CBC_SHA256 (0x003c)**
        Cipher Suite: TLS_RSA_WITH_AES_256_CBC_SHA (0x0035)
        Cipher Suite: TLS_RSA_WITH_AES_128_CBC_SHA (0x002f)
        Cipher Suite: TLS_EMPTY_RENEGOTIATION_INFO_SCSV (0x00ff)
    
    
    更新2
    我们设法在协商期间以及MakeSecuredConnection期间强制使用密码。不幸的是,它只能在.NET5.0上实现,需要在MakeSecureConnection中进行黑客攻击。
    我使用.net core 3.1尝试了相同的方法,但失败的原因可能是使用了AuthenticateTasClientAsync

    下面是.NET5.0 IBM MQ Client 9.2.0.1 hack

  • 反编译IBMMQClient(amqmdnetstd.dll)的代码
  • 将.csproj标记为.NET5.0
    NET5.0
  • 在类
    MQEncryptedSocket
    中编辑
    MakeSecureConnection
    方法,如下所示
  • 仅限.NET5.0

    if(!RuntimeInformation.IsOSPlatform(OSPlatform.Linux))
    {
    stream.authenticatesClient(“*”,x509Certificate2Collection,sslProtocol,sslCertRevocationCheck);
    }
    其他的
    {
    //stream.authenticatesClient(“*”,x509Certificate2Collection,sslProtocol,sslCertRevocationCheck);
    var sslClientOptions=新的SslClientAuthenticationOptions()
    {
    CertificateRelocationCheckMode=sslCertRevocationCheck?X509RevocationMode.脱机:X509RevocationMode.NoCheck,
    ClientCertificates=x509Certificate2Collection,
    EnabledSslProtocols=sslProtocol,
    TargetHost=“*”,
    RemoteCertificateValidationCallback=ClientValidatingServerCertificate,
    LocalCertificateSelectionCallback=FixClientCertificate,
    CipherSuite策略=新的CipherSuite策略(新列表(){Enum.Parse(cipherSpec)})
    };
    TrText(方法,$“为AuthenticateTasClient设置密码{string.Join(':',sslClientOptions.CipherSuite.AllowedCipherSuite)}”);
    stream.authenticatesClient(sslClientOptions);
    }
    
    对于.net core 3.1,您必须调用

    stream.authenticatesClientAsync(sslClientOptions);
    
    因为没有方法
    authenticatesClient
    重载接受
    SslClientAuthenticationOptions
    参数。
    .net标准2.0和2.1在类
    SslClientAuthenticationOptions
    中没有CipherSuite策略参数,这就是为什么我必须将库从.net标准2.0移动到.net5.0(成功)和.net core 3.1而不移动的原因。

    您知道如何使其在.net core 3.1上工作吗?

    客户端指定TLS版本,并且TLS版本必须与加密模式兼容()。因此,如果c#没有指定TLS版本,默认版本将在windows中使用(这可能不正确)。因此,您需要在c#client中添加TLS版本:System.Net.ServicePointManager.SecurityProtocol=SecurityProtocolType.Tls12提供了一些详细信息,说明了为什么IBM MQ托管.Net客户端无法像在其他客户端那样对特定密码进行深入分析,它只使用密码来确定要使用的版本(例如TLS1.2),则协商针对所有客户端。除非您修改windows上的策略,否则客户端不允许使用单个密码。如果windows服务器在9.2上,他们可以从服务器提供的最后一个密码中删除AES_128密码,这将迫使协商使用不同的值。是的,您是正确的,客户端将发送完整列表服务器将在其自己的列表中选择第一个备份(我原以为此列表也会发送回客户端)。在MQ v9.1上,服务器端订单禁用TLS1.0(默认情况下)在《代码》中,我们看了一下下面的《代码》下面的《代码》下面的《代码》下面的《代码》下面的《代码》下面的《代码》下面的一些文章,上面的一些文章,上面的一些文章,上面的一些文章,上面的一些文章,上面的一些文章,RSA,RSA,RSA,RSA,RSA,RSA,RSA,RSA,RSA,RSA,RSA,RSA,RSA,有密码,有密码,有密码,有密码,有密码,有密码,RSA,RSA,RSA,RSA,RSA,RSA,有密码,有密码,有密码,有密码,有密码,有密码,有密码,有密码,有密码,有密码,有密码,有密码,有密码,有密码,有密码,有密码,有密码,有密码,有密码,有密码,有密码,有密码有密码,有密码有密码有密码有密码有密码有密码有密码有密码有密码有密码有密码有密码有密码有密码有密码有密码有密码有密码有密码有密码有密码有密码有密码有AES_256_GCM_SHA384。根据该输出和客户端列表,您可以重新接收预期的协商。在MQ v9.2,默认情况下,此列表已从我记忆中重新排序,并且AES_128不再是列表中的第一个,同样在9.2,管理员可以更改顺序和允许的密码。正确,在9.1服务器上,您看到的结果是expec