diff --git a/CMakeLists.txt b/CMakeLists.txt
index 68d0692300190c6928edc023a3e20449636df4f5..fdb16cf761f8d882443f639fa3371d3382e451aa 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -33,7 +33,7 @@ if (OPENDHT_LTO)
     endif ()
 endif ()
 
-find_package (GnuTLS 3.1 REQUIRED)
+find_package (GnuTLS 3.3 REQUIRED)
 find_package (Msgpack 1.2 REQUIRED)
 if (OPENDHT_TOOLS)
     find_package (Readline 6 REQUIRED)
diff --git a/README.md b/README.md
index c18e5646b6df1db507222204c75c80bc57b9d93c..ca86733878e940ae85ace0845b92388a768a1541 100644
--- a/README.md
+++ b/README.md
@@ -89,7 +89,7 @@ for r in results:
 
 ## Dependencies
 - msgpack-c 1.2+, used for data serialization.
-- GnuTLS 3.1+, used for cryptographic operations.
+- GnuTLS 3.3+, used for cryptographic operations.
 - Nettle 2.4+, a GnuTLS dependency for crypto.
 - Build tested with GCC 4.8+ (GNU/Linux, Android, Windows with MinGW), Clang/LLVM (Linux, OS X).
 - Build tested with Microsoft Visual Studio 2015
diff --git a/configure.ac b/configure.ac
index 9850d9a291b86ba353fdc9c4fbd415bbbf06a0d5..3915ad89d905c1019b41e43c946fa3626f238537 100644
--- a/configure.ac
+++ b/configure.ac
@@ -87,7 +87,7 @@ AX_CXX_COMPILE_STDCXX(11,[noext],[mandatory])
 
 PKG_PROG_PKG_CONFIG()
 PKG_CHECK_MODULES([Nettle], [nettle >= 2.4])
-PKG_CHECK_MODULES([GnuTLS], [gnutls >= 3.1])
+PKG_CHECK_MODULES([GnuTLS], [gnutls >= 3.3])
 PKG_CHECK_MODULES([MsgPack], [msgpack >= 1.2])
 CXXFLAGS="${CXXFLAGS} -DMSGPACK_DISABLE_LEGACY_NIL -DMSGPACK_DISABLE_LEGACY_CONVERT"
 
diff --git a/src/crypto.cpp b/src/crypto.cpp
index a0777c18ff8680fcf492815ceff16c77b89d2e76..d205ae4bf0ac8f7bef46c419f262bca3588e9819 100644
--- a/src/crypto.cpp
+++ b/src/crypto.cpp
@@ -220,19 +220,10 @@ Blob hash(const Blob& data, size_t hash_len)
 }
 
 PrivateKey::PrivateKey()
-{
-#if GNUTLS_VERSION_NUMBER < 0x030300
-    if (gnutls_global_init() != GNUTLS_E_SUCCESS)
-        throw CryptoException("Can't initialize GnuTLS.");
-#endif
-}
+{}
 
 PrivateKey::PrivateKey(gnutls_x509_privkey_t k) : x509_key(k)
 {
-#if GNUTLS_VERSION_NUMBER < 0x030300
-    if (gnutls_global_init() != GNUTLS_E_SUCCESS)
-        throw CryptoException("Can't initialize GnuTLS.");
-#endif
     gnutls_privkey_init(&key);
     if (gnutls_privkey_import_x509(key, k, GNUTLS_PRIVKEY_IMPORT_COPY) != GNUTLS_E_SUCCESS) {
         key = nullptr;
@@ -242,10 +233,6 @@ PrivateKey::PrivateKey(gnutls_x509_privkey_t k) : x509_key(k)
 
 PrivateKey::PrivateKey(const Blob& import, const std::string& password)
 {
-#if GNUTLS_VERSION_NUMBER < 0x030300
-    if (gnutls_global_init() != GNUTLS_E_SUCCESS)
-        throw CryptoException("Can't initialize GnuTLS.");
-#endif
     int err = gnutls_x509_privkey_init(&x509_key);
     if (err != GNUTLS_E_SUCCESS)
         throw CryptoException("Can't initialize private key !");
@@ -277,11 +264,6 @@ PrivateKey::PrivateKey(const Blob& import, const std::string& password)
 
 PrivateKey::PrivateKey(PrivateKey&& o) noexcept : key(o.key), x509_key(o.x509_key)
 {
-#if GNUTLS_VERSION_NUMBER < 0x030300
-    // gnutls_global_init already succeeded at least once here so no real need to check.
-    int ret = gnutls_global_init();
-    assert(ret == GNUTLS_E_SUCCESS);
-#endif
     o.key = nullptr;
     o.x509_key = nullptr;
 }
@@ -296,9 +278,6 @@ PrivateKey::~PrivateKey()
         gnutls_x509_privkey_deinit(x509_key);
         x509_key = nullptr;
     }
-#if GNUTLS_VERSION_NUMBER < 0x030300
-    gnutls_global_deinit();
-#endif
 }
 
 PrivateKey&
@@ -749,10 +728,6 @@ Certificate::toString(bool chain) const
 PrivateKey
 PrivateKey::generate(unsigned key_length)
 {
-#if GNUTLS_VERSION_NUMBER < 0x030300
-    if (gnutls_global_init() != GNUTLS_E_SUCCESS)
-        throw CryptoException("Can't initialize GnuTLS.");
-#endif
     gnutls_x509_privkey_t key;
     if (gnutls_x509_privkey_init(&key) != GNUTLS_E_SUCCESS)
         throw CryptoException("Can't initialize private key.");
@@ -767,17 +742,8 @@ PrivateKey::generate(unsigned key_length)
 Identity
 generateIdentity(const std::string& name, crypto::Identity ca, unsigned key_length, bool is_ca)
 {
-#if GNUTLS_VERSION_NUMBER < 0x030300
-    if (gnutls_global_init() != GNUTLS_E_SUCCESS)
-        return {};
-#endif
     auto key = std::make_shared<PrivateKey>(PrivateKey::generate(key_length));
-
     auto cert = std::make_shared<Certificate>(Certificate::generate(*key, name, ca, is_ca));
-
-#if GNUTLS_VERSION_NUMBER < 0x030300
-    gnutls_global_deinit();
-#endif
     return {std::move(key), std::move(cert)};
 }
 
diff --git a/src/securedht.cpp b/src/securedht.cpp
index efb988df4d8747c9f24ead9555b328c47a70697c..b3d33b922373b6068441636df01ce71b4bc459a8 100644
--- a/src/securedht.cpp
+++ b/src/securedht.cpp
@@ -50,12 +50,6 @@ SecureDht::SecureDht(int s, int s6, SecureDht::Config conf)
     if (s < 0 && s6 < 0)
         return;
 
-#if GNUTLS_VERSION_NUMBER < 0x030300
-    int rc = gnutls_global_init();
-    if (rc != GNUTLS_E_SUCCESS)
-        throw DhtException(std::string("Error initializing GnuTLS: ")+gnutls_strerror(rc));
-#endif
-
     for (const auto& type : DEFAULT_TYPES)
         registerType(type);
 
@@ -81,11 +75,7 @@ SecureDht::SecureDht(int s, int s6, SecureDht::Config conf)
 }
 
 SecureDht::~SecureDht()
-{
-#if GNUTLS_VERSION_NUMBER < 0x030300
-    gnutls_global_deinit();
-#endif
-}
+{}
 
 ValueType
 SecureDht::secureType(ValueType&& type)