diff --git a/src/security/v2/key-chain.cpp b/src/security/v2/key-chain.cpp
new file mode 100644
index 0000000..0f3909e
--- /dev/null
+++ b/src/security/v2/key-chain.cpp
@@ -0,0 +1,698 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/**
+ * Copyright (c) 2013-2017 Regents of the University of California.
+ *
+ * This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
+ *
+ * ndn-cxx 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.
+ *
+ * ndn-cxx 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 ndn-cxx authors and contributors.
+ */
+
+#include "key-chain.hpp"
+
+#include "../../util/config-file.hpp"
+
+#include "../pib/pib-sqlite3.hpp"
+#include "../pib/pib-memory.hpp"
+
+#ifdef NDN_CXX_HAVE_OSX_SECURITY
+#include "../tpm/back-end-osx.hpp"
+#endif // NDN_CXX_HAVE_OSX_SECURITY
+
+#include "../tpm/back-end-file.hpp"
+#include "../tpm/back-end-mem.hpp"
+
+#include "../transform/bool-sink.hpp"
+#include "../transform/buffer-source.hpp"
+#include "../transform/private-key.hpp"
+#include "../transform/verifier-filter.hpp"
+#include "../../encoding/buffer-stream.hpp"
+#include "../../util/crypto.hpp"
+
+#include <boost/lexical_cast.hpp>
+
+namespace ndn {
+namespace security {
+
+// When static library is used, not everything is compiled into the resulting binary.
+// Therefore, the following standard PIB and TPMs need to be registered here.
+// http://stackoverflow.com/q/9459980/2150331
+
+/////////
+// PIB //
+/////////
+namespace pib {
+NDN_CXX_V2_KEYCHAIN_REGISTER_PIB_BACKEND(PibSqlite3);
+NDN_CXX_V2_KEYCHAIN_REGISTER_PIB_BACKEND(PibMemory);
+} // namespace pib
+
+/////////
+// TPM //
+/////////
+namespace tpm {
+#if defined(NDN_CXX_HAVE_OSX_SECURITY) && defined(NDN_CXX_WITH_OSX_KEYCHAIN)
+NDN_CXX_V2_KEYCHAIN_REGISTER_TPM_BACKEND(BackEndOsx);
+#endif // defined(NDN_CXX_HAVE_OSX_SECURITY) && defined(NDN_CXX_WITH_OSX_KEYCHAIN)
+
+NDN_CXX_V2_KEYCHAIN_REGISTER_TPM_BACKEND(BackEndFile);
+NDN_CXX_V2_KEYCHAIN_REGISTER_TPM_BACKEND(BackEndMem);
+} // namespace tpm
+
+namespace v2 {
+
+std::string KeyChain::s_defaultPibLocator;
+std::string KeyChain::s_defaultTpmLocator;
+
+KeyChain::PibFactories&
+KeyChain::getPibFactories()
+{
+  static PibFactories pibFactories;
+  return pibFactories;
+}
+
+KeyChain::TpmFactories&
+KeyChain::getTpmFactories()
+{
+  static TpmFactories tpmFactories;
+  return tpmFactories;
+}
+
+const std::string&
+KeyChain::getDefaultPibScheme()
+{
+  return pib::PibSqlite3::getScheme();;
+}
+
+const std::string&
+KeyChain::getDefaultTpmScheme()
+{
+#if defined(NDN_CXX_HAVE_OSX_SECURITY) && defined(NDN_CXX_WITH_OSX_KEYCHAIN)
+  return tpm::BackEndOsx::getScheme();;
+#else
+  return tpm::BackEndFile::getScheme();
+#endif // defined(NDN_CXX_HAVE_OSX_SECURITY) && defined(NDN_CXX_WITH_OSX_KEYCHAIN)
+}
+
+const std::string&
+KeyChain::getDefaultPibLocator()
+{
+  if (!s_defaultPibLocator.empty())
+    return s_defaultPibLocator;
+
+  if (getenv("NDN_CLIENT_PIB") != nullptr) {
+    s_defaultPibLocator = getenv("NDN_CLIENT_PIB");
+  }
+  else {
+    ConfigFile config;
+    s_defaultPibLocator = config.getParsedConfiguration().get<std::string>("pib", getDefaultPibScheme() + ":");
+  }
+
+  return s_defaultPibLocator;
+}
+
+const std::string&
+KeyChain::getDefaultTpmLocator()
+{
+  if (!s_defaultTpmLocator.empty())
+    return s_defaultTpmLocator;
+
+  if (getenv("NDN_CLIENT_TPM") != nullptr) {
+    s_defaultTpmLocator = getenv("NDN_CLIENT_TPM");
+  }
+  else {
+    ConfigFile config;
+    s_defaultTpmLocator = config.getParsedConfiguration().get<std::string>("tpm", getDefaultTpmScheme() + ":");
+  }
+
+  return s_defaultTpmLocator;
+}
+
+
+// Other defaults
+
+const SigningInfo&
+KeyChain::getDefaultSigningInfo()
+{
+  static SigningInfo signingInfo;
+  return signingInfo;
+}
+
+const KeyParams&
+KeyChain::getDefaultKeyParams()
+{
+  static EcdsaKeyParams keyParams;
+  return keyParams;
+}
+
+//
+
+KeyChain::KeyChain()
+  : KeyChain(getDefaultPibLocator(), getDefaultTpmLocator(), true)
+{
+}
+
+KeyChain::KeyChain(const std::string& pibLocator, const std::string& tpmLocator, bool allowReset)
+{
+  // PIB Locator
+  std::string pibScheme, pibLocation;
+  std::tie(pibScheme, pibLocation) = parseAndCheckPibLocator(pibLocator);
+  std::string canonicalPibLocator = pibScheme + ":" + pibLocation;
+
+  // Create PIB
+  m_pib = createPib(canonicalPibLocator);
+  std::string oldTpmLocator;
+  try {
+    oldTpmLocator = m_pib->getTpmLocator();
+  }
+  catch (const Pib::Error&) {
+    // TPM locator is not set in PIB yet.
+  }
+
+  // TPM Locator
+  std::string tpmScheme, tpmLocation;
+  std::tie(tpmScheme, tpmLocation) = parseAndCheckTpmLocator(tpmLocator);
+  std::string canonicalTpmLocator = tpmScheme + ":" + tpmLocation;
+
+  if (canonicalPibLocator == getDefaultPibLocator()) {
+    // Default PIB must use default TPM
+    if (!oldTpmLocator.empty() && oldTpmLocator != getDefaultTpmLocator()) {
+      m_pib->reset();
+      canonicalTpmLocator = getDefaultTpmLocator();
+    }
+  }
+  else {
+    // non-default PIB check consistency
+    if (!oldTpmLocator.empty() && oldTpmLocator != canonicalTpmLocator) {
+      if (allowReset)
+        m_pib->reset();
+      else
+        BOOST_THROW_EXCEPTION(LocatorMismatchError("TPM locator supplied does not match TPM locator in PIB: " +
+                                                   oldTpmLocator + " != " + canonicalTpmLocator));
+    }
+  }
+
+  // note that key mismatch may still happen if the TPM locator is initially set to a
+  // wrong one or if the PIB was shared by more than one TPMs before.  This is due to the
+  // old PIB does not have TPM info, new pib should not have this problem.
+  m_tpm = createTpm(canonicalTpmLocator);
+  m_pib->setTpmLocator(canonicalTpmLocator);
+}
+
+KeyChain::~KeyChain() = default;
+
+// public: management
+
+Identity
+KeyChain::createIdentity(const Name& identityName, const KeyParams& params)
+{
+  Identity id = m_pib->addIdentity(identityName);
+
+  Key key;
+  try {
+    key = id.getDefaultKey();
+  }
+  catch (const Pib::Error&) {
+    key = createKey(id, params);
+  }
+
+  try {
+    key.getDefaultCertificate();
+  }
+  catch (const Pib::Error&) {
+    selfSign(key);
+  }
+
+  return id;
+}
+
+void
+KeyChain::deleteIdentity(const Identity& identity)
+{
+  BOOST_ASSERT(static_cast<bool>(identity));
+
+  Name identityName = identity.getName();
+
+  for (const auto& key : identity.getKeys()) {
+    m_tpm->deleteKey(key.getName());
+  }
+
+  m_pib->removeIdentity(identityName);
+}
+
+void
+KeyChain::setDefaultIdentity(const Identity& identity)
+{
+  BOOST_ASSERT(static_cast<bool>(identity));
+
+  m_pib->setDefaultIdentity(identity.getName());
+}
+
+Key
+KeyChain::createKey(const Identity& identity, const KeyParams& params)
+{
+  BOOST_ASSERT(static_cast<bool>(identity));
+
+  // create key in TPM
+  Name keyName = m_tpm->createKey(identity.getName(), params);
+
+  // set up key info in PIB
+  ConstBufferPtr pubKey = m_tpm->getPublicKey(keyName);
+  Key key = identity.addKey(pubKey->buf(), pubKey->size(), keyName);
+  selfSign(key);
+
+  return key;
+}
+
+void
+KeyChain::deleteKey(const Identity& identity, const Key& key)
+{
+  BOOST_ASSERT(static_cast<bool>(identity));
+  BOOST_ASSERT(static_cast<bool>(key));
+
+  Name keyName = key.getName();
+  if (identity.getName() != key.getIdentity()) {
+    BOOST_THROW_EXCEPTION(std::invalid_argument("Identity `" + identity.getName().toUri() + "` "
+                                                "does match key `" + keyName.toUri() + "`"));
+  }
+
+  identity.removeKey(keyName);
+  m_tpm->deleteKey(keyName);
+}
+
+void
+KeyChain::setDefaultKey(const Identity& identity, const Key& key)
+{
+  BOOST_ASSERT(static_cast<bool>(identity));
+  BOOST_ASSERT(static_cast<bool>(key));
+
+  if (identity.getName() != key.getIdentity())
+    BOOST_THROW_EXCEPTION(std::invalid_argument("Identity `" + identity.getName().toUri() + "` "
+                                                "does match key `" + key.getName().toUri() + "`"));
+
+  identity.setDefaultKey(key.getName());
+}
+
+void
+KeyChain::addCertificate(const Key& key, const Certificate& certificate)
+{
+  BOOST_ASSERT(static_cast<bool>(key));
+
+  if (key.getName() != certificate.getKeyName() ||
+      !std::equal(certificate.getContent().value_begin(), certificate.getContent().value_end(),
+                  key.getPublicKey().begin()))
+    BOOST_THROW_EXCEPTION(std::invalid_argument("Key `" + key.getName().toUri() + "` "
+                                                "does match certificate `" + certificate.getName().toUri() + "`"));
+
+  key.addCertificate(certificate);
+}
+
+void
+KeyChain::deleteCertificate(const Key& key, const Name& certificateName)
+{
+  BOOST_ASSERT(static_cast<bool>(key));
+
+  if (!Certificate::isValidName(certificateName)) {
+    BOOST_THROW_EXCEPTION(std::invalid_argument("Wrong certificate name `" + certificateName.toUri() + "`"));
+  }
+
+  key.removeCertificate(certificateName);
+}
+
+void
+KeyChain::setDefaultCertificate(const Key& key, const Certificate& cert)
+{
+  BOOST_ASSERT(static_cast<bool>(key));
+
+  try {
+    addCertificate(key, cert);
+  }
+  catch (const Pib::Error&) { // force to overwrite the existing certificates
+    key.removeCertificate(cert.getName());
+    addCertificate(key, cert);
+  }
+  key.setDefaultCertificate(cert.getName());
+}
+
+shared_ptr<SafeBag>
+KeyChain::exportSafeBag(const Certificate& certificate, const char* pw, size_t pwLen)
+{
+  Name identity = certificate.getIdentity();
+  Name keyName = certificate.getKeyName();
+
+  ConstBufferPtr encryptedKey;
+  try {
+    encryptedKey = m_tpm->exportPrivateKey(keyName, pw, pwLen);
+  }
+  catch (const tpm::BackEnd::Error&) {
+    BOOST_THROW_EXCEPTION(Error("Private `" + keyName.toUri() + "` key does not exist"));
+  }
+
+  return make_shared<SafeBag>(certificate, *encryptedKey);
+}
+
+void
+KeyChain::importSafeBag(const SafeBag& safeBag, const char* pw, size_t pwLen)
+{
+  Data certData = safeBag.getCertificate();
+  Certificate cert(std::move(certData));
+  Name identity = cert.getIdentity();
+  Name keyName = cert.getKeyName();
+  const Buffer publicKeyBits = cert.getPublicKey();
+
+  if (m_tpm->hasKey(keyName)) {
+    BOOST_THROW_EXCEPTION(Error("Private key `" + keyName.toUri() + "` already exists"));
+  }
+
+  try {
+    Identity existingId = m_pib->getIdentity(identity);
+    existingId.getKey(keyName);
+    BOOST_THROW_EXCEPTION(Error("Public key `" + keyName.toUri() + "` already exists"));
+  }
+  catch (const Pib::Error&) {
+    // Either identity or key doesn't exist. OK to import.
+  }
+
+  try {
+    m_tpm->importPrivateKey(keyName,
+                            safeBag.getEncryptedKeyBag().buf(), safeBag.getEncryptedKeyBag().size(),
+                            pw, pwLen);
+  }
+  catch (const std::runtime_error&) {
+    BOOST_THROW_EXCEPTION(Error("Fail to import private key `" + keyName.toUri() + "`"));
+  }
+
+  // check the consistency of private key and certificate
+  const uint8_t content[] = {0x01, 0x02, 0x03, 0x04};
+  ConstBufferPtr sigBits;
+  try {
+    sigBits = m_tpm->sign(content, 4, keyName, DigestAlgorithm::SHA256);
+  }
+  catch (const std::runtime_error&) {
+    m_tpm->deleteKey(keyName);
+    BOOST_THROW_EXCEPTION(Error("Invalid private key `" + keyName.toUri() + "`"));
+  }
+  bool isVerified = false;
+  {
+    using namespace transform;
+    PublicKey publicKey;
+    publicKey.loadPkcs8(publicKeyBits.buf(), publicKeyBits.size());
+    bufferSource(content, sizeof(content)) >> verifierFilter(DigestAlgorithm::SHA256, publicKey,
+                                                             sigBits->buf(), sigBits->size())
+                                           >> boolSink(isVerified);
+  }
+  if (!isVerified) {
+    m_tpm->deleteKey(keyName);
+    BOOST_THROW_EXCEPTION(Error("Certificate `" + cert.getName().toUri() + "` "
+                                "and private key `" + keyName.toUri() + "` do not match"));
+  }
+
+  Identity id = m_pib->addIdentity(identity);
+  Key key = id.addKey(cert.getPublicKey().buf(), cert.getPublicKey().size(), keyName);
+  key.addCertificate(cert);
+}
+
+
+// public: signing
+
+void
+KeyChain::sign(Data& data, const SigningInfo& params)
+{
+  Name keyName;
+  SignatureInfo sigInfo;
+  std::tie(keyName, sigInfo) = prepareSignatureInfo(params);
+
+  data.setSignature(Signature(sigInfo));
+
+  EncodingBuffer encoder;
+  data.wireEncode(encoder, true);
+
+  Block sigValue = sign(encoder.buf(), encoder.size(), keyName, params.getDigestAlgorithm());
+
+  data.wireEncode(encoder, sigValue);
+}
+
+void
+KeyChain::sign(Interest& interest, const SigningInfo& params)
+{
+  Name keyName;
+  SignatureInfo sigInfo;
+  std::tie(keyName, sigInfo) = prepareSignatureInfo(params);
+
+  Name signedName = interest.getName();
+  signedName.append(sigInfo.wireEncode()); // signatureInfo
+
+  Block sigValue = sign(signedName.wireEncode().value(), signedName.wireEncode().value_size(),
+                        keyName, params.getDigestAlgorithm());
+
+  sigValue.encode();
+  signedName.append(sigValue); // signatureValue
+  interest.setName(signedName);
+}
+
+Block
+KeyChain::sign(const uint8_t* buffer, size_t bufferLength, const SigningInfo& params)
+{
+  Name keyName;
+  SignatureInfo sigInfo;
+  std::tie(keyName, sigInfo) = prepareSignatureInfo(params);
+
+  return sign(buffer, bufferLength, keyName, params.getDigestAlgorithm());
+}
+
+// public: PIB/TPM creation helpers
+
+static inline std::tuple<std::string/*type*/, std::string/*location*/>
+parseLocatorUri(const std::string& uri)
+{
+  size_t pos = uri.find(':');
+  if (pos != std::string::npos) {
+    return std::make_tuple(uri.substr(0, pos), uri.substr(pos + 1));
+  }
+  else {
+    return std::make_tuple(uri, "");
+  }
+}
+
+std::tuple<std::string/*type*/, std::string/*location*/>
+KeyChain::parseAndCheckPibLocator(const std::string& pibLocator)
+{
+  std::string pibScheme, pibLocation;
+  std::tie(pibScheme, pibLocation) = parseLocatorUri(pibLocator);
+
+  if (pibScheme.empty()) {
+    pibScheme = getDefaultPibScheme();
+  }
+
+  auto pibFactory = getPibFactories().find(pibScheme);
+  if (pibFactory == getPibFactories().end()) {
+    BOOST_THROW_EXCEPTION(KeyChain::Error("PIB scheme `" + pibScheme + "` is not supported"));
+  }
+
+  return std::make_tuple(pibScheme, pibLocation);
+}
+
+unique_ptr<Pib>
+KeyChain::createPib(const std::string& pibLocator)
+{
+  std::string pibScheme, pibLocation;
+  std::tie(pibScheme, pibLocation) = parseAndCheckPibLocator(pibLocator);
+  auto pibFactory = getPibFactories().find(pibScheme);
+  BOOST_ASSERT(pibFactory != getPibFactories().end());
+  return unique_ptr<Pib>(new Pib(pibScheme, pibLocation, pibFactory->second(pibLocation)));
+}
+
+std::tuple<std::string/*type*/, std::string/*location*/>
+KeyChain::parseAndCheckTpmLocator(const std::string& tpmLocator)
+{
+  std::string tpmScheme, tpmLocation;
+  std::tie(tpmScheme, tpmLocation) = parseLocatorUri(tpmLocator);
+
+  if (tpmScheme.empty()) {
+    tpmScheme = getDefaultTpmScheme();
+  }
+  auto tpmFactory = getTpmFactories().find(tpmScheme);
+  if (tpmFactory == getTpmFactories().end()) {
+    BOOST_THROW_EXCEPTION(KeyChain::Error("TPM scheme `" + tpmScheme + "` is not supported"));
+  }
+
+  return std::make_tuple(tpmScheme, tpmLocation);
+}
+
+unique_ptr<Tpm>
+KeyChain::createTpm(const std::string& tpmLocator)
+{
+  std::string tpmScheme, tpmLocation;
+  std::tie(tpmScheme, tpmLocation) = parseAndCheckTpmLocator(tpmLocator);
+  auto tpmFactory = getTpmFactories().find(tpmScheme);
+  BOOST_ASSERT(tpmFactory != getTpmFactories().end());
+  return unique_ptr<Tpm>(new Tpm(tpmScheme, tpmLocation, tpmFactory->second(tpmLocation)));
+}
+
+// private: signing
+
+Certificate
+KeyChain::selfSign(Key& key)
+{
+  Certificate certificate;
+
+  // set name
+  Name certificateName = key.getName();
+  certificateName
+    .append("self")
+    .appendVersion();
+  certificate.setName(certificateName);
+
+  // set metainfo
+  certificate.setContentType(tlv::ContentType_Key);
+  certificate.setFreshnessPeriod(time::hours(1));
+
+  // set content
+  certificate.setContent(key.getPublicKey().buf(), key.getPublicKey().size());
+
+  // set signature-info
+  SignatureInfo sigInfo;
+  sigInfo.setKeyLocator(key.getName());
+  sigInfo.setSignatureType(getSignatureType(key.getKeyType(), DigestAlgorithm::SHA256));
+  sigInfo.setValidityPeriod(ValidityPeriod(time::system_clock::now(),
+                                           time::system_clock::now() + time::days(1000 * 3365)));
+  certificate.setSignature(Signature(sigInfo));
+
+  EncodingBuffer encoder;
+  certificate.wireEncode(encoder, true);
+  Block sigValue = sign(encoder.buf(), encoder.size(), key.getName(), DigestAlgorithm::SHA256);
+  certificate.wireEncode(encoder, sigValue);
+
+  key.addCertificate(certificate);
+  return certificate;
+}
+
+std::tuple<Name, SignatureInfo>
+KeyChain::prepareSignatureInfo(const SigningInfo& params)
+{
+  SignatureInfo sigInfo = params.getSignatureInfo();
+
+  Name identityName;
+  name::Component keyId;
+  Name certificateName;
+
+  pib::Identity identity;
+  pib::Key key;
+
+  switch (params.getSignerType()) {
+    case SigningInfo::SIGNER_TYPE_NULL: {
+      try {
+        identity = m_pib->getDefaultIdentity();
+      }
+      catch (const Pib::Error&) { // no default identity, use sha256 for signing.
+        sigInfo.setSignatureType(tlv::DigestSha256);
+        return std::make_tuple(SigningInfo::getDigestSha256Identity(), sigInfo);
+      }
+      break;
+    }
+    case SigningInfo::SIGNER_TYPE_ID: {
+      try {
+        identity = m_pib->getIdentity(params.getSignerName());
+      }
+      catch (const Pib::Error&) {
+        BOOST_THROW_EXCEPTION(InvalidSigningInfoError("Signing identity `" +
+                                                      params.getSignerName().toUri() + "` does not exist"));
+      }
+      break;
+    }
+    case SigningInfo::SIGNER_TYPE_KEY: {
+      Name identityName = extractIdentityFromKeyName(params.getSignerName());
+
+      try {
+        identity = m_pib->getIdentity(identityName);
+        key = identity.getKey(params.getSignerName());
+        identity = Identity(); // we will use the PIB key instance, so reset identity;
+      }
+      catch (const Pib::Error&) {
+        BOOST_THROW_EXCEPTION(InvalidSigningInfoError("Signing key `" +
+                                                      params.getSignerName().toUri() + "` does not exist"));
+      }
+      break;
+    }
+    case SigningInfo::SIGNER_TYPE_CERT: {
+      Name identityName = extractIdentityFromCertName(params.getSignerName());
+      Name keyName = extractKeyNameFromCertName(params.getSignerName());
+
+      try {
+        identity = m_pib->getIdentity(identityName);
+        key = identity.getKey(keyName);
+      }
+      catch (const Pib::Error&) {
+        BOOST_THROW_EXCEPTION(InvalidSigningInfoError("Signing certificate `" +
+                                                      params.getSignerName().toUri() + "` does not exist"));
+      }
+
+      break;
+    }
+    case SigningInfo::SIGNER_TYPE_SHA256: {
+      sigInfo.setSignatureType(tlv::DigestSha256);
+      return std::make_tuple(SigningInfo::getDigestSha256Identity(), sigInfo);
+    }
+    default: {
+      BOOST_THROW_EXCEPTION(InvalidSigningInfoError("Unrecognized signer type " +
+                                                    boost::lexical_cast<std::string>(params.getSignerType())));
+    }
+  }
+
+  if (!identity && !key) {
+    BOOST_THROW_EXCEPTION(InvalidSigningInfoError("Cannot determine signing parameters"));
+  }
+
+  if (identity && !key) {
+    try {
+      key = identity.getDefaultKey();
+    }
+    catch (const Pib::Error&) {
+      BOOST_THROW_EXCEPTION(InvalidSigningInfoError("Signing identity `" + identity.getName().toUri() +
+                                                    "` does not have default certificate"));
+    }
+  }
+
+  BOOST_ASSERT(key);
+
+  sigInfo.setSignatureType(getSignatureType(key.getKeyType(), params.getDigestAlgorithm()));
+  sigInfo.setKeyLocator(KeyLocator(key.getName()));
+  return std::make_tuple(key.getName(), sigInfo);
+}
+
+Block
+KeyChain::sign(const uint8_t* buf, size_t size,
+               const Name& keyName, DigestAlgorithm digestAlgorithm) const
+{
+  if (keyName == SigningInfo::getDigestSha256Identity())
+    return Block(tlv::SignatureValue, crypto::sha256(buf, size));
+
+  return Block(tlv::SignatureValue, m_tpm->sign(buf, size, keyName, digestAlgorithm));
+}
+
+tlv::SignatureTypeValue
+KeyChain::getSignatureType(KeyType keyType, DigestAlgorithm digestAlgorithm)
+{
+  switch (keyType) {
+  case KeyType::RSA:
+    return tlv::SignatureSha256WithRsa;
+  case KeyType::EC:
+    return tlv::SignatureSha256WithEcdsa;
+  default:
+    BOOST_THROW_EXCEPTION(Error("Unsupported key types"));
+  }
+}
+
+} // namespace v2
+} // namespace security
+} // namespace ndn
diff --git a/src/security/v2/key-chain.hpp b/src/security/v2/key-chain.hpp
new file mode 100644
index 0000000..ca394a5
--- /dev/null
+++ b/src/security/v2/key-chain.hpp
@@ -0,0 +1,508 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/**
+ * Copyright (c) 2013-2017 Regents of the University of California.
+ *
+ * This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
+ *
+ * ndn-cxx 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.
+ *
+ * ndn-cxx 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 ndn-cxx authors and contributors.
+ */
+
+#ifndef NDN_SECURITY_V2_KEY_CHAIN_HPP
+#define NDN_SECURITY_V2_KEY_CHAIN_HPP
+
+#include "certificate.hpp"
+#include "../key-params.hpp"
+#include "../pib/pib.hpp"
+#include "../safe-bag.hpp"
+#include "../signing-info.hpp"
+#include "../tpm/tpm.hpp"
+#include "../../interest.hpp"
+
+namespace ndn {
+namespace security {
+namespace v2 {
+
+/**
+ * @brief The interface of signing key management.
+ *
+ * The KeyChain class provides an interface to manage entities related to packet signing,
+ * such as Identity, Key, and Certificates.  It consists of two parts: a private key module
+ * (TPM) and a public key information base (PIB).  Managing signing key and its related
+ * entities through KeyChain interface guarantees the consistency between TPM and PIB.
+ */
+class KeyChain : noncopyable
+{
+public:
+  class Error : public std::runtime_error
+  {
+  public:
+    explicit
+    Error(const std::string& what)
+      : std::runtime_error(what)
+    {
+    }
+  };
+
+  /**
+   * @brief Error indicating that the supplied TPM locator does not match the locator stored in PIB.
+   */
+  class LocatorMismatchError : public Error
+  {
+  public:
+    explicit
+    LocatorMismatchError(const std::string& what)
+      : Error(what)
+    {
+    }
+  };
+
+  /**
+   * @brief Error indicating that the supplied SigningInfo is invalid.
+   */
+  class InvalidSigningInfoError : public Error
+  {
+  public:
+    explicit
+    InvalidSigningInfoError(const std::string& what)
+      : Error(what)
+    {
+    }
+  };
+
+  /**
+   * @brief Constructor to create KeyChain with default PIB and TPM.
+   *
+   * Default PIB and TPM are platform-dependent and can be overriden system-wide or
+   * individually for the user.
+   *
+   * @sa manpage ndn-client.conf
+   *
+   * @todo Add detailed description about config file behavior here
+   */
+  KeyChain();
+
+  /**
+   * @brief KeyChain constructor
+   *
+   * @sa manpage ndn-client.conf
+   *
+   * @param pibLocator PIB locator, e.g., pib-sqlite3:/example/dir
+   * @param tpmLocator TPM locator, e.g., tpm-memory:
+   * @param allowReset if true, the PIB will be reset when the supplied tpmLocator
+   *        mismatches the one in PIB
+   */
+  KeyChain(const std::string& pibLocator, const std::string& tpmLocator, bool allowReset = false);
+
+  ~KeyChain();
+
+  const Pib&
+  getPib() const
+  {
+    return *m_pib;
+  }
+
+  const Tpm&
+  getTpm() const
+  {
+    return *m_tpm;
+  }
+
+public: // Identity management
+  /**
+   * @brief Create an identity @p identityName.
+   *
+   * This method will check if the identity exists in PIB and whether the identity has a
+   * default key and default certificate.  If the identity does not exist, this method will
+   * create the identity in PIB.  If the identity's default key does not exist, this method
+   * will create a key pair and set it as the identity's default key.  If the key's default
+   * certificate is missing, this method will create a self-signed certificate for the key.
+   *
+   * If @p identityName did not exist and no default identity was selected before, the created
+   * identity will be set as the default identity
+   *
+   * @param identityName The name of the identity.
+   * @param params The key parameters if a key needs to be created for the identity (default:
+   *               ECDSA key with random key id)
+   * @return The created Identity instance.
+   */
+  Identity
+  createIdentity(const Name& identityName, const KeyParams& params = getDefaultKeyParams());
+
+  /**
+   * @brief delete @p identity.
+   *
+   * @pre @p identity must be valid.
+   * @post @p identity becomes invalid.
+   */
+  void
+  deleteIdentity(const Identity& identity);
+
+  /**
+   * @brief Set @p identity as the default identity.
+   * @pre @p identity must be valid.
+   */
+  void
+  setDefaultIdentity(const Identity& identity);
+
+public: // Key management
+  /**
+   * @brief Create a key for @p identity according to @p params.
+   *
+   * @param identity reference to a valid Identity object
+   * @param params The key parameters if a key needs to be created for the identity (default:
+   *               ECDSA key with random key id)
+   *
+   * If @p identity had no default key selected, the created key will be set as the default for
+   * this identity.
+   *
+   * This method will also create a self-signed certificate for the created key.
+   * @pre @p identity must be valid.
+   */
+  Key
+  createKey(const Identity& identity, const KeyParams& params = getDefaultKeyParams());
+
+  /**
+   * @brief Delete a key @p key of @p identity.
+   *
+   * @pre @p identity must be valid.
+   * @pre @p key must be valid.
+   * @post @p key becomes invalid.
+   * @throw std::invalid_argument @p key does not belong to @p identity
+   */
+  void
+  deleteKey(const Identity& identity, const Key& key);
+
+  /**
+   * @brief Set @p key as the default key of @p identity.
+   *
+   * @pre @p identity must be valid.
+   * @pre @p key must be valid.
+   * @throw std::invalid_argument @p key does not belong to @p identity
+   */
+  void
+  setDefaultKey(const Identity& identity, const Key& key);
+
+public: // Certificate management
+  /**
+   * @brief Add a certificate @p certificate for @p key
+   *
+   * If @p key had no default certificate selected, the added certificate will be set as the
+   * default certificate for this key.
+   *
+   * @note This method overwrites certificate with the same name, without considering the
+   *       implicit digest.
+   *
+   * @pre @p key must be valid.
+   * @throw std::invalid_argument @p key does not match @p certificate
+   * @throw Pib::Error a certificate with the same name already exists
+   */
+  void
+  addCertificate(const Key& key, const Certificate& certificate);
+
+  /**
+   * @brief delete a certificate with name @p certificateName of @p key.
+   *
+   * If the certificate @p certificateName does not exist, this method has no effect.
+   *
+   * @pre @p key must be valid.
+   * @throw std::invalid_argument @p certificateName does not follow certificate naming convention.
+   */
+  void
+  deleteCertificate(const Key& key, const Name& certificateName);
+
+  /**
+   * @brief Set @p cert as the default certificate of @p key.
+   *
+   * The certificate @p cert will be added to the @p key, potentially overriding existing
+   * certificate if it has the same name (without considering implicit digest).
+   *
+   * @pre @p key must be valid.
+   */
+  void
+  setDefaultCertificate(const Key& key, const Certificate& cert);
+
+public: // signing
+  /**
+   * @brief Sign data according to the supplied signing information.
+   *
+   * This method uses the supplied signing information @p params to create the SignatureInfo block:
+   * - it selects a private key and its certificate to sign the packet
+   * - sets the KeyLocator field with the certificate name, and
+   * - adds other requested information to the SignatureInfo block.
+   *
+   * After that, the method assigns the created SignatureInfo to the data packets, generate a
+   * signature and sets as part of the SignatureValue block.
+   *
+   * @note The exception throwing semantics has changed from v1::KeyChain.
+   *       If the requested identity/key/certificate does not exist, it will **not** be created
+   *       and exception will be thrown.
+   *
+   * @param data The data to sign
+   * @param params The signing parameters.
+   * @throw Error signing fails
+   * @throw InvalidSigningInfoError invalid @p params is specified or specified identity, key,
+   *                                or certificate does not exist
+   * @see SigningInfo
+   */
+  void
+  sign(Data& data, const SigningInfo& params = getDefaultSigningInfo());
+
+  /**
+   * @brief Sign interest according to the supplied signing information
+   *
+   * This method uses the supplied signing information @p params to create the SignatureInfo block:
+   * - it selects a private key and its certificate to sign the packet
+   * - sets the KeyLocator field with the certificate name, and
+   * - adds other requested information to the SignatureInfo block.
+   *
+   * After that, the method appends the created SignatureInfo to the interest name, generate a
+   * signature and appends it as part of the SignatureValue block to the interest name.
+   *
+   * @note The exception throwing semantics has changed from v1::KeyChain.  If the requested
+   *       identity/key/certificate does not exist, it will **not** be created and exception
+   *       will be thrown.
+   *
+   * @param interest The interest to sign
+   * @param params The signing parameters.
+   * @throw Error signing fails
+   * @throw InvalidSigningInfoError invalid @p params is specified or specified identity, key,
+   *                                or certificate does not exist
+   * @see SigningInfo
+   * @see docs/specs/signed-interest.rst
+   */
+  void
+  sign(Interest& interest, const SigningInfo& params = getDefaultSigningInfo());
+
+  /**
+   * @brief Sign buffer according to the supplied signing information @p params
+   *
+   * If @p params refers to an identity, the method selects the default key of the identity.
+   * If @p params refers to a key or certificate, the method select the corresponding key.
+   *
+   * @param buffer The buffer to sign
+   * @param bufferLength The buffer size
+   * @param params The signing parameters.
+   * @return a SignatureValue TLV block
+   * @throw Error signing fails
+   * @see SigningInfo
+   */
+  Block
+  sign(const uint8_t* buffer, size_t bufferLength, const SigningInfo& params = getDefaultSigningInfo());
+
+public: // export & import
+  /**
+   * @brief export a certificate of name @p certificateName and its corresponding private key.
+   *
+   * @param certificate The certificate to export.
+   * @param pw The password to secure the private key.
+   * @param pwLen The length of password.
+   * @return A SafeBag carrying the certificate and encrypted private key.
+   * @throw Error the certificate or private key does not exist
+   */
+  shared_ptr<SafeBag>
+  exportSafeBag(const Certificate& certificate, const char* pw, size_t pwLen);
+
+  /**
+   * @brief Import a pair of certificate and its corresponding private key encapsulated in a SafeBag.
+   *
+   * If the certificate and key are imported properly, the default setting will be updated as if
+   * a new key and certificate is added into KeyChain.
+   *
+   * @param safeBag The encoded data to import.
+   * @param pw The password to secure the private key.
+   * @param pwLen The length of password.
+   * @throw Error any of following conditions:
+   *              - the safebag cannot be decoded or its content does not match;
+   *              - private key cannot be imported;
+   *              - a private/public key of the same name already exists;
+   *              - a certificate of the same name already exists.
+   */
+  void
+  importSafeBag(const SafeBag& safeBag, const char* pw, size_t pwLen);
+
+NDN_CXX_PUBLIC_WITH_TESTS_ELSE_PRIVATE:
+  /**
+   * @brief Derive SignatureTypeValue according to key type and digest algorithm.
+   */
+  static tlv::SignatureTypeValue
+  getSignatureType(KeyType keyType, DigestAlgorithm digestAlgorithm);
+
+public: // PIB & TPM backend registry
+  /**
+   * @brief Register a new PIB backend
+   * @param scheme Name for the registered PIB backend scheme
+   *
+   * @note This interface is implementation detail and may change without notice.
+   */
+  template<class PibBackendType>
+  static void
+  registerPibBackend(const std::string& scheme);
+
+  /**
+   * @brief Register a new TPM backend
+   * @param scheme Name for the registered TPM backend scheme
+   *
+   * @note This interface is implementation detail and may change without notice.
+   */
+  template<class TpmBackendType>
+  static void
+  registerTpmBackend(const std::string& scheme);
+
+private:
+  typedef std::map<std::string, function<unique_ptr<pib::PibImpl>(const std::string& location)>> PibFactories;
+  typedef std::map<std::string, function<unique_ptr<tpm::BackEnd>(const std::string& location)>> TpmFactories;
+
+  static PibFactories&
+  getPibFactories();
+
+  static TpmFactories&
+  getTpmFactories();
+
+  static std::tuple<std::string/*type*/, std::string/*location*/>
+  parseAndCheckPibLocator(const std::string& pibLocator);
+
+  static std::tuple<std::string/*type*/, std::string/*location*/>
+  parseAndCheckTpmLocator(const std::string& tpmLocator);
+
+  static const std::string&
+  getDefaultPibScheme();
+
+  static const std::string&
+  getDefaultTpmScheme();
+
+  /**
+    * @brief Create a PIB according to @p pibLocator
+    */
+  static unique_ptr<Pib>
+  createPib(const std::string& pibLocator);
+
+  /**
+   * @brief Create a TPM according to @p tpmLocator
+   */
+  static unique_ptr<Tpm>
+  createTpm(const std::string& tpmLocator);
+
+NDN_CXX_PUBLIC_WITH_TESTS_ELSE_PRIVATE:
+  static const std::string&
+  getDefaultPibLocator();
+
+  static const std::string&
+  getDefaultTpmLocator();
+
+private: // signing
+  /**
+   * @brief Generate a self-signed certificate for a public key.
+   *
+   * The self-signed certificate will also be added into PIB
+   *
+   * @param keyName The name of the public key
+   * @return The generated certificate
+   */
+  Certificate
+  selfSign(Key& key);
+
+  /**
+   * @brief Prepare a SignatureInfo TLV according to signing information and return the signing
+   *        key name
+   *
+   * @param sigInfo The SignatureInfo to prepare.
+   * @param params The signing parameters.
+   * @return The signing key name and prepared SignatureInfo.
+   * @throw InvalidSigningInfoError when the requested signing method cannot be satisfied.
+   */
+  std::tuple<Name, SignatureInfo>
+  prepareSignatureInfo(const SigningInfo& params);
+
+  /**
+   * @brief Generate a SignatureValue block for a buffer @p buf with size @p size using
+   *        a key with name @p keyName and digest algorithm @p digestAlgorithm.
+   */
+  Block
+  sign(const uint8_t* buf, size_t size, const Name& keyName, DigestAlgorithm digestAlgorithm) const;
+
+public:
+  static const SigningInfo&
+  getDefaultSigningInfo();
+
+  static const KeyParams&
+  getDefaultKeyParams();
+
+private:
+  std::unique_ptr<Pib> m_pib;
+  std::unique_ptr<Tpm> m_tpm;
+
+  static std::string s_defaultPibLocator;
+  static std::string s_defaultTpmLocator;
+};
+
+template<class PibType>
+inline void
+KeyChain::registerPibBackend(const std::string& scheme)
+{
+  getPibFactories().emplace(scheme, [] (const std::string& locator) {
+      return unique_ptr<pib::PibImpl>(new PibType(locator));
+    });
+}
+
+template<class TpmType>
+inline void
+KeyChain::registerTpmBackend(const std::string& scheme)
+{
+  getTpmFactories().emplace(scheme, [] (const std::string& locator) {
+      return unique_ptr<tpm::BackEnd>(new TpmType(locator));
+    });
+}
+
+/**
+ * @brief Register Pib backend class in KeyChain
+ *
+ * This macro should be placed once in the implementation file of the
+ * Pib backend class within the namespace where the type is declared.
+ *
+ * @note This interface is implementation detail and may change without notice.
+ */
+#define NDN_CXX_V2_KEYCHAIN_REGISTER_PIB_BACKEND(PibType)     \
+static class NdnCxxAuto ## PibType ## PibRegistrationClass    \
+{                                                             \
+public:                                                       \
+  NdnCxxAuto ## PibType ## PibRegistrationClass()             \
+  {                                                           \
+    ::ndn::security::v2::KeyChain::registerPibBackend<PibType>(PibType::getScheme()); \
+  }                                                           \
+} ndnCxxAuto ## PibType ## PibRegistrationVariable
+
+/**
+ * @brief Register Tpm backend class in KeyChain
+ *
+ * This macro should be placed once in the implementation file of the
+ * Tpm backend class within the namespace where the type is declared.
+ *
+ * @note This interface is implementation detail and may change without notice.
+ */
+#define NDN_CXX_V2_KEYCHAIN_REGISTER_TPM_BACKEND(TpmType)     \
+static class NdnCxxAuto ## TpmType ## TpmRegistrationClass    \
+{                                                             \
+public:                                                       \
+  NdnCxxAuto ## TpmType ## TpmRegistrationClass()             \
+  {                                                           \
+    ::ndn::security::v2::KeyChain::registerTpmBackend<TpmType>(TpmType::getScheme()); \
+  }                                                           \
+} ndnCxxAuto ## TpmType ## TpmRegistrationVariable
+
+} // namespace v2
+} // namespace security
+} // namespace ndn
+
+#endif // NDN_SECURITY_V2_KEY_CHAIN_HPP
