diff --git a/include/opendht/dht_proxy_server.h b/include/opendht/dht_proxy_server.h
index 8be073ac958af602eeb7f41acb050f40d9ae587e..c98ca30dcb88ca42f6bf51f9a1a8321c52d6bccc 100644
--- a/include/opendht/dht_proxy_server.h
+++ b/include/opendht/dht_proxy_server.h
@@ -31,7 +31,11 @@
 
 #include <memory>
 #include <mutex>
+
 #include <restinio/all.hpp>
+#ifdef OPENDHT_PROXY_OPENSSL
+#include <restinio/tls.hpp>
+#endif
 #include "http.h"
 
 #ifdef OPENDHT_JSONCPP
@@ -51,7 +55,12 @@ namespace restinio {
 }
 
 using RestRouter = restinio::router::express_router_t<>;
+
+#ifdef OPENDHT_PROXY_OPENSSL
+struct RestRouterTraits : public restinio::default_tls_traits_t
+#else
 struct RestRouterTraits : public restinio::default_traits_t
+#endif
 {
     using timer_manager_t = restinio::asio_timer_manager_t;
     using http_methods_mapper_t = restinio::custom_http_methods_t;
@@ -88,10 +97,10 @@ public:
      */
     DhtProxyServer(
 #ifdef OPENDHT_PROXY_OPENSSL
-                   dht::crypto::Identity& identity,
+       dht::crypto::Identity& identity,
 #endif
-                   std::shared_ptr<DhtRunner> dht, in_port_t port = 8000,
-                   const std::string& pushServer = "", std::shared_ptr<dht::Logger> logger = {});
+       std::shared_ptr<DhtRunner> dht, in_port_t port = 8000, const std::string& pushServer = "",
+       std::shared_ptr<dht::Logger> logger = {});
 
     virtual ~DhtProxyServer();
 
@@ -337,6 +346,10 @@ private:
     // http server
     std::thread httpServerThread_;
     std::unique_ptr<restinio::http_server_t<RestRouterTraits>> httpServer_;
+#ifdef OPENDHT_PROXY_OPENSSL
+    std::unique_ptr<const asio::const_buffer> pk_;
+    std::unique_ptr<const asio::const_buffer> cc_;
+#endif
 
     // http client
     std::pair<std::string, std::string> pushHostPort_;
diff --git a/src/dht_proxy_server.cpp b/src/dht_proxy_server.cpp
index 8db78805b8217880d6d428cb38fb9be690673e3f..977952ab52f76582faae45e8e6c01e6f50072d98 100644
--- a/src/dht_proxy_server.cpp
+++ b/src/dht_proxy_server.cpp
@@ -48,15 +48,14 @@ constexpr const std::chrono::minutes PRINT_STATS_PERIOD {2};
 
 DhtProxyServer::DhtProxyServer(
 #ifdef OPENDHT_PROXY_OPENSSL
-                               dht::crypto::Identity& identity,
+    dht::crypto::Identity& identity,
 #endif
-                               std::shared_ptr<DhtRunner> dht, in_port_t port,
-                               const std::string& pushServer, std::shared_ptr<dht::Logger> logger
+    std::shared_ptr<DhtRunner> dht, in_port_t port, const std::string& pushServer,
+    std::shared_ptr<dht::Logger> logger
 ):
         dht_(dht), logger_(logger), lockListener_(std::make_shared<std::mutex>()),
         listeners_(std::make_shared<std::map<restinio::connection_id_t, http::ListenerSession>>()),
-        connListener_(std::make_shared<http::ConnectionListener>(
-                        dht, listeners_, lockListener_, logger)),
+        connListener_(std::make_shared<http::ConnectionListener>(dht, listeners_, lockListener_, logger)),
         pushServer_(pushServer)
 {
     if (not dht_)
@@ -80,6 +79,33 @@ DhtProxyServer::DhtProxyServer(
     // build http server
     auto settings = makeHttpServerSettings();
     settings.port(port);
+
+#ifdef OPENDHT_PROXY_OPENSSL
+    // define tls context
+    asio::ssl::context tls_context { asio::ssl::context::sslv23 };
+    tls_context.set_options(asio::ssl::context::default_workarounds
+                            | asio::ssl::context::no_sslv2
+                            | asio::ssl::context::single_dh_use);
+    // save keys in memory & set in tls context
+    asio::error_code ec;
+    // node private key
+    auto pk = identity.first->serialize(); // returns Blob
+    pk_ = std::make_unique<const asio::const_buffer>(static_cast<void*>(pk.data()),
+                                                    (std::size_t) pk.size());
+    tls_context.use_private_key(*pk_, asio::ssl::context::file_format::pem, ec);
+    if (ec)
+        throw std::runtime_error("Error setting Node private key: " + ec.message());
+    // certificate chain
+    auto cc = identity.second->toString(true/*chain*/);
+    auto ccb = dht::Blob(cc.begin(), cc.end());
+    cc_ = std::make_unique<const asio::const_buffer>(static_cast<void*>(ccb.data()),
+                                                    (std::size_t) ccb.size());
+    tls_context.use_certificate_chain(*cc_, ec);
+    if (ec)
+        throw std::runtime_error("Error setting CA chain file: " + ec.message());
+    settings.tls_context(std::move(tls_context));
+#endif
+
     httpServer_.reset(new restinio::http_server_t<RestRouterTraits>(
         restinio::own_io_context(),
         std::forward<ServerSettings>(settings)
diff --git a/tests/dhtproxytester.cpp b/tests/dhtproxytester.cpp
index 459cffc4ce6b08e4a4a5469c8402a86b15384eb1..98bf654f1096e22e81c4925dda11f4e2681dc83f 100644
--- a/tests/dhtproxytester.cpp
+++ b/tests/dhtproxytester.cpp
@@ -41,15 +41,17 @@ DhtProxyTester::setUp() {
     nodeProxy->run(0, /*identity*/{}, /*threaded*/true);
     nodeProxy->bootstrap(nodePeer.getBound());
 
-#ifdef OPENDHT_PUSH_NOTIFICATIONS
-    auto ca_tmp = dht::crypto::generateEcIdentity("DHT Node CA");
-    serverIdentity = dht::crypto::generateIdentity("DHT Node", ca_tmp);
+#ifdef OPENDHT_PROXY_OPENSSL
+    serverCAIdentity = std::make_unique<dht::crypto::Identity>(
+        dht::crypto::generateEcIdentity("DHT Node CA"));
+    serverIdentity = std::make_unique<dht::crypto::Identity>(
+        dht::crypto::generateIdentity("DHT Node", *serverCAIdentity));
 #endif
 
     serverProxy = std::unique_ptr<dht::DhtProxyServer>(
         new dht::DhtProxyServer(
 #ifdef OPENDHT_PUSH_NOTIFICATIONS
-            serverIdentity,
+            *serverIdentity,
 #endif
             nodeProxy, 8080, /*pushServer*/"127.0.0.1:8090", logger));
 
diff --git a/tests/dhtproxytester.h b/tests/dhtproxytester.h
index a5078b7eae1db122449084a634446e15b9f68753..5739235d6bf83f8d500e583773f1ff2a15b98e42 100644
--- a/tests/dhtproxytester.h
+++ b/tests/dhtproxytester.h
@@ -68,7 +68,8 @@ class DhtProxyTester : public CppUnit::TestFixture {
     std::shared_ptr<dht::DhtRunner> nodeProxy;
 
 #ifdef OPENDHT_PUSH_NOTIFICATIONS
-    dht::crypto::Identity serverIdentity;
+    std::unique_ptr<dht::crypto::Identity> serverIdentity;
+    std::unique_ptr<dht::crypto::Identity> serverCAIdentity;
 #endif
     std::unique_ptr<dht::DhtProxyServer> serverProxy;
 
diff --git a/tools/dhtnode.cpp b/tools/dhtnode.cpp
index 6bef49e3d91ef2ae4feb6f08aaf1bd8edee24dba..197515cce94849d10c6ba99daa4e58e7d0eff062 100644
--- a/tools/dhtnode.cpp
+++ b/tools/dhtnode.cpp
@@ -228,7 +228,7 @@ void cmd_loop(std::shared_ptr<DhtRunner>& node, dht_params& params
                 proxies.emplace(port, std::unique_ptr<DhtProxyServer>(
                     new DhtProxyServer(
 #ifdef OPENDHT_PROXY_OPENSSL
-                        params.id, /* dht::crypto::Identity */
+                        params.id,
 #endif
                         node, port
 #ifdef OPENDHT_PUSH_NOTIFICATIONS
@@ -512,16 +512,19 @@ main(int argc, char **argv)
     setupSignals();
 
     auto node = std::make_shared<DhtRunner>();
-
     try {
+#ifndef OPENDHT_PROXY_SERVER
         if (not params.id.first and params.generate_identity) {
-            auto ca_tmp = dht::crypto::generateEcIdentity("DHT Node CA");
-            params.id = dht::crypto::generateIdentity("DHT Node", ca_tmp);
+#endif
+            auto node_ca = std::make_unique<dht::crypto::Identity>(dht::crypto::generateEcIdentity("DHT Node CA"));
+            params.id = dht::crypto::generateIdentity("DHT Node", *node_ca);
             if (not params.save_identity.empty()) {
-                dht::crypto::saveIdentity(ca_tmp, params.save_identity + "_ca", params.privkey_pwd);
+                dht::crypto::saveIdentity(*node_ca, params.save_identity + "_ca", params.privkey_pwd);
                 dht::crypto::saveIdentity(params.id, params.save_identity, params.privkey_pwd);
             }
+#ifndef OPENDHT_PROXY_SERVER
         }
+#endif
 
         dht::DhtRunner::Config config {};
         config.dht_config.node_config.network = params.network;
@@ -562,7 +565,7 @@ main(int argc, char **argv)
             proxies.emplace(params.proxyserver, std::unique_ptr<DhtProxyServer>(
                 new DhtProxyServer(
 #ifdef OPENDHT_PROXY_OPENSSL
-                    params.id, /* dht::crypto::Identity */
+                    params.id,
 #endif
                     node, params.proxyserver, params.pushserver, context.logger)));
 #else