diff --git a/dap-sdk/core/include/dap_common.h b/dap-sdk/core/include/dap_common.h
index ea2a41ab94901868dd8158c9735d2825258a9821..3b58cda9e5d68d7ae879194037bd8b88d4e60c32 100755
--- a/dap-sdk/core/include/dap_common.h
+++ b/dap-sdk/core/include/dap_common.h
@@ -160,7 +160,13 @@ DAP_STATIC_INLINE void _dap_aligned_free( void *ptr )
     DAP_FREE( base_ptr );
 }
 
-#define DAP_PROTOCOL_VERSION  22
+/*
+ * 23: added support for encryption key type parameter and option to encrypt headers
+*/
+#define DAP_PROTOCOL_VERSION          23
+#define DAP_PROTOCOL_VERSION_DEFAULT  22 // used if version is not explicitly specified
+
+#define DAP_CLIENT_PROTOCOL_VERSION   23
 
 #if __SIZEOF_LONG__==8
 #define DAP_UINT64_FORMAT_X  "lX"
diff --git a/dap-sdk/crypto/include/dap_enc_key.h b/dap-sdk/crypto/include/dap_enc_key.h
index 7ef187742ec71e45813da67a55d286cddee647b0..42711803e73cfa8bc21d79d8a920723224cbeb79 100755
--- a/dap-sdk/crypto/include/dap_enc_key.h
+++ b/dap-sdk/crypto/include/dap_enc_key.h
@@ -43,7 +43,7 @@ typedef enum dap_enc_data_type{DAP_ENC_DATA_TYPE_RAW,
 
 typedef enum dap_enc_key_type{
 
-
+                           DAP_ENC_KEY_TYPE_INVALID = -1,
                            DAP_ENC_KEY_TYPE_IAES, // Symmetric AES
                            DAP_ENC_KEY_TYPE_OAES,// from https://github.com/monero-project/monero/tree/master/src/crypto
 
@@ -123,7 +123,8 @@ typedef enum dap_enc_key_type{
 
                            DAP_ENC_KEY_TYPE_SIG_RINGCT20,//ring signature for confidentional transaction
 
-                           DAP_ENC_KEY_TYPE_NULL = 0
+                           DAP_ENC_KEY_TYPE_LAST = DAP_ENC_KEY_TYPE_SIG_RINGCT20,
+                           DAP_ENC_KEY_TYPE_NULL = 0 // avoid using it: 0 is a DAP_ENC_KEY_TYPE_NULL and DAP_ENC_KEY_TYPE_IAES at the same time
 
                          }  dap_enc_key_type_t;
 
@@ -244,6 +245,7 @@ int dap_enc_key_init(void);
 void dap_enc_key_deinit(void);
 
 const char *dap_enc_get_type_name(dap_enc_key_type_t a_key_type);
+dap_enc_key_type_t dap_enc_key_type_find_by_name(const char * a_name);
 size_t dap_enc_key_get_enc_size(dap_enc_key_t * a_key, const size_t buf_in_size);
 size_t dap_enc_key_get_dec_size(dap_enc_key_t * a_key, const size_t buf_in_size);
 
diff --git a/dap-sdk/crypto/src/dap_enc_key.c b/dap-sdk/crypto/src/dap_enc_key.c
index 95b9c89200f6f94124a1657e9cc882b54fd6bebf..69aac3100950811fae7b7f007c85abaad88e5b2e 100755
--- a/dap-sdk/crypto/src/dap_enc_key.c
+++ b/dap-sdk/crypto/src/dap_enc_key.c
@@ -837,7 +837,18 @@ const char *dap_enc_get_type_name(dap_enc_key_type_t a_key_type)
     if(s_callbacks[a_key_type].name) {
         return s_callbacks[a_key_type].name;
     }
-    log_it(L_ERROR, "name not realize for current key type");
+    log_it(L_WARNING, "name was not set for key type %d", a_key_type);
     return 0;
 
 }
+
+dap_enc_key_type_t dap_enc_key_type_find_by_name(const char * a_name){
+    for(dap_enc_key_type_t i = 0; i <= DAP_ENC_KEY_TYPE_LAST; i++){
+        const char * l_current_key_name = dap_enc_get_type_name(i);
+        if(l_current_key_name && !strcmp(a_name, l_current_key_name))
+            return i;
+    }
+    log_it(L_WARNING, "no key type with name %s", a_name);
+    return DAP_ENC_KEY_TYPE_INVALID;
+}
+
diff --git a/dap-sdk/net/client/dap_client_pvt.c b/dap-sdk/net/client/dap_client_pvt.c
index 59a52c01f98d95256170fcc41b950340ddafb383..3e6c98f74b689d701f00a373bd031505889115fe 100644
--- a/dap-sdk/net/client/dap_client_pvt.c
+++ b/dap-sdk/net/client/dap_client_pvt.c
@@ -79,6 +79,8 @@
 
 static void s_stage_status_after(dap_client_pvt_t * a_client_internal);
 
+const static dap_enc_key_type_t s_dap_client_pvt_preferred_encryption_type = DAP_ENC_KEY_TYPE_IAES;
+
 // ENC stage callbacks
 void m_enc_init_response(dap_client_t *, void *, size_t);
 void m_enc_init_error(dap_client_t *, int);
@@ -438,7 +440,17 @@ static void s_stage_status_after(dap_client_pvt_t * a_client_pvt)
             log_it(L_DEBUG, "STREAM_CTL request size %u", strlen(l_request));
 
             char *l_suburl;
-            l_suburl = dap_strdup_printf("stream_ctl,channels=%s", a_client_pvt->active_channels);
+
+            uint32_t l_least_common_dap_protocol = min(a_client_pvt->remote_protocol_version,
+                                                       a_client_pvt->uplink_protocol_version);
+
+            if(l_least_common_dap_protocol < 23){
+                l_suburl = dap_strdup_printf("stream_ctl,channels=%s",
+                                             a_client_pvt->active_channels);
+            }else{
+                l_suburl = dap_strdup_printf("stream_ctl,channels=%s,enc_type=%d,enc_headers=%d",
+                                             a_client_pvt->active_channels,s_dap_client_pvt_preferred_encryption_type,0);
+            }
             //
             dap_client_pvt_request_enc(a_client_pvt,
             DAP_UPLINK_PATH_STREAM_CTL,
@@ -954,13 +966,22 @@ void m_enc_init_response(dap_client_t * a_client, void * a_response, size_t a_re
                         json_parse_count++;
                     }
                 }
+                if(json_object_get_type(val) == json_type_int) {
+                    int val_int = (uint32_t)json_object_get_int(val);
+                    if(!strcmp(key, "dap_protocol_version")) {
+                        l_client_pvt->remote_protocol_version = val_int;
+                        json_parse_count++;
+                    }
+                }
             }
             // free jobj
             json_object_put(jobj);
+            if(!l_client_pvt->remote_protocol_version)
+                l_client_pvt->remote_protocol_version = DAP_PROTOCOL_VERSION_DEFAULT;
         }
         //char l_session_id_b64[DAP_ENC_BASE64_ENCODE_SIZE(DAP_ENC_KS_KEY_ID_SIZE) + 1] = { 0 };
         //char *l_bob_message_b64 = DAP_NEW_Z_SIZE(char, a_response_size - sizeof(l_session_id_b64) + 1);
-        if(json_parse_count == 2) { //if (sscanf (a_response,"%s %s",l_session_id_b64, l_bob_message_b64) == 2 ){
+        if(json_parse_count >= 2 && json_parse_count <=3) { //if (sscanf (a_response,"%s %s",l_session_id_b64, l_bob_message_b64) == 2 ){
             l_client_pvt->session_key_id = DAP_NEW_Z_SIZE(char, strlen(l_session_id_b64) + 1);
             dap_enc_base64_decode(l_session_id_b64, strlen(l_session_id_b64),
                     l_client_pvt->session_key_id, DAP_ENC_DATA_TYPE_B64);
@@ -1059,14 +1080,14 @@ void m_stream_ctl_response(dap_client_t * a_client, void * a_data, size_t a_data
         s_stage_status_after(l_client_internal);
     } else {
         int l_arg_count;
-        char l_stream_id[25] = { 0 };
+        char l_stream_id[26] = { 0 };
         char *l_stream_key = DAP_NEW_Z_SIZE(char, 4096 * 3);
-        void * l_stream_key_raw = DAP_NEW_Z_SIZE(char, 4096);
-        size_t l_stream_key_raw_size = 0;
         uint32_t l_remote_protocol_version;
+        dap_enc_key_type_t l_enc_type = DAP_ENC_KEY_TYPE_OAES;
+        int l_enc_headers = 0;
 
-        l_arg_count = sscanf(l_response_str, "%25s %4096s %u"
-                , l_stream_id, l_stream_key, &l_remote_protocol_version);
+        l_arg_count = sscanf(l_response_str, "%25s %4096s %u %d %d"
+                , l_stream_id, l_stream_key, &l_remote_protocol_version, &l_enc_type, &l_enc_headers);
         if(l_arg_count < 2) {
             log_it(L_WARNING, "STREAM_CTL Need at least 2 arguments in reply (got %d)", l_arg_count);
             l_client_internal->last_error = ERROR_STREAM_CTL_ERROR_RESPONSE_FORMAT;
@@ -1078,8 +1099,8 @@ void m_stream_ctl_response(dap_client_t * a_client, void * a_data, size_t a_data
                 l_client_internal->uplink_protocol_version = l_remote_protocol_version;
                 log_it(L_DEBUG, "Uplink protocol version %u", l_remote_protocol_version);
             } else
-                log_it(L_WARNING, "No uplink protocol version, use the default version %d"
-                        , l_client_internal->uplink_protocol_version = DAP_PROTOCOL_VERSION);
+                log_it(L_WARNING, "No uplink protocol version, use legacy version %d"
+                        , l_client_internal->uplink_protocol_version = 22);
 
             if(strlen(l_stream_id) < 13) {
                 //log_it(L_DEBUG, "Stream server id %s, stream key length(base64 encoded) %u"
@@ -1087,17 +1108,17 @@ void m_stream_ctl_response(dap_client_t * a_client, void * a_data, size_t a_data
                 log_it(L_DEBUG, "Stream server id %s, stream key '%s'"
                         , l_stream_id, l_stream_key);
 
-                //l_stream_key_raw_size = dap_enc_base64_decode(l_stream_key,strlen(l_stream_key),
-                //                                             l_stream_key_raw,DAP_ENC_DATA_TYPE_B64);
                 // Delete old key if present
                 if(l_client_internal->stream_key)
                     dap_enc_key_delete(l_client_internal->stream_key);
 
                 strncpy(l_client_internal->stream_id, l_stream_id, sizeof(l_client_internal->stream_id) - 1);
                 l_client_internal->stream_key =
-                        dap_enc_key_new_generate(DAP_ENC_KEY_TYPE_OAES, l_stream_key, strlen(l_stream_key), NULL, 0,
+                        dap_enc_key_new_generate(l_enc_type, l_stream_key, strlen(l_stream_key), NULL, 0,
                                 32);
 
+                l_client_internal->encrypted_headers = l_enc_headers;
+
                 if(l_client_internal->stage == STAGE_STREAM_CTL) { // We are on the right stage
                     l_client_internal->stage_status = STAGE_STATUS_DONE;
                     s_stage_status_after(l_client_internal);
@@ -1115,7 +1136,6 @@ void m_stream_ctl_response(dap_client_t * a_client, void * a_data, size_t a_data
 
         }
         DAP_DELETE(l_stream_key);
-        DAP_DELETE(l_stream_key_raw);
     }
 }
 
diff --git a/dap-sdk/net/client/include/dap_client.h b/dap-sdk/net/client/include/dap_client.h
index ff2ec55fda9f9da9f5c6bb2226d49bf4b915af18..316a31547c6d5b6376f8cb431f626ddc54fd8661 100644
--- a/dap-sdk/net/client/include/dap_client.h
+++ b/dap-sdk/net/client/include/dap_client.h
@@ -66,8 +66,6 @@ typedef enum dap_client_error {
     ERROR_NETWORK_CONNECTION_TIMEOUT
 } dap_client_error_t;
 
-#define DAP_CLIENT_PROTOCOL_VERSION 22
-
 /**
  * @brief The dap_client struct
  */
diff --git a/dap-sdk/net/client/include/dap_client_pvt.h b/dap-sdk/net/client/include/dap_client_pvt.h
index 6966a2cf5f3bef2125ef8189d035df71dccbf556..c3c97473ebd5328b4a586cd05929e844383db086 100644
--- a/dap-sdk/net/client/include/dap_client_pvt.h
+++ b/dap-sdk/net/client/include/dap_client_pvt.h
@@ -60,7 +60,7 @@ typedef struct dap_client_internal
     char * active_channels;
     uint16_t uplink_port;
     uint32_t uplink_protocol_version;
-
+    uint32_t remote_protocol_version;
 
     dap_client_stage_t stage_target;
     dap_client_callback_t stage_target_done_callback;
@@ -77,6 +77,7 @@ typedef struct dap_client_internal
     int connect_attempt;
 
     bool is_encrypted;
+    bool encrypted_headers;
     bool is_reconnect;
     bool is_close_session;// the last request in session, in the header will be added "SessionCloseAfterRequest: true"
     dap_client_callback_data_size_t request_response_callback;
diff --git a/dap-sdk/net/server/enc_server/dap_enc_http.c b/dap-sdk/net/server/enc_server/dap_enc_http.c
index eabc22b6f6c1fa57f3781f051c181a719824cc5f..d8db585694eb6436166931bfcef48028aef3273f 100644
--- a/dap-sdk/net/server/enc_server/dap_enc_http.c
+++ b/dap-sdk/net/server/enc_server/dap_enc_http.c
@@ -75,6 +75,7 @@ static void _enc_http_write_reply(struct dap_http_simple *cl_st,
     struct json_object *jobj = json_object_new_object();
     json_object_object_add(jobj, "encrypt_id", json_object_new_string(encrypt_id));
     json_object_object_add(jobj, "encrypt_msg", json_object_new_string(encrypt_msg));
+    json_object_object_add(jobj, "dap_protocol_version", json_object_new_int(DAP_PROTOCOL_VERSION));
     const char* json_str = json_object_to_json_string(jobj);
     dap_http_simple_reply(cl_st, (void*) json_str,
                           (size_t) strlen(json_str));
diff --git a/dap-sdk/net/stream/stream/dap_stream_ctl.c b/dap-sdk/net/stream/stream/dap_stream_ctl.c
index ef5d72345ae8dbb122417fbf8f92a739da045fd1..696b0eb0961140db9a536c87be284fee781715a4 100644
--- a/dap-sdk/net/stream/stream/dap_stream_ctl.c
+++ b/dap-sdk/net/stream/stream/dap_stream_ctl.c
@@ -69,17 +69,30 @@ static struct {
     dap_enc_key_type_t type;
 } s_socket_forward_key;
 
+static const dap_enc_key_type_t s_dap_stream_default_preferred_encryption = DAP_ENC_KEY_TYPE_IAES;
 
 /**
  * @brief stream_ctl_init Initialize stream control module
  * @return Zero if ok others if not
  */
-int dap_stream_ctl_init(dap_enc_key_type_t socket_forward_key_type,
+int dap_stream_ctl_init(dap_config_t * a_config,
                         size_t socket_forward_key_size)
 {
-    s_socket_forward_key.type = socket_forward_key_type;
     s_socket_forward_key.size = socket_forward_key_size;
-    log_it(L_NOTICE,"Initialized stream control module");
+
+    const char *l_preferred_encryption_name = dap_config_get_item_str(a_config, "stream", "preferred_encryption");
+    if(!l_preferred_encryption_name){
+        s_socket_forward_key.type = s_dap_stream_default_preferred_encryption;
+    }else{
+        dap_enc_key_type_t l_found_key_type = dap_enc_key_type_find_by_name(l_preferred_encryption_name);
+
+        if(l_found_key_type != DAP_ENC_KEY_TYPE_INVALID)
+            s_socket_forward_key.type = l_found_key_type;
+        else
+            s_socket_forward_key.type = s_dap_stream_default_preferred_encryption;
+    }
+
+    log_it(L_NOTICE,"Initialized stream control module: ecryption type is set to %s", dap_enc_get_type_name(s_socket_forward_key.type));
     return 0;
 }
 
@@ -121,17 +134,20 @@ void s_proc(struct dap_http_simple *a_http_simple, void * a_arg)
     if(l_dg){
         size_t l_channels_str_size = sizeof(ss->active_channels);
         char l_channels_str[sizeof(ss->active_channels)];
-        if(l_dg->url_path && strlen(l_dg->url_path) < 30 &&
-                sscanf(l_dg->url_path, "stream_ctl,channels=%s", l_channels_str) == 1) {
+        dap_enc_key_type_t l_enc_type = s_socket_forward_key.type;
+        int l_enc_headers;
+        int l_url_sscanf_res = sscanf(l_dg->url_path, "stream_ctl,channels=%16s,enc_type=%d,enc_headers=%d", l_channels_str, &l_enc_type, &l_enc_headers);
+        if(l_url_sscanf_res > 0){
+            if(l_url_sscanf_res < 3){
+                log_it(L_INFO, "legacy encryption mode used (OAES)");
+                l_enc_type = DAP_ENC_KEY_TYPE_OAES;
+            }
             l_new_session = true;
         }
         else if(strcmp(l_dg->url_path, "socket_forward" ) == 0) {
             l_channels_str[0]  = '\0';
             l_new_session = true;
         }
-        /* }else if (strcmp(dg->url_path,"stream_ctl")==0) {
-            l_new_session = true;
-        }*/
         else{
             log_it(L_ERROR,"ctl command unknown: %s",l_dg->url_path);
             enc_http_delegate_delete(l_dg);
@@ -144,7 +160,7 @@ void s_proc(struct dap_http_simple *a_http_simple, void * a_arg)
             strncpy(ss->active_channels, l_channels_str, l_channels_str_size);
             char *key_str = calloc(1, KEX_KEY_STR_SIZE+1);
             dap_random_string_fill(key_str, KEX_KEY_STR_SIZE);
-            ss->key = dap_enc_key_new_generate( s_socket_forward_key.type, key_str, KEX_KEY_STR_SIZE,
+            ss->key = dap_enc_key_new_generate( l_enc_type, key_str, KEX_KEY_STR_SIZE,
                                                NULL, 0, s_socket_forward_key.size);
             dap_http_header_t *l_hdr_key_id = dap_http_header_find(a_http_simple->http_client->in_headers, "KeyID");
             if (l_hdr_key_id) {
@@ -156,7 +172,7 @@ void s_proc(struct dap_http_simple *a_http_simple, void * a_arg)
                 }
                 ss->acl = l_ks_key->acl_list;
             }
-            enc_http_reply_f(l_dg,"%u %s",ss->id,key_str);
+            enc_http_reply_f(l_dg,"%u %s %u %d %d",ss->id, key_str, DAP_PROTOCOL_VERSION, l_enc_type, l_enc_headers);
             *return_code = Http_Status_OK;
 
             log_it(L_INFO," New stream session %u initialized",ss->id);
diff --git a/dap-sdk/net/stream/stream/include/dap_stream_ctl.h b/dap-sdk/net/stream/stream/include/dap_stream_ctl.h
index 56fe6e995554b46dbe186ffb0906712194979452..ff5f7369beb1059147aac173f5afe28437a96be3 100644
--- a/dap-sdk/net/stream/stream/include/dap_stream_ctl.h
+++ b/dap-sdk/net/stream/stream/include/dap_stream_ctl.h
@@ -21,11 +21,12 @@
 #pragma once
 
 #include "dap_enc.h"
+#include "dap_config.h"
 typedef struct dap_http dap_http_t;
 #define KEX_KEY_STR_SIZE 128
 
 
-int dap_stream_ctl_init(dap_enc_key_type_t socket_forward_key_type,
+int dap_stream_ctl_init(dap_config_t * a_config,
                         size_t socket_forward_key_size);
 void dap_stream_ctl_deinit();
 void dap_stream_ctl_add_proc(struct dap_http * sh, const char * url);