【问题标题】:OpenSSL 1.1 get a cipher suite by the IANA IDOpenSSL 1.1 通过 IANA ID 获取密码套件
【发布时间】:2020-08-19 16:56:33
【问题描述】:

在 OpenSSL 1.0.2 中,我们使用了 s3_lib.c 中的 ssl3_get_cipher_by_id() 函数来使用 IANA ID 获取密码套件 (SSL_CIPHER*)。

例如,ID 0x00,0x2F 会将TLS_RSA_WITH_AES_128_CBC_SHA 密码套件作为SSL_CIPHER 结构提供给我们。

但是,1.0.2 及更高版本的 OpenSSL 文档中未列出此功能,虽然该功能在 1.1.1 中仍然可用,但似乎没有为较新的密码套件工作,例如为这两个返回 NULL:

0xC0,0x2F TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256
0xC0,0x14 TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA

我的问题:有没有一种现代方法可以通过其 IANA ID 获取密码套件(SSL_CIPHER 结构)?

我见过this related question,但它没有回答如何从 IANA 十六进制 ID 获取密码套件对象。

注意IANA ID 是指此类页面上的第一个十六进制列:

【问题讨论】:

    标签: c openssl


    【解决方案1】:

    你可以使用 SSL_CIPHER_find(),它

    ... 返回一个 SSL_CIPHER 结构,其密码 ID 存储在 ptr 中。 ptr 参数是一个 char 的二元数组,以网络字节顺序存储两字节的 TLS 密码 ID(由 IANA 分配)。

    https://www.openssl.org/docs/man1.1.1/man3/SSL_CIPHER_find.html

    C 程序

    您的两个示例的 C 代码可能如下所示:

    #include <stdio.h>
    #include <openssl/err.h>
    #include <openssl/ssl.h>
    
    static void print_name(unsigned char iana[], const SSL_CIPHER *cipher);
    
    int main(void) {
        SSL_CTX *ctx = SSL_CTX_new(TLS_client_method());
        SSL *ssl = SSL_new(ctx);
        if (ssl == NULL) {
            ERR_print_errors_fp(stderr);
            exit(1);
        }
    
        unsigned char iana1[] = {0xC0, 0x2F};
        const SSL_CIPHER *cipher = SSL_CIPHER_find(ssl, iana1);
        if (cipher) {
            print_name(iana1, cipher);
        }
    
        unsigned char iana2[] = {0xC0, 0x14};
        cipher = SSL_CIPHER_find(ssl, iana2);
        if (cipher) {
            print_name(iana2, cipher);
        }
        SSL_free(ssl);
        SSL_CTX_free(ctx);
        return 0;
    }
    
    static void print_name(unsigned char iana[], const SSL_CIPHER *cipher) {
        const char *name = SSL_CIPHER_standard_name(cipher);
        if (name == NULL)
            name = "?";
        printf("0x%02X,0x%02X -> %s\n", iana[0], iana[1], name);
    }
    

    测试

    如果你运行上面的程序,你会在调试控制台上得到如下输出:

    0xC0,0x2F -> TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256
    0xC0,0x14 -> TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA
    

    【讨论】:

    • 谢谢,这正是我们所需要的!
    • @NealEastwood 您知道以编程方式获取 IANA ID 密码的方法吗?
    • @Ilyakom 取决于您的起点。如果您已经有一个SSL_CIPHER*,那么您可以检查int SSL_CIPHER_get_cipher_nid(const SSL_CIPHER *c); 的API 描述,看看它是否符合您的要求。避免使用uint32_t SSL_CIPHER_get_id(const SSL_CIPHER *c);,因为“该 ID 与 IANA 特定 ID 不同”。如果您还没有SSL_CIPHER*,则取决于您的数据源。就我而言,它是直接解析包含 TLS 记录的 libpcap 网络数据包,因此我可以直接从数据包中提取密码套件 ID 字节。
    • @NealEastwood 感谢您的回复。这个想法是使用 WinApi 获得支持的密码,然后将它们映射到 OpenSSL 密码。有两种方法,第一种是使用testssl的映射表,第二种是即时执行。第二种方法相当复杂,因为我知道如何获取 Win 密码名称,但不知道如何获取 ID。如果我有 ID,我将能够使用 SSL_CIPHER_find。可能是一个单独的问题。
    猜你喜欢
    • 1970-01-01
    • 2014-11-29
    • 1970-01-01
    • 1970-01-01
    • 2013-10-24
    • 1970-01-01
    • 2015-01-19
    • 1970-01-01
    • 2018-07-06
    相关资源
    最近更新 更多