diff --git a/include/opendht/crypto.h b/include/opendht/crypto.h
index 64d43092928acad69f7a222ff9fd01d88d70bd62..15aec8806778c5f8b7df7d72e0a5ad3431b4acb9 100644
--- a/include/opendht/crypto.h
+++ b/include/opendht/crypto.h
@@ -33,6 +33,7 @@ extern "C" {
 #include <vector>
 #include <memory>
 #include <atomic>
+#include <mutex>
 
 #ifdef _WIN32
 #include <iso646.h>
@@ -207,6 +208,7 @@ private:
     PrivateKey& operator=(const PrivateKey&) = delete;
     Blob decryptBloc(const uint8_t* src, size_t src_size) const;
 
+    mutable std::mutex publicKeyMutex_ {};
     mutable std::shared_ptr<PublicKey> publicKey_ {};
 };
 
diff --git a/src/crypto.cpp b/src/crypto.cpp
index f1b18c1523534429ea3d7d75bb6e55e5821a234e..dba347320eb7fe16f0a19a0151913bfadf82693d 100644
--- a/src/crypto.cpp
+++ b/src/crypto.cpp
@@ -361,6 +361,7 @@ PrivateKey::getPublicKey() const
 const std::shared_ptr<PublicKey>&
 PrivateKey::getSharedPublicKey() const
 {
+    std::lock_guard<std::mutex> lock(publicKeyMutex_);
     if (not publicKey_) {
         auto pk = std::make_shared<PublicKey>();
         if (auto err = gnutls_pubkey_import_privkey(pk->pk, key, GNUTLS_KEY_KEY_CERT_SIGN | GNUTLS_KEY_CRL_SIGN, 0))