diff --git a/include/opendht/default_types.h b/include/opendht/default_types.h
index 96c5a5a4f082a72d1bc09b54417187f0072aa7da..c6d8907c4bdb89edcf4e4ee6666f98442781cbff 100644
--- a/include/opendht/default_types.h
+++ b/include/opendht/default_types.h
@@ -150,9 +150,33 @@ struct IceCandidates : public EncryptedValue<IceCandidates>
         return EncryptedValue::getFilter();
     }
 
+    template <typename Packer>
+    void msgpack_pack(Packer& pk) const
+    {
+        pk.pack_array(2);
+        pk.pack(id);
+#if 0
+        pk.pack_bin(ice_data.size());
+        pk.pack_bin_body((const char*)ice_data.data(), ice_data.size());
+#else
+        // hack for backward compatibility with old opendht compiled with msgpack 1.0
+        // remove when enough people have moved to new versions 
+        pk.pack_array(ice_data.size());
+        for (uint8_t b : ice_data)
+            pk.pack(b);
+#endif
+    }
+
+    void msgpack_unpack(msgpack::object o)
+    {
+        if (o.type != msgpack::type::ARRAY) throw msgpack::type_error();
+        if (o.via.array.size < 2) throw msgpack::type_error();
+        id = o.via.array.ptr[0].as<Value::Id>();
+        ice_data = unpackBlob(o.via.array.ptr[1]);
+    }
+
     Value::Id id;
     Blob ice_data;
-    MSGPACK_DEFINE(id, ice_data);
 };
 
 
diff --git a/include/opendht/value.h b/include/opendht/value.h
index 8f98737afd8a855157f25deaa8505fd350ef2a61..2a9a39b074c5a66d17797d5cda4420a9e17e449c 100644
--- a/include/opendht/value.h
+++ b/include/opendht/value.h
@@ -505,4 +505,9 @@ unpackVector(const std::vector<std::shared_ptr<Value>>& vals) {
     return ret;
 }
 
+/**
+ * Provides backward compatibility with msgpack 1.0
+ */
+Blob unpackBlob(msgpack::object& o);
+
 }
diff --git a/src/crypto.cpp b/src/crypto.cpp
index 4719b67022cdac6221afd836642127c1df28a3ea..122d3fb0074ab1a347ff124e36fa712db374b8d9 100644
--- a/src/crypto.cpp
+++ b/src/crypto.cpp
@@ -30,6 +30,7 @@
 
 #include "crypto.h"
 #include "rng.h"
+#include "value.h"
 
 extern "C" {
 #include <gnutls/gnutls.h>
@@ -395,9 +396,12 @@ PublicKey::unpack(const uint8_t* data, size_t data_size)
 void
 PublicKey::msgpack_unpack(msgpack::object o)
 {
-    if (o.type != msgpack::type::BIN)
-        throw msgpack::type_error();
-    unpack((const uint8_t*)o.via.bin.ptr, o.via.bin.size);
+    if (o.type == msgpack::type::BIN)
+        unpack((const uint8_t*)o.via.bin.ptr, o.via.bin.size);
+    else {
+        Blob dat = unpackBlob(o);
+        unpack(dat.data(), dat.size());
+    }
 }
 
 bool
@@ -521,9 +525,12 @@ Certificate::unpack(const uint8_t* dat, size_t dat_size)
 void
 Certificate::msgpack_unpack(msgpack::object o)
 {
-    if (o.type != msgpack::type::BIN)
-        throw msgpack::type_error();
-    unpack((const uint8_t*)o.via.bin.ptr, o.via.bin.size);
+    if (o.type == msgpack::type::BIN)
+        unpack((const uint8_t*)o.via.bin.ptr, o.via.bin.size);
+    else {
+        Blob dat = unpackBlob(o);
+        unpack(dat.data(), dat.size());
+    }
 }
 
 void
diff --git a/src/dht.cpp b/src/dht.cpp
index 567952169d066063be6a629cad5baac95b148920..9a1f12856569611f130f132236aeaa9a1f8e918a 100644
--- a/src/dht.cpp
+++ b/src/dht.cpp
@@ -3114,28 +3114,6 @@ findMapValue(msgpack::object& map, const std::string& key) {
     return nullptr;
 }
 
-/**
- * Provides backward compatibility with msgpack 1.0
- */
-Blob
-getBlob(msgpack::object& o) {
-    switch (o.type) {
-    case msgpack::type::BIN:
-        return {o.via.bin.ptr, o.via.bin.ptr+o.via.bin.size};
-    case msgpack::type::STR:
-        return {o.via.str.ptr, o.via.str.ptr+o.via.str.size};
-    case msgpack::type::ARRAY: {
-        Blob ret(o.via.array.size);
-        std::transform(o.via.array.ptr, o.via.array.ptr+o.via.array.size, ret.begin(), [](const msgpack::object& b) {
-            return b.as<uint8_t>();
-        });
-        return ret;
-    }
-    default:
-        throw msgpack::type_error();
-    }
-}
-
 void
 Dht::ParsedMessage::msgpack_unpack(msgpack::object msg)
 {
@@ -3171,16 +3149,16 @@ Dht::ParsedMessage::msgpack_unpack(msgpack::object msg)
         target = {*rtarget};
 
     if (auto otoken = findMapValue(req, "token"))
-        token = getBlob(*otoken);
+        token = unpackBlob(*otoken);
 
     if (auto vid = findMapValue(req, "vid"))
         value_id = vid->as<Value::Id>();
 
     if (auto rnodes4 = findMapValue(req, "n4"))
-        nodes4 = getBlob(*rnodes4);
+        nodes4 = unpackBlob(*rnodes4);
 
     if (auto rnodes6 = findMapValue(req, "n6"))
-        nodes6 = getBlob(*rnodes6);
+        nodes6 = unpackBlob(*rnodes6);
 
     if (auto sa = findMapValue(req, "sa")) {
         if (sa->type != msgpack::type::BIN)
diff --git a/src/value.cpp b/src/value.cpp
index c80761827c6e7c0dab19b62d6d995e4099313907..dbcb197f51e2161bf1dd4860d15669343c52d186 100644
--- a/src/value.cpp
+++ b/src/value.cpp
@@ -128,8 +128,7 @@ Value::msgpack_unpack_body(const msgpack::object& o)
             throw msgpack::type_error();
 
         if (auto rdata = findMapValue(*rbody, "data")) {
-            auto dat = rdata->as<std::vector<char>>();
-            data = {dat.begin(), dat.end()};
+            data = unpackBlob(*rdata);
         } else
             throw msgpack::type_error();
 
@@ -153,12 +152,30 @@ Value::msgpack_unpack_body(const msgpack::object& o)
             }
 
             if (auto rsig = findMapValue(o, "sig")) {
-                auto dat = rsig->as<std::vector<char>>();
-                signature = {dat.begin(), dat.end()};
+                signature = unpackBlob(*rsig);
             } else
                 throw msgpack::type_error();
         }
     }
 }
 
+Blob
+unpackBlob(msgpack::object& o) {
+    switch (o.type) {
+    case msgpack::type::BIN:
+        return {o.via.bin.ptr, o.via.bin.ptr+o.via.bin.size};
+    case msgpack::type::STR:
+        return {o.via.str.ptr, o.via.str.ptr+o.via.str.size};
+    case msgpack::type::ARRAY: {
+        Blob ret(o.via.array.size);
+        std::transform(o.via.array.ptr, o.via.array.ptr+o.via.array.size, ret.begin(), [](const msgpack::object& b) {
+            return b.as<uint8_t>();
+        });
+        return ret;
+    }
+    default:
+        throw msgpack::type_error();
+    }
+}
+
 }