diff --git a/include/opendht/value.h b/include/opendht/value.h
index 4d58fe7c7886efc335580f412b03911a3eca91b3..bf5b8b61657c1697b123fc282cb553ad187f8eed 100644
--- a/include/opendht/value.h
+++ b/include/opendht/value.h
@@ -390,7 +390,7 @@ struct OPENDHT_PUBLIC Value
      * Build a value from a json object
      * @param json
      */
-    Value(Json::Value& json);
+    Value(const Json::Value& json);
 #endif
 
     template <typename Type>
diff --git a/src/base64.cpp b/src/base64.cpp
index 04d7aba8aa4b06cf0bfa4b272eae7c360476188f..c0a2eb20d270d286a5d0d34075792b284500f0de 100644
--- a/src/base64.cpp
+++ b/src/base64.cpp
@@ -131,7 +131,7 @@ base64_encode(const std::vector<unsigned char>& str)
     return base64_encode(str.cbegin(), str.cend());
 }
 
-std::string
+std::vector<unsigned char>
 base64_decode(const std::string& str)
 {
     size_t output_length = str.length() / 4 * 3 + 2;
@@ -139,5 +139,5 @@ base64_decode(const std::string& str)
     output.resize(output_length);
     base64_decode(str.data(), str.size(), output.data(), &output_length);
     output.resize(output_length);
-    return std::string(output.begin(), output.end());
+    return output;
 }
diff --git a/src/base64.h b/src/base64.h
index a868cfa0505b5a8761252404bb201122f3da67fe..5a765a17e18337c4d3b570a69b4f42cf68ec27f2 100644
--- a/src/base64.h
+++ b/src/base64.h
@@ -33,4 +33,4 @@ std::string base64_encode(const std::vector<unsigned char>& str);
  * @param str the input buffer
  * @return a base64-decoded buffer
  */
-std::string base64_decode(const std::string& str);
+std::vector<unsigned char> base64_decode(const std::string& str);
diff --git a/src/value.cpp b/src/value.cpp
index 3f8298eb8f1c5a6d977d56a0bd0eaee5613f706d..7dc83fbab4bf37c3be7b6a3b9b001c02e7128a54 100644
--- a/src/value.cpp
+++ b/src/value.cpp
@@ -165,39 +165,36 @@ Value::msgpack_unpack_body(const msgpack::object& o)
 }
 
 #ifdef OPENDHT_JSONCPP
-Value::Value(Json::Value& json)
+Value::Value(const Json::Value& json)
 {
     id = Value::Id(unpackId(json, "id"));
-    if (json.isMember("cypher")) {
-        auto cypherStr = json["cypher"].asString();
-        cypherStr = base64_decode(cypherStr);
-        cypher = std::vector<unsigned char>(cypherStr.begin(), cypherStr.end());
-    }
-    if (json.isMember("sig")) {
-        auto sigStr = json["sig"].asString();
-        sigStr = base64_decode(sigStr);
-        signature = std::vector<unsigned char>(sigStr.begin(), sigStr.end());
-    }
-    if (json.isMember("seq"))
-        seq = json["seq"].asInt();
-    if (json.isMember("owner")) {
-        auto ownerStr = json["owner"].asString();
+    const auto& jcypher = json["cypher"];
+    if (jcypher.isString())
+        cypher = base64_decode(jcypher.asString());
+    const auto& jsig = json["sig"];
+    if (jsig.isString())
+        signature = base64_decode(jsig.asString());
+    const auto& jseq = json["seq"];
+    if (!jseq.isNull())
+        seq = jseq.asInt();
+    const auto& jowner = json["owner"];
+    if (jowner.isString()) {
+        auto ownerStr = jowner.asString();
         auto ownerBlob = std::vector<unsigned char>(ownerStr.begin(), ownerStr.end());
         owner = std::make_shared<const crypto::PublicKey>(ownerBlob);
     }
-    if (json.isMember("to")) {
-        auto toStr = json["to"].asString();
-        recipient = InfoHash(toStr);
-    }
-    if (json.isMember("type"))
-        type = json["type"].asInt();
-    if (json.isMember("data")){
-        auto dataStr = json["data"].asString();
-        dataStr = base64_decode(dataStr);
-        data = std::vector<unsigned char>(dataStr.begin(), dataStr.end());
-    }
-    if (json.isMember("utype"))
-        user_type = json["utype"].asString();
+    const auto& jto = json["to"];
+    if (jto.isString())
+        recipient = InfoHash(jto.asString());
+    const auto& jtype = json["type"];
+    if (!jtype.isNull())
+        type = jtype.asInt();
+    const auto& jdata = json["data"];
+    if (jdata.isString())
+        data = base64_decode(jdata.asString());
+    const auto& jutype = json["utype"];
+    if (jutype.isString())
+        user_type = jutype.asString();
 }
 
 Json::Value