diff --git a/ChangeLog.md b/ChangeLog.md
--- a/ChangeLog.md
+++ b/ChangeLog.md
@@ -1,5 +1,16 @@
 # ChangeLog for hpke
 
+## 0.2.1
+
+* `Show EncodedSecretKey` no longer prints the key.  `Show` is what `print`,
+  a message built with `error`, an exception and a test framework's failure
+  output all reach for, so it is the instance a key travels on when nobody
+  meant to send it anywhere; it now renders `<secret>`, and
+  `Crypto.Debug.debugShow` returns the hexadecimal it used to.
+  `EncodedPublicKey` is unchanged.
+  [#2](https://github.com/kazu-yamamoto/hpke/pull/2)
+* The lower bound on crypton moves to 2.0, which is where `Crypto.Debug` is.
+
 ## 0.2.0
 
 * Breaking change: `exportS` and `exportR` return `Either HPKEError Key`
diff --git a/Crypto/HPKE/Types.hs b/Crypto/HPKE/Types.hs
--- a/Crypto/HPKE/Types.hs
+++ b/Crypto/HPKE/Types.hs
@@ -38,6 +38,7 @@
 ) where
 
 import Control.Exception (Exception)
+import Crypto.Debug (DebugShow (..))
 import Crypto.ECC (SharedSecret (..))
 import Crypto.Error (CryptoFailable (..))
 import Crypto.Hash.IO (hashDigestSize)
@@ -112,8 +113,12 @@
 instance Show EncodedPublicKey where
     show (EncodedPublicKey pk) = showBS16 pk
 
+-- | The key material is not shown.  Use 'Crypto.Debug.debugShow' to see it.
 instance Show EncodedSecretKey where
-    show (EncodedSecretKey pk) = showBS16 pk
+    show _ = "<secret>"
+
+instance DebugShow EncodedSecretKey where
+    debugShow (EncodedSecretKey sk) = showBS16 sk
 
 instance IsString EncodedPublicKey where
     fromString = EncodedPublicKey . fromString
diff --git a/hpke.cabal b/hpke.cabal
--- a/hpke.cabal
+++ b/hpke.cabal
@@ -1,6 +1,6 @@
 cabal-version:      >=1.10
 name:               hpke
-version:            0.2.0
+version:            0.2.1
 license:            BSD3
 license-file:       LICENSE
 maintainer:         kazu@iij.ad.jp
@@ -32,7 +32,7 @@
         base >=4.7 && <5,
         base16-bytestring,
         bytestring,
-        crypton >= 1.1.0 && <2.1,
+        crypton >= 2.0 && <2.2,
         ram
 
     default-extensions: Strict StrictData
@@ -48,6 +48,7 @@
                         A4Spec
                         A5Spec
                         A6Spec
+                        SecretSpec
                         Test
 
     default-language:   Haskell2010
@@ -58,5 +59,6 @@
         QuickCheck,
         bytestring,
         base16-bytestring,
+        crypton,
         hpke,
         hspec
diff --git a/test/SecretSpec.hs b/test/SecretSpec.hs
new file mode 100644
--- /dev/null
+++ b/test/SecretSpec.hs
@@ -0,0 +1,21 @@
+{-# LANGUAGE OverloadedStrings #-}
+
+module SecretSpec where
+
+import Crypto.Debug (debugShow)
+import Crypto.HPKE
+import Data.List (isInfixOf)
+import Test.Hspec
+
+-- | A secret key is what a caller stores and what a debugging line prints,
+-- so 'Show' does not render it and 'debugShow' does.
+spec :: Spec
+spec = describe "Show of an encoded key" $ do
+    it "does not print a secret key" $ do
+        show sk `shouldBe` "<secret>"
+        hex `isInfixOf` debugShow sk `shouldBe` True
+    it "still prints a public key" $
+        hex `isInfixOf` show (EncodedPublicKey "\x01\x23\x45\x67") `shouldBe` True
+  where
+    sk = EncodedSecretKey "\x01\x23\x45\x67"
+    hex = "01234567"
