diff --git a/tools/ndnsec/cert-gen.cpp b/tools/ndnsec/cert-gen.cpp
new file mode 100644
index 0000000..f1b2512
--- /dev/null
+++ b/tools/ndnsec/cert-gen.cpp
@@ -0,0 +1,214 @@
+/* -*- 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 "ndnsec.hpp"
+#include "util.hpp"
+
+namespace ndn {
+namespace ndnsec {
+
+int
+ndnsec_cert_gen(int argc, char** argv)
+{
+  using boost::tokenizer;
+  using boost::escaped_list_separator;
+
+  namespace po = boost::program_options;
+
+  security::v1::KeyChain keyChain;
+
+  std::string notBeforeStr;
+  std::string notAfterStr;
+  std::string subjectName;
+  std::string requestFile("-");
+  Name signId;
+  std::string subjectInfo;
+  std::vector<std::string> signedInfo;
+  Name certPrefix = security::v1::KeyChain::DEFAULT_PREFIX; // to avoid displaying the default value
+
+  po::options_description description(
+    "General Usage\n"
+    "  ndnsec cert-gen [-h] [-S date] [-E date] [-N subject-name] [-I subject-info] "
+        "[-s sign-id] [-p cert-prefix] request\n"
+    "General options");
+
+  description.add_options()
+    ("help,h", "produce help message")
+    ("not-before,S",   po::value<std::string>(&notBeforeStr),
+                       "certificate starting date, YYYYMMDDhhmmss (default: now)")
+    ("not-after,E",    po::value<std::string>(&notAfterStr),
+                       "certificate ending date, YYYYMMDDhhmmss (default: now + 365 days)")
+    ("subject-name,N", po::value<std::string>(&subjectName),
+                       "subject name")
+    ("subject-info,I", po::value<std::string>(&subjectInfo),
+                       "(deprecated, uses 'signed-info') subject info, pairs of OID and string "
+                       " description: \"2.5.4.10 'University of California, Los Angeles'\"")
+    ("signed-info",    po::value<std::vector<std::string> >(&signedInfo),
+                       "a pair of OID and string (must be separated by a single space), e.g., "
+                       "\"2.5.4.10 University of California, Los Angeles\". "
+                       "May be repeated multiple times")
+    ("sign-id,s",      po::value<Name>(&signId)->default_value(keyChain.getDefaultIdentity()),
+                       "signing identity")
+    ("cert-prefix,p",  po::value<Name>(&certPrefix),
+                       "cert prefix, which is the part of certificate name before "
+                       "KEY component")
+    ("request,r",      po::value<std::string>(&requestFile)->default_value("-"),
+                       "request file name, - for stdin")
+    ;
+
+  po::positional_options_description p;
+  p.add("request", 1);
+
+  po::variables_map vm;
+  try {
+    po::store(po::command_line_parser(argc, argv).options(description).positional(p).run(), vm);
+    po::notify(vm);
+  }
+  catch (const std::exception& e) {
+    std::cerr << "ERROR: " << e.what() << std::endl;
+    return 1;
+  }
+
+  if (vm.count("help") != 0) {
+    std::cout << description << std::endl;
+    return 0;
+  }
+
+  if (vm.count("subject-name") == 0) {
+    std::cerr << "ERROR: subject name must be specified" << std::endl
+              << std::endl
+              << description << std::endl;
+    return 1;
+  }
+
+  std::vector<security::v1::CertificateSubjectDescription> subjectDescription;
+  subjectDescription.push_back(security::v1::CertificateSubjectDescription(oid::ATTRIBUTE_NAME, subjectName));
+
+  // 'subjectInfo' is deprecated and the following block will be removed eventually
+  tokenizer<escaped_list_separator<char>> subjectInfoItems(subjectInfo,
+                                                           escaped_list_separator<char>("\\", " \t",
+                                                                                        "'\""));
+
+  tokenizer<escaped_list_separator<char>>::iterator it = subjectInfoItems.begin();
+
+  while (it != subjectInfoItems.end()) {
+    std::string oid = *it;
+
+    it++;
+    if (it == subjectInfoItems.end()) {
+      std::cerr << "ERROR: unmatched info for oid [" << oid << "]" << std::endl;
+      return 1;
+    }
+
+    std::string value = *it;
+
+    subjectDescription.push_back(security::v1::CertificateSubjectDescription(Oid(oid), value));
+
+    it++;
+  }
+
+  // new 'signedInfo' processing
+  for (std::vector<std::string>::const_iterator info = signedInfo.begin(); info != signedInfo.end();
+       ++info) {
+    size_t pos = info->find(" ");
+    if (pos == std::string::npos) {
+      std::cerr << "ERROR: incorrectly formatted signed info block [" << *info << "]" << std::endl;
+      return 1;
+    }
+    Oid oid(info->substr(0, pos));
+    std::string value = info->substr(pos + 1);
+
+    subjectDescription.push_back(security::v1::CertificateSubjectDescription(oid, value));
+  }
+
+  time::system_clock::TimePoint notBefore;
+  time::system_clock::TimePoint notAfter;
+
+  if (vm.count("not-before") == 0) {
+    notBefore = time::system_clock::now();
+  }
+  else {
+    notBefore = time::fromIsoString(notBeforeStr.substr(0, 8) + "T" + notBeforeStr.substr(8, 6));
+  }
+
+  if (vm.count("not-after") == 0) {
+    notAfter = notBefore + time::days(365);
+  }
+  else {
+    notAfter = time::fromIsoString(notAfterStr.substr(0, 8) + "T" + notAfterStr.substr(8, 6));
+
+    if (notAfter < notBefore) {
+      std::cerr << "ERROR: not-before cannot be later than not-after" << std::endl
+                << std::endl
+                << description << std::endl;
+      return 1;
+    }
+  }
+
+  if (vm.count("request") == 0) {
+    std::cerr << "ERROR: request file must be specified" << std::endl
+              << std::endl
+              << description << std::endl;
+    return 1;
+  }
+
+  shared_ptr<security::v1::IdentityCertificate> selfSignedCertificate = getIdentityCertificate(requestFile);
+
+  if (selfSignedCertificate == nullptr) {
+    std::cerr << "ERROR: input error" << std::endl;
+    return 1;
+  }
+
+  Name keyName = selfSignedCertificate->getPublicKeyName();
+
+  shared_ptr<security::v1::IdentityCertificate> certificate =
+    keyChain.prepareUnsignedIdentityCertificate(keyName, selfSignedCertificate->getPublicKeyInfo(),
+                                                signId, notBefore, notAfter, subjectDescription,
+                                                certPrefix);
+
+  if (certificate == nullptr) {
+    std::cerr << "ERROR: key name is not formated correctly or does not match certificate name"
+              << std::endl;
+    return 1;
+  }
+
+  keyChain.createIdentity(signId);
+  Name signingCertificateName = keyChain.getDefaultCertificateNameForIdentity(signId);
+  keyChain.sign(*certificate,
+                security::SigningInfo(security::SigningInfo::SIGNER_TYPE_CERT,
+                                      signingCertificateName));
+
+  Block wire = certificate->wireEncode();
+
+  namespace t = security::transform;
+  try {
+    t::bufferSource(wire.wire(), wire.size()) >> t::base64Encode(true) >> t::streamSink(std::cout);
+  }
+  catch (const security::transform::Error& e) {
+    std::cerr << "ERROR: " << e.what() << std::endl;
+    return 1;
+  }
+
+  return 0;
+}
+
+} // namespace ndnsec
+} // namespace ndn
