diff --git a/docs/_static/decryptor.png b/docs/_static/decryptor.png
new file mode 100644
index 0000000..30791b7
--- /dev/null
+++ b/docs/_static/decryptor.png
Binary files differ
diff --git a/docs/figures/decryptor.pptx b/docs/figures/decryptor.pptx
new file mode 100644
index 0000000..e0f9545
--- /dev/null
+++ b/docs/figures/decryptor.pptx
Binary files differ
diff --git a/docs/spec.rst b/docs/spec.rst
index 2dfc33f..2de5aa1 100644
--- a/docs/spec.rst
+++ b/docs/spec.rst
@@ -120,3 +120,12 @@
                       .EncryptedPayload = ContentKey encrypted by public key /[access-namespace]/NAC/[dataset]/KEK/[key-id]
                       // .InitializationVector, .EncryptedPayloadKey, and .Name are not set
                     )
+
+Decryptor
+---------
+
+.. figure:: _static/decryptor.png
+   :alt: Decryptor
+   :align: center
+
+Encryptor decrypts (asynchronous operation, contingent on successful retrieval of CK data, KDK, and decryption of both) the supplied ``EncryptedContent`` element.
diff --git a/src/decryptor.cpp b/src/decryptor.cpp
new file mode 100644
index 0000000..25043d5
--- /dev/null
+++ b/src/decryptor.cpp
@@ -0,0 +1,269 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/**
+ * Copyright (c) 2014-2018, Regents of the University of California
+ *
+ * NAC library is free software: you can redistribute it and/or modify it under the
+ * terms of the GNU Lesser General Public License as published by the Free Software
+ * Foundation, either version 3 of the License, or (at your option) any later version.
+ *
+ * NAC library is distributed in the hope that it will be useful, but WITHOUT ANY
+ * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+ * PARTICULAR PURPOSE.  See the GNU Lesser General Public License for more details.
+ *
+ * You should have received copies of the GNU General Public License and GNU Lesser
+ * General Public License along with ndn-cxx, e.g., in COPYING.md file.  If not, see
+ * <http://www.gnu.org/licenses/>.
+ *
+ * See AUTHORS.md for complete list of NAC library authors and contributors.
+ */
+
+#include "decryptor.hpp"
+
+#include <ndn-cxx/util/logger.hpp>
+
+namespace ndn {
+namespace nac {
+
+NDN_LOG_INIT(nac.Decryptor);
+
+const size_t N_RETRIES = 3;
+
+Decryptor::Decryptor(const Key& credentialsKey, Validator& validator, KeyChain& keyChain, Face& face)
+  : m_credentialsKey(credentialsKey)
+  // , m_validator(validator)
+  , m_face(face)
+  , m_keyChain(keyChain)
+  , m_internalKeyChain("pib-memory:", "tpm-memory:")
+{
+}
+
+Decryptor::~Decryptor()
+{
+  for (auto& i : m_cks) {
+    if (i.second.pendingInterest != nullptr) {
+      m_face.removePendingInterest(i.second.pendingInterest);
+      i.second.pendingInterest = nullptr;
+
+      for (const auto& p : i.second.pendingDecrypts) {
+        p.onFailure(ErrorCode::CkRetrievalFailure, "Cancel pending decrypt as ContentKey is being destroyed");
+      }
+      i.second.pendingDecrypts.clear(); // not really necessary, but just in case
+    }
+  }
+}
+
+void
+Decryptor::decrypt(const Block& encryptedContent, const DecryptSuccessCallback& onSuccess, const ErrorCallback& onFailure)
+{
+  EncryptedContent ec(encryptedContent);
+  if (!ec.hasKeyLocator()) {
+    NDN_LOG_INFO("Missing required KeyLocator in the supplied EncryptedContent block");
+    return onFailure(ErrorCode::MissingRequiredKeyLocator,
+                     "Missing required KeyLocator in the supplied EncryptedContent block");
+  }
+
+  if (!ec.hasIv()) {
+    NDN_LOG_INFO("Missing required InitialVector in the supplied EncryptedContent block");
+    return onFailure(ErrorCode::MissingRequiredKeyLocator,
+                     "Missing required InitialVector in the supplied EncryptedContent block");
+  }
+
+  ContentKeys::iterator ck;
+  bool isNew = false;
+  std::tie(ck, isNew) = m_cks.emplace(ec.getKeyLocator(), ContentKey{});
+
+  if (ck->second.isRetrieved) {
+    doDecrypt(ec, ck->second.bits, onSuccess, onFailure);
+  }
+  else {
+    NDN_LOG_DEBUG("CK " << ec.getKeyLocator() << " not yet available, adding decrypt to the pending queue");
+    ck->second.pendingDecrypts.push_back({ec, onSuccess, onFailure});
+  }
+
+  if (isNew) {
+    fetchCk(ck, onFailure, N_RETRIES);
+  }
+}
+
+void
+Decryptor::fetchCk(ContentKeys::iterator ck, const ErrorCallback& onFailure, size_t nTriesLeft)
+{
+  // full name of CK is
+
+  // <whatever-prefix>/CK/<ck-id>  /ENCRYPTED-BY /<kek-prefix>/KEK/<key-id>
+  // \                          /                \                        /
+  //  -----------  -------------                  -----------  -----------
+  //             \/                                          \/
+  //   from the encrypted data          unknown (name in retrieved CK is used to determine KDK)
+
+  const Name& ckName = ck->first;
+
+  NDN_LOG_DEBUG("Fetching CK " << ckName);
+
+  ck->second.pendingInterest = m_face.expressInterest(Interest(ckName)
+                                                       .setMustBeFresh(false) // ?
+                                                       .setCanBePrefix(true),
+    [=] (const Interest& ckInterest, const Data& ckData) {
+      ck->second.pendingInterest = nullptr;
+      // @TODO verify if the key is legit
+      Name kdkPrefix, kdkIdentity, kdkKeyName;
+      std::tie(kdkPrefix, kdkIdentity, kdkKeyName) =
+        extractKdkInfoFromCkName(ckData.getName(), ckInterest.getName(), onFailure);
+      if (kdkPrefix.empty()) {
+        return; // error has been already reported
+      }
+
+      // check if KDK already exists (there is a corresponding
+      auto kdkIdentityIt = m_internalKeyChain.getPib().getIdentities().find(kdkIdentity);
+      if (kdkIdentityIt != m_internalKeyChain.getPib().getIdentities().end()) {
+        auto kdkKeyIt = (*kdkIdentityIt).getKeys().find(kdkKeyName);
+        if (kdkKeyIt != (*kdkIdentityIt).getKeys().end()) {
+          // KDK was already fetched and imported
+          NDN_LOG_DEBUG("KDK " << kdkKeyName << " already exists, directly using it to decrypt CK");
+          return decryptCkAndProcessPendingDecrypts(ck, ckData, kdkKeyName, onFailure);
+        }
+      }
+
+      fetchKdk(ck, kdkPrefix, ckData, onFailure, N_RETRIES);
+    },
+    [=] (const Interest& i, const lp::Nack& nack) {
+      ck->second.pendingInterest = nullptr;
+      onFailure(ErrorCode::CkRetrievalFailure,
+                "Retrieval of CK [" + i.getName().toUri() + "] failed. "
+                "Got NACK (" + boost::lexical_cast<std::string>(nack.getReason()) + ")");
+    },
+    [=] (const Interest& i) {
+      ck->second.pendingInterest = nullptr;
+      if (nTriesLeft > 1) {
+        fetchCk(ck, onFailure, nTriesLeft - 1);
+      }
+      else {
+        onFailure(ErrorCode::CkRetrievalTimeout,
+                  "Retrieval of CK [" + i.getName().toUri() + "] timed out");
+      }
+    });
+}
+
+void
+Decryptor::fetchKdk(ContentKeys::iterator ck, const Name& kdkPrefix, const Data& ckData,
+                    const ErrorCallback& onFailure, size_t nTriesLeft)
+{
+  // <kdk-prefix>/KDK/<kdk-id>    /ENCRYPTED-BY  /<credential-identity>/KEY/<key-id>
+  // \                          /                \                                /
+  //  -----------  -------------                  ---------------  ---------------
+  //             \/                                              \/
+  //     from the CK data                                from configuration
+
+  Name kdkName = kdkPrefix;
+  kdkName
+    .append(ENCRYPTED_BY)
+    .append(m_credentialsKey.getName());
+
+  NDN_LOG_DEBUG("Fetching KDK " << kdkName);
+
+  ck->second.pendingInterest = m_face.expressInterest(Interest(kdkName)
+                                                     .setMustBeFresh(true)
+                                                     .setCanBePrefix(false),
+    [=] (const Interest& ckInterest, const Data& kdkData) {
+      ck->second.pendingInterest = nullptr;
+      // @TODO verify if the key is legit
+
+      bool isOk = decryptAndImportKdk(kdkData, onFailure);
+      if (!isOk)
+        return;
+      decryptCkAndProcessPendingDecrypts(ck, ckData,
+                                         kdkPrefix.getPrefix(-2).append("KEY").append(kdkPrefix.get(-1)), // a bit hacky
+                                         onFailure);
+    },
+    [=] (const Interest& i, const lp::Nack& nack) {
+      ck->second.pendingInterest = nullptr;
+      onFailure(ErrorCode::KdkRetrievalFailure,
+                "Retrieval of KDK [" + i.getName().toUri() + "] failed. "
+                "Got NACK (" + boost::lexical_cast<std::string>(nack.getReason()) + ")");
+    },
+    [=] (const Interest& i) {
+      ck->second.pendingInterest = nullptr;
+      if (nTriesLeft > 1) {
+        fetchKdk(ck, kdkPrefix, ckData, onFailure, nTriesLeft - 1);
+      }
+      else {
+        onFailure(ErrorCode::KdkRetrievalTimeout,
+                  "Retrieval of KDK [" + i.getName().toUri() + "] timed out");
+      }
+    });
+}
+
+bool
+Decryptor::decryptAndImportKdk(const Data& kdkData, const ErrorCallback& onFailure)
+{
+  try {
+    NDN_LOG_DEBUG("Decrypting and importing KDK " << kdkData.getName());
+    EncryptedContent content(kdkData.getContent().blockFromValue());
+
+    SafeBag safeBag(content.getPayload().blockFromValue());
+    auto secret = m_keyChain.getTpm().decrypt(content.getPayloadKey().value(),
+                                              content.getPayloadKey().value_size(),
+                                              m_credentialsKey.getName());
+    if (secret == nullptr) {
+      onFailure(ErrorCode::TpmKeyNotFound,
+                "Could not decrypt secret, " + m_credentialsKey.getName().toUri() + " not found in TPM");
+      return false;
+    }
+
+    m_internalKeyChain.importSafeBag(safeBag, reinterpret_cast<const char*>(secret->data()), secret->size());
+    return true;
+  }
+  catch (const std::runtime_error& e) {
+    // can be tlv::Error, pib::Error, tpm::Error, and bunch of other runtime-derived errors
+    onFailure(ErrorCode::KdkDecryptionFailure,
+              "Failed to decrypt KDK [" + kdkData.getName().toUri() + "]: " + e.what());
+    return false;
+  }
+}
+
+void
+Decryptor::decryptCkAndProcessPendingDecrypts(ContentKeys::iterator ck, const Data& ckData, const Name& kdkKeyName,
+                                              const ErrorCallback& onFailure)
+{
+  NDN_LOG_DEBUG("Decrypting CK data " << ckData.getName());
+
+  EncryptedContent content(ckData.getContent().blockFromValue());
+
+  auto ckBits = m_internalKeyChain.getTpm().decrypt(content.getPayload().value(), content.getPayload().value_size(),
+                                                    kdkKeyName);
+  if (ckBits == nullptr) {
+    onFailure(ErrorCode::TpmKeyNotFound, "Could not decrypt secret, " + kdkKeyName.toUri() + " not found in TPM");
+    return;
+  }
+
+  ck->second.bits = *ckBits;
+  ck->second.isRetrieved = true;
+
+  for (const auto& item : ck->second.pendingDecrypts) {
+    doDecrypt(item.encryptedContent, ck->second.bits, item.onSuccess, item.onFailure);
+  }
+  ck->second.pendingDecrypts.clear();
+}
+
+void
+Decryptor::doDecrypt(const EncryptedContent& content, const Buffer& ckBits,
+                     const DecryptSuccessCallback& onSuccess,
+                     const ErrorCallback& onFailure)
+{
+  if (!content.hasIv()) {
+    BOOST_THROW_EXCEPTION(Error("Expecting Initial Vector in the encrypted content, but it is not present"));
+  }
+
+  OBufferStream os;
+  security::transform::bufferSource(content.getPayload().value(), content.getPayload().value_size())
+    >> security::transform::blockCipher(BlockCipherAlgorithm::AES_CBC,
+                                        CipherOperator::DECRYPT,
+                                        ckBits.data(), ckBits.size(),
+                                        content.getIv().value(), content.getIv().value_size())
+    >> security::transform::streamSink(os);
+
+  onSuccess(os.buf());
+}
+
+} // namespace nac
+} // namespace ndn
diff --git a/src/decryptor.hpp b/src/decryptor.hpp
new file mode 100644
index 0000000..d2d6406
--- /dev/null
+++ b/src/decryptor.hpp
@@ -0,0 +1,117 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/**
+ * Copyright (c) 2014-2018, Regents of the University of California
+ *
+ * NAC library is free software: you can redistribute it and/or modify it under the
+ * terms of the GNU Lesser General Public License as published by the Free Software
+ * Foundation, either version 3 of the License, or (at your option) any later version.
+ *
+ * NAC library is distributed in the hope that it will be useful, but WITHOUT ANY
+ * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+ * PARTICULAR PURPOSE.  See the GNU Lesser General Public License for more details.
+ *
+ * You should have received copies of the GNU General Public License and GNU Lesser
+ * General Public License along with ndn-cxx, e.g., in COPYING.md file.  If not, see
+ * <http://www.gnu.org/licenses/>.
+ *
+ * See AUTHORS.md for complete list of NAC library authors and contributors.
+ */
+
+#ifndef NDN_NAC_DECRYPTOR_HPP
+#define NDN_NAC_DECRYPTOR_HPP
+
+#include "common.hpp"
+#include "encrypted-content.hpp"
+
+#include <ndn-cxx/face.hpp>
+
+namespace ndn {
+namespace nac {
+
+/**
+ * @brief NAC Decryptor
+ *
+ * Encryptor decrypts (asynchronous operation, contingent on successful retrieval of CK data,
+ * KDK, and decryption of both) the supplied ``EncryptedContent`` element.
+ */
+class Decryptor
+{
+public:
+  using DecryptSuccessCallback = std::function<void(ConstBufferPtr)>;
+
+private:
+  struct ContentKey
+  {
+    bool isRetrieved = false;
+    Buffer bits;
+    const PendingInterestId* pendingInterest = nullptr;
+
+    struct PendingDecrypt
+    {
+      EncryptedContent encryptedContent;
+      DecryptSuccessCallback onSuccess;
+      ErrorCallback onFailure;
+    };
+    std::list<PendingDecrypt> pendingDecrypts;
+  };
+
+  using ContentKeys = std::map<Name, ContentKey>;
+
+public:
+  /**
+   * @brief Constructor
+   * @param credentialsKey Credentials key to be used to retrieve and decrypt KDK
+   * @param validator Validation policy to ensure validity of KDK and CK
+   * @param keyChain  KeyChain
+   * @param face      Face that will be used to fetch CK and KDK
+   */
+  Decryptor(const Key& credentialsKey, Validator& validator, KeyChain& keyChain, Face& face);
+
+  ~Decryptor();
+
+  /**
+   * @brief Asynchronously decrypt @p encryptedContent
+   */
+  void
+  decrypt(const Block& encryptedContent, const DecryptSuccessCallback& onSuccess, const ErrorCallback& onFailure);
+
+private:
+  void
+  fetchCk(ContentKeys::iterator ck, const ErrorCallback& onFailure, size_t nTriesLeft);
+
+  void
+  fetchKdk(ContentKeys::iterator ck, const Name& kdkPrefix, const Data& ckData,
+           const ErrorCallback& onFailure, size_t nTriesLeft);
+
+  bool
+  decryptAndImportKdk(const Data& kdkData, const ErrorCallback& onFailure);
+
+  void
+  decryptCkAndProcessPendingDecrypts(ContentKeys::iterator ck, const Data& ckData,
+                                     const Name& kdkKeyName/* local keyChain name for KDK key*/,
+                                     const ErrorCallback& onFailure);
+
+  /**
+   * @brief Synchronously decrypt (assume CK exists)
+   */
+  void
+  doDecrypt(const EncryptedContent& encryptedContent, const Buffer& ckBits,
+            const DecryptSuccessCallback& onSuccess,
+            const ErrorCallback& onFailure);
+
+private:
+  Key m_credentialsKey;
+  // Validator& m_validator;
+  Face& m_face;
+  KeyChain& m_keyChain; // external keychain with access credentials
+  KeyChain m_internalKeyChain; // internal in-memory keychain for temporarily storing KDKs
+
+  // a set of Content Keys
+  // @TODO add some expiration, so they are not stored forever
+  ContentKeys m_cks;
+};
+
+} // namespace nac
+} // namespace ndn
+
+#endif // NDN_NAC_DECRYPTOR_HPP
diff --git a/tests/tests/decryptor.t.cpp b/tests/tests/decryptor.t.cpp
new file mode 100644
index 0000000..258d135
--- /dev/null
+++ b/tests/tests/decryptor.t.cpp
@@ -0,0 +1,137 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/**
+ * Copyright (c) 2014-2018, Regents of the University of California
+ *
+ * NAC library is free software: you can redistribute it and/or modify it under the
+ * terms of the GNU Lesser General Public License as published by the Free Software
+ * Foundation, either version 3 of the License, or (at your option) any later version.
+ *
+ * NAC library is distributed in the hope that it will be useful, but WITHOUT ANY
+ * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+ * PARTICULAR PURPOSE.  See the GNU Lesser General Public License for more details.
+ *
+ * You should have received copies of the GNU General Public License and GNU Lesser
+ * General Public License along with ndn-cxx, e.g., in COPYING.md file.  If not, see
+ * <http://www.gnu.org/licenses/>.
+ *
+ * See AUTHORS.md for complete list of NAC library authors and contributors.
+ */
+
+#include "decryptor.hpp"
+
+#include "encryptor.hpp"
+#include "encrypted-content.hpp"
+#include "access-manager.hpp"
+
+#include "tests-common.hpp"
+#include "dummy-forwarder.hpp"
+#include "static-data.hpp"
+
+#include <iostream>
+#include <boost/mpl/vector.hpp>
+
+namespace ndn {
+namespace nac {
+namespace tests {
+
+class StaticDataEnvironment : public UnitTestTimeFixture
+{
+public:
+  StaticDataEnvironment()
+    : fw(m_io, m_keyChain)
+    , imsFace(static_cast<util::DummyClientFace&>(fw.addFace()))
+  {
+    StaticData data;
+    for (const auto& block : data.managerPackets) {
+      auto data = make_shared<Data>(block);
+      m_ims.insert(*data);
+    }
+
+    for (const auto& block : data.encryptorPackets) {
+      auto data = make_shared<Data>(block);
+      m_ims.insert(*data);
+    }
+
+    auto serveFromIms = [this] (const Name& prefix, const Interest& interest) {
+      auto data = m_ims.find(interest);
+      if (data != nullptr) {
+        imsFace.put(*data);
+      }
+    };
+    imsFace.setInterestFilter("/", serveFromIms, [] (auto...) {});
+    advanceClocks(1_ms, 10);
+
+    // import "/first/user" identity
+    m_keyChain.importSafeBag(SafeBag(data.userIdentities.at(0)), "password", strlen("password"));
+    // credentialIdentity = m_keyChain.getPib().getIdentity("/first/user");
+
+    addIdentity("/not/authorized");
+  }
+
+public:
+  DummyForwarder fw;
+  util::DummyClientFace& imsFace;
+  InMemoryStoragePersistent m_ims;
+};
+
+template<class T>
+class DecryptorFixture : public StaticDataEnvironment
+{
+public:
+  DecryptorFixture()
+    : face(static_cast<util::DummyClientFace&>(fw.addFace()))
+    , decryptor(m_keyChain.getPib().getIdentity(T().identity).getDefaultKey(), validator, m_keyChain, face)
+  {
+    advanceClocks(1_ms, 10);
+  }
+
+public:
+  util::DummyClientFace& face;
+  ValidatorNull validator;
+  Decryptor decryptor;
+};
+
+BOOST_AUTO_TEST_SUITE(TestDecryptor)
+
+struct Valid
+{
+  std::string identity = "/first/user";
+  bool expectToSucceed = true;
+};
+
+struct Invalid
+{
+  std::string identity = "/not/authorized";
+  bool expectToSucceed = false;
+};
+
+using Identities = boost::mpl::vector<Valid, Invalid>;
+
+BOOST_FIXTURE_TEST_CASE_TEMPLATE(DecryptSuccess, T, Identities, DecryptorFixture<T>)
+{
+  StaticData data;
+
+  size_t nSuccesses = 0;
+  size_t nFailures = 0;
+  this->decryptor.decrypt(data.encryptedBlobs.at(0),
+                    [&] (ConstBufferPtr buffer) {
+                      ++nSuccesses;
+                      BOOST_CHECK_EQUAL(buffer->size(), 15);
+                      std::string content(reinterpret_cast<const char*>(buffer->data()), buffer->size());
+                      BOOST_CHECK_EQUAL(content, "Data to encrypt");
+                    },
+                    [&] (const ErrorCode& code, const std::string& msg) {
+                      BOOST_TEST_MESSAGE(msg);
+                      ++nFailures;
+                    });
+  this->advanceClocks(2_s, 10);
+
+  BOOST_CHECK_EQUAL(nSuccesses, T().expectToSucceed ? 1 : 0);
+  BOOST_CHECK_EQUAL(nFailures, T().expectToSucceed ? 0 : 1);
+}
+
+BOOST_AUTO_TEST_SUITE_END()
+
+} // namespace tests
+} // namespace nac
+} // namespace ndn
