EDH-RSA-DES-CBC3-SHA的“无共享密码”错误

我想用密码EDH-RSA-DES-CBC3-SHA测试TLS 1.0连接。

我用openssl s_server和s_client测试。 工作良好。 连接和数据交换都很好。

openssl s_server -accept 4433 -cert server.pem -key serverkey.pem -cipher EDH-RSA-DES-CBC3-SHA -tls1

openssl s_client -connect 127.0.0.1:443 -cipher EDH-RSA-DES-CBC3-SHA -tls1

共享密码:EDH-RSA-DES-CBC3-SHA

现在,我有另一个简单的OpenSSL服务器代码。 使用this和s_client连接失败,服务器抛出以下内容:

3077613304:错误:1408A0C1:SSL例程:SSL3_GET_CLIENT_HELLO:无共享密码:s3_srvr.c:1361

我检查s_server / s_client使用的库和我的服务器应用程序使用的库是否相同如下:

cat /proc/9515/maps | awk '{print $6}' | grep '\.so' | sort | uniq | grep -e ssl -e libcrypto

/usr/lib/libcrypto.so.1.0.1e

/usr/lib/libssl.so.1.0.1e

但是, 对于像AES128-SHA这样的其他密码,从s_client到我的服务器应用程序的连接也没问题。

以下是我在服务器代码中设置ctx

 SSL_CTX* InitServerCTX(void) { SSL_CTX *ctx = NULL; SSL_library_init(); OpenSSL_add_all_algorithms(); SSL_load_error_strings(); ctx = SSL_CTX_new(TLSv1_server_method()); SSL_CTX_set_cipher_list(ctx,"EDH-RSA-DES-CBC3-SHA"); // Returns 1 SSL_CTX_use_certificate_chain_file(ctx, "server.pem"); SSL_CTX_use_PrivateKey_file(ctx, "serverkey.pem", SSL_FILETYPE_PEM); return ctx; } 

为什么我的服务器应用程序会抛出“No shared cipher”错误,并且s_server对同一个客户端没问题?

您需要创建一个DH对象并为ssl上下文ctx设置DH参数。 更具体地说,一旦分配了DH对象,就需要设置primp p和generator g。

一种方法是使用下面的示例伪代码

这里dh512_p dh512_g分别是primo p和generator g

 DH* get_dh512(const unsigned char *dh512_p,const unsigned char *dh512_g) { DH *dh=NULL; if ((dh=DH_new()) == NULL) return(NULL); dh->p=BN_bin2bn(dh512_p,sizeof(dh512_p),NULL); dh->g=BN_bin2bn(dh512_g,sizeof(dh512_g),NULL); if ((dh->p == NULL) || (dh->g == NULL)) return(NULL); return(dh); } 

然后使用回调在函数中设置参数

 //if key exchange is based on diffie hellman DH *dh = get_dh512(dh512_p,dh512_g) SSL_CTX_set_tmp_dh(ctx,dh); SSL_CTX_set_cipher_list(ctx,ciphers); 

请查看以下链接以获取回调详细信息http://linux.die.net/man/3/ssl_ctx_set_tmp_dh

@ Cmidid的回答是正确的。 这里有更多信息,包括IETF DH组和通过DH回调选择组大小。

它用C ++编写,但很容易转换回C.

 using DH_ptr = std::unique_ptr; using BIO_MEM_ptr = std::unique_ptr; using BIO_FILE_ptr = std::unique_ptr; using SSL_CTX_ptr = std::unique_ptr; SSL_CTX* CreateServerContext(const string & domain) { const SSL_METHOD* method = SSLv23_server_method(); ASSERT(method != NULL); SSL_CTX_ptr t(SSL_CTX_new(method), ::SSL_CTX_free); ASSERT(t.get() != NULL); long flags = SSL_OP_NO_SSLv2 | SSL_OP_NO_SSLv3; flags |= SSL_OP_NO_COMPRESSION; flags |= SSL_OP_SAFARI_ECDHE_ECDSA_BUG; flags |= SSL_OP_CIPHER_SERVER_PREFERENCE; SSL_CTX_set_options(t.get(), flags); string ciphers = "HIGH:!aNULL:!RC4:!MD5"; rc = SSL_CTX_set_cipher_list(t.get(), ciphers.c_str()); ... LogDebug("GetServerContext: setting DH callback"); SSL_CTX_set_tmp_dh_callback(t.get(), DhCallback); LogDebug("GetServerContext: setting ECDH callback"); SSL_CTX_set_tmp_ecdh_callback(t.get(), EcdhCallback); ... return t.release(); } DH* DhCallback(SSL *ssl, int is_export, int keylength) { UNUSED(ssl); UNUSED(is_export); #if defined(ALLOW_DH_1024_PARAMS) if (keylength <= 1024 + 4) return DH1024(); else #endif if (keylength <= 1536 + 4) return DH1536(); else if (keylength <= 2048 + 4) return DH2048(); else if (keylength <= 3072 + 4) return DH3072(); else if (keylength <= 4096 + 4) return DH4096(); return DH4096(); } #if defined(ALLOW_DH_1024_PARAMS) static DH* DH1024() { static const char g_dh1024_sz[] = "-----BEGIN DH PARAMETERS-----\n" "MIGHAoGBAP//////////yQ/aoiFowjTExmKLgNwc0SkCTgiKZ8x0Agu+pjsTmyJR\n" "Sgh5jjQE3e+VGbPNOkMbMCsKbfJfFDdP4TVtbVHCReSFtXZiXn7G9ExC6aY37WsL\n" "/1y29Aa37e44a/taiZ+lrp8kEXxLH+ZJKGZR7OZTgf//////////AgEC\n" "-----END DH PARAMETERS-----"; static DH_ptr dh(NULL, NULL); if (dh.get()) return dh.get(); BIO_MEM_ptr bio(BIO_new_mem_buf((void*) g_dh1024_sz, (int) sizeof(g_dh1024_sz)), ::BIO_free); ASSERT(bio.get()); dh = DH_ptr(PEM_read_bio_DHparams(bio.get(), NULL, NULL, NULL), ::DH_free); unsigned long err = ERR_get_error(); ASSERT(dh.get()); return dh.get(); } #endif static DH* DH1536() { static const char g_dh1536_sz[] = "-----BEGIN DH PARAMETERS-----\n" "MIHHAoHBAP//////////yQ/aoiFowjTExmKLgNwc0SkCTgiKZ8x0Agu+pjsTmyJR\n" "Sgh5jjQE3e+VGbPNOkMbMCsKbfJfFDdP4TVtbVHCReSFtXZiXn7G9ExC6aY37WsL\n" "/1y29Aa37e44a/taiZ+lrp8kEXxLH+ZJKGZR7ORbPcIAfLihY78FmNpINhxV05pp\n" "Fj+o/STPX4NlXSPco62WHGLzViCFUrue1SkHcJaWbWcMNU5KvJgE8XRsCMojcyf/\n" "/////////wIBAg==\n" "-----END DH PARAMETERS-----"; static DH_ptr dh(NULL, NULL); if (dh.get()) return dh.get(); BIO_MEM_ptr bio(BIO_new_mem_buf((void*) g_dh1536_sz, (int) sizeof(g_dh1536_sz)), ::BIO_free); ASSERT(bio.get()); dh = DH_ptr(PEM_read_bio_DHparams(bio.get(), NULL, NULL, NULL), ::DH_free); unsigned long err = ERR_get_error(); ASSERT(dh.get()); return dh.get(); } static DH* DH2048() { static const char g_dh2048_sz[] = "-----BEGIN DH PARAMETERS-----\n" "MIIBCAKCAQEA///////////JD9qiIWjCNMTGYouA3BzRKQJOCIpnzHQCC76mOxOb\n" "IlFKCHmONATd75UZs806QxswKwpt8l8UN0/hNW1tUcJF5IW1dmJefsb0TELppjft\n" "awv/XLb0Brft7jhr+1qJn6WunyQRfEsf5kkoZlHs5Fs9wgB8uKFjvwWY2kg2HFXT\n" "mmkWP6j9JM9fg2VdI9yjrZYcYvNWIIVSu57VKQdwlpZtZww1Tkq8mATxdGwIyhgh\n" "fDKQXkYuNs474553LBgOhgObJ4Oi7Aeij7XFXfBvTFLJ3ivL9pVYFxg5lUl86pVq\n" "5RXSJhiY+gUQFXKOWoqsqmj//////////wIBAg==\n" "-----END DH PARAMETERS-----"; static DH_ptr dh(NULL, NULL); if (dh.get()) return dh.get(); BIO_MEM_ptr bio(BIO_new_mem_buf((void*) g_dh2048_sz, (int) sizeof(g_dh2048_sz)), ::BIO_free); ASSERT(bio.get()); dh = DH_ptr(PEM_read_bio_DHparams(bio.get(), NULL, NULL, NULL), ::DH_free); unsigned long err = ERR_get_error(); ASSERT(dh.get()); return dh.get(); } static DH* DH3072() { static const char g_dh3072_sz[] = "-----BEGIN DH PARAMETERS-----\n" "MIIBiAKCAYEA///////////JD9qiIWjCNMTGYouA3BzRKQJOCIpnzHQCC76mOxOb\n" "IlFKCHmONATd75UZs806QxswKwpt8l8UN0/hNW1tUcJF5IW1dmJefsb0TELppjft\n" "awv/XLb0Brft7jhr+1qJn6WunyQRfEsf5kkoZlHs5Fs9wgB8uKFjvwWY2kg2HFXT\n" "mmkWP6j9JM9fg2VdI9yjrZYcYvNWIIVSu57VKQdwlpZtZww1Tkq8mATxdGwIyhgh\n" "fDKQXkYuNs474553LBgOhgObJ4Oi7Aeij7XFXfBvTFLJ3ivL9pVYFxg5lUl86pVq\n" "5RXSJhiY+gUQFXKOWoqqxC2tMxcNBFB6M6hVIavfHLpk7PuFBFjb7wqK6nFXXQYM\n" "fbOXD4Wm4eTHq/WujNsJM9cejJTgSiVhnc7j0iYa0u5r8S/6BtmKCGTYdgJzPshq\n" "ZFIfKxgXeyAMu+EXV3phXWx3CYjAutlG4gjiT6B05asxQ9tb/OD9EI5LgtEgqTrS\n" "yv//////////AgEC\n" "-----END DH PARAMETERS-----"; static DH_ptr dh(NULL, NULL); if (dh.get()) return dh.get(); BIO_MEM_ptr bio(BIO_new_mem_buf((void*) g_dh3072_sz, (int) sizeof(g_dh3072_sz)), ::BIO_free); ASSERT(bio.get()); dh = DH_ptr(PEM_read_bio_DHparams(bio.get(), NULL, NULL, NULL), ::DH_free); unsigned long err = ERR_get_error(); ASSERT(dh.get()); return dh.get(); } static DH* DH4096() { static const char g_dh4096_sz[] = "-----BEGIN DH PARAMETERS-----\n" "MIICCAKCAgEA///////////JD9qiIWjCNMTGYouA3BzRKQJOCIpnzHQCC76mOxOb\n" "IlFKCHmONATd75UZs806QxswKwpt8l8UN0/hNW1tUcJF5IW1dmJefsb0TELppjft\n" "awv/XLb0Brft7jhr+1qJn6WunyQRfEsf5kkoZlHs5Fs9wgB8uKFjvwWY2kg2HFXT\n" "mmkWP6j9JM9fg2VdI9yjrZYcYvNWIIVSu57VKQdwlpZtZww1Tkq8mATxdGwIyhgh\n" "fDKQXkYuNs474553LBgOhgObJ4Oi7Aeij7XFXfBvTFLJ3ivL9pVYFxg5lUl86pVq\n" "5RXSJhiY+gUQFXKOWoqqxC2tMxcNBFB6M6hVIavfHLpk7PuFBFjb7wqK6nFXXQYM\n" "fbOXD4Wm4eTHq/WujNsJM9cejJTgSiVhnc7j0iYa0u5r8S/6BtmKCGTYdgJzPshq\n" "ZFIfKxgXeyAMu+EXV3phXWx3CYjAutlG4gjiT6B05asxQ9tb/OD9EI5LgtEgqSEI\n" "ARpyPBKnh+bXiHGaEL26WyaZwycYavTiPBqUaDS2FQvaJYPpyirUTOjbu8LbBN6O\n" "+S6O/BQfvsqmKHxZR05rwF2ZspZPoJDDoiM7oYZRW+ftH2EpcM7i16+4G912IXBI\n" "HNAGkSfVsFqpk7TqmI2P3cGG/7fckKbAj030Nck0BjGZ//////////8CAQI=\n" "-----END DH PARAMETERS-----"; static DH_ptr dh(NULL, NULL); if (dh.get()) return dh.get(); BIO_MEM_ptr bio(BIO_new_mem_buf((void*) g_dh4096_sz, (int) sizeof(g_dh4096_sz)), ::BIO_free); ASSERT(bio.get()); dh = DH_ptr(PEM_read_bio_DHparams(bio.get(), NULL, NULL, NULL), ::DH_free); unsigned long err = ERR_get_error(); ASSERT(dh.get()); return dh.get(); }