diff --git a/lib/secrets.js b/lib/secrets.js
index 1dffcad9f01dee38e71acf309259d98ffce712ba..32adfcb6cd7204485224a35978d29aca057a51da 100644
--- a/lib/secrets.js
+++ b/lib/secrets.js
@@ -36,7 +36,8 @@
 const
 path = require('path'),
 fs = require('fs'),
-jwk = require('jwcrypto/jwk');
+jwk = require('jwcrypto/jwk'),
+jwt = require('jwcrypto/jwt');
 
 exports.generate = function(chars) {
   var str = "";
@@ -92,29 +93,31 @@ exports.loadSecretKey = function(name, dir) {
   return jwk.SecretKey.deserialize(secret);
 }
 
-exports.publicKeyCreationDate = function(name, dir) {
-  name = checkName(name);
-  dir = checkDir(dir);
-  var p = path.join(dir, name + ".publickey");
-  var stats = fs.statSync(p);
-  return stats.ctime;
-};
-
-exports.loadPublicKey = function(name, dir) {
+function readAndParseCert(name, dir) {
   name = checkName(name);
   dir = checkDir(dir);
-  var p = path.join(dir, name + ".publickey");
-  var secret = undefined;
+  var p = path.join(dir, name + ".cert");
+  var cert = undefined;
 
   // may throw
-  secret = fs.readFileSync(p).toString();
+  cert = fs.readFileSync(p).toString();
 
-  if (secret === undefined) {
+  if (cert === undefined) {
     return null;
   }
 
   // parse it
   // it should be a JSON structure with alg and serialized key
   // {alg: <ALG>, value: <SERIALIZED_KEY>}
-  return jwk.PublicKey.deserialize(secret);
+  var tok = new jwt.JWT();
+  tok.parse(cert);
+  return JSON.parse(new Buffer(tok.payloadSegment, 'base64').toString());
 }
+
+exports.publicKeyCreationDate = function(name, dir) {
+  return new Date(readAndParseCert(name, dir).iat);
+};
+
+exports.loadPublicKey = function(name, dir) {
+  return jwk.PublicKey.deserialize(JSON.stringify(readAndParseCert(name, dir)['public-key']));
+};
diff --git a/package.json b/package.json
index 9c1befbeff1aae27e565118a5b130276ce42b76c..7c1097c1824c00cf08a3e4e1825c3a77b0d1c957 100644
--- a/package.json
+++ b/package.json
@@ -25,7 +25,7 @@
     , "colors" : "0.5.0"
     , "sax" : "0.2.3"
     , "mimelib-noiconv" : "0.1.3"
-    , "jwcrypto": "https://github.com/mozilla/jwcrypto/tarball/083132cb"
+    , "jwcrypto": "https://github.com/mozilla/jwcrypto/tarball/e02d4ea"
     , "postprocess": "0.0.3"
     , "urlparse": "0.0.1"
   }
diff --git a/scripts/generate_ephemeral_keys.sh b/scripts/generate_ephemeral_keys.sh
index ee48695673b756031ae5ec4ad039be968c03b620..05e79374dcc711ccd937a24c068ff3474315d170 100755
--- a/scripts/generate_ephemeral_keys.sh
+++ b/scripts/generate_ephemeral_keys.sh
@@ -10,14 +10,25 @@ if [ -f $VAR/root.publickey ] ; then
 fi
 
 GENERATE_KEYPAIR=`which generate-keypair 2> /dev/null`
+CERTIFY=`which certify 2> /dev/null`
 
 if [ ! -x "$GENERATE_KEYPAIR" ] ; then
     echo "can't find generate-keypair from the jwcrypto package.  try: npm install"
     exit 1
 fi
 
+if [ ! -x "$CERTIFY" ] ; then
+    echo "can't find certify from the jwcrypto package.  try: rm -rf node_modules && npm install"
+    exit 1
+fi
+
 echo '*** Generating ephemeral keys used for testing ***'
 $GENERATE_KEYPAIR -k 128 -a rsa
 mkdir -p $VAR
-mv key.publickey $VAR/root.publickey
+
+# public key will be stored as a self signed certificate with an embedded
+# creation date (so that if the key is updated, we can revoke outstanding
+# certificates - GH-599 & GH-600)
+$CERTIFY -s key.secretkey -p key.publickey > $VAR/root.cert
+rm key.publickey
 mv key.secretkey $VAR/root.secretkey