diff --git a/src/Microsoft.AspNet.DataProtection/KeyManagement/XmlKeyManager.cs b/src/Microsoft.AspNet.DataProtection/KeyManagement/XmlKeyManager.cs
index 2465348513..7ea42e2737 100644
--- a/src/Microsoft.AspNet.DataProtection/KeyManagement/XmlKeyManager.cs
+++ b/src/Microsoft.AspNet.DataProtection/KeyManagement/XmlKeyManager.cs
@@ -204,7 +204,12 @@ namespace Microsoft.AspNet.DataProtection.KeyManagement
{
foreach (var key in keyIdToKeyMap.Values)
{
- if (key.CreationDate <= mostRecentMassRevocationDate)
+ // The contract of IKeyManager.RevokeAllKeys is that keys created *strictly before* the
+ // revocation date are revoked. The system clock isn't very granular, and if this were
+ // a less-than-or-equal check we could end up with the weird case where a revocation
+ // immediately followed by a key creation results in a newly-created revoked key (since
+ // the clock hasn't yet stepped).
+ if (key.CreationDate < mostRecentMassRevocationDate)
{
key.SetRevoked();
if (_logger.IsVerboseLevelEnabled())
diff --git a/test/Microsoft.AspNet.DataProtection.Test/KeyManagement/XmlKeyManagerTests.cs b/test/Microsoft.AspNet.DataProtection.Test/KeyManagement/XmlKeyManagerTests.cs
index 1fa9079564..559c5cc0be 100644
--- a/test/Microsoft.AspNet.DataProtection.Test/KeyManagement/XmlKeyManagerTests.cs
+++ b/test/Microsoft.AspNet.DataProtection.Test/KeyManagement/XmlKeyManagerTests.cs
@@ -403,7 +403,7 @@ namespace Microsoft.AspNet.DataProtection.KeyManagement
- 2016-01-01T00:00:00Z
+ 2017-01-01T00:00:00Z