diff --git a/ChangeLog.md b/ChangeLog.md
--- a/ChangeLog.md
+++ b/ChangeLog.md
@@ -1,9 +1,23 @@
 # Changelog for `password`
 
+## 3.0.4.0
+
+-   Support `base64` package up to and including `base64-1.0`.
+-   Added the Cabal flags `crypton` and `cryptonite` to choose which dependency to
+    build with. Right now the default is `cryptonite` and setting `crypton` changes
+    it to `crypton`. Setting the `cryptonite` flag does nothing at the moment, but
+    will replace the `crypton` flag in a future major release, so if you want to keep
+    using the `cryptonite` package you should start building with this flag.
+    When the flags get switched the `crypton` package will be the default and the
+    `crypton` flag will turn into a no-op, and you'll have to supply the `cryptonite`
+    flag to build with the `cryptonite` package.
+    Thanks to [@Vlix](https://github.com/Vlix)
+    [#74](https://github.com/cdepillabout/password/pull/74)
+
 ## 3.0.3.0
 
--  Added `bcrypt` `defaultParams` used by `hashPassword`
-  Thanks to [@blackheaven](https://github.com/blackheaven)
+-   Added `bcrypt` `defaultParams` used by `hashPassword`
+    Thanks to [@blackheaven](https://github.com/blackheaven)
     [#70](https://github.com/cdepillabout/password/pull/70)
 
 ## 3.0.2.2
diff --git a/password.cabal b/password.cabal
--- a/password.cabal
+++ b/password.cabal
@@ -1,7 +1,7 @@
 cabal-version: 1.12
 
 name:           password
-version:        3.0.3.0
+version:        3.0.4.0
 category:       Data
 synopsis:       Hashing and checking of passwords
 description:
@@ -47,22 +47,34 @@
     ChangeLog.md
 
 flag argon2
-  description: Compile with argon2 support?
+  description: Compile with Argon2 support?
   default: True
   manual: True
 
 flag bcrypt
-  description: Compile with Scrypt support?
+  description: Compile with bcrypt support?
   default: True
   manual: True
 
+flag crypton
+  description: Use the [crypton] library as the cryptographic backend.
+  default: False
+  manual: True
+
+flag cryptonite
+  description:
+    Use the [cryptonite] library as the cryptographic backend.
+    (Does nothing until a future major version)
+  default: False
+  manual: True
+
 flag pbkdf2
   description: Compile with PBKDF2 support?
   default: True
   manual: True
 
 flag scrypt
-  description: Compile with Scrypt support?
+  description: Compile with scrypt support?
   default: True
   manual: True
 
@@ -98,9 +110,8 @@
       Data.Password.Internal
   build-depends:
       base        >= 4.9      && < 5
-    , base64      >= 0.3      && < 0.5
+    , base64      >= 0.3      && < 1.1
     , bytestring  >= 0.9      && < 0.13
-    , cryptonite  >= 0.15.1   && < 0.31
     , memory                     < 1
     , password-types             < 2
     , template-haskell
@@ -109,6 +120,15 @@
       -Wall
   default-language:
       Haskell2010
+  -- At some future major version bump, this should
+  -- be changed to the [cryptonite] flag and that
+  -- `if flag(cryptonite) build-depends: cryptonite`
+  if flag(crypton)
+    build-depends:
+      crypton     >= 0.31   && < 0.35
+  else
+    build-depends:
+      cryptonite  >= 0.15.1   && < 0.31
 
 test-suite doctests
   type:
@@ -173,7 +193,6 @@
     , base64
     , password-types
     , bytestring
-    , cryptonite
     , memory
     , quickcheck-instances
     , scrypt
@@ -196,3 +215,12 @@
   if flag(scrypt)
     cpp-options:
       -DCABAL_FLAG_scrypt
+  -- At some future major version bump, this should
+  -- be changed to the [cryptonite] flag and that
+  -- `if flag(cryptonite) build-depends: cryptonite`
+  if flag(crypton)
+    build-depends:
+      crypton
+  else
+    build-depends:
+      cryptonite
diff --git a/src/Data/Password/Argon2.hs b/src/Data/Password/Argon2.hs
--- a/src/Data/Password/Argon2.hs
+++ b/src/Data/Password/Argon2.hs
@@ -74,6 +74,9 @@
 import Control.Monad.IO.Class (MonadIO (liftIO))
 import Crypto.Error (throwCryptoError)
 import Crypto.KDF.Argon2 as Argon2 (Options (..), Variant (..), Version (..), hash)
+#if MIN_VERSION_base64(1,0,0)
+import Data.Base64.Types (extractBase64)
+#endif
 import Data.ByteArray (Bytes, constEq, convert)
 import Data.ByteString as B (ByteString, length)
 import Data.ByteString.Base64 (encodeBase64)
@@ -205,7 +208,11 @@
     , encodeWithoutPadding key
     ]
   where
+#if MIN_VERSION_base64(1,0,0)
+    encodeWithoutPadding = T.dropWhileEnd (== '=') . extractBase64 . encodeBase64
+#else
     encodeWithoutPadding = T.dropWhileEnd (== '=') . encodeBase64
+#endif
     parameters = T.intercalate ","
         [ "m=" <> showT argon2MemoryCost
         , "t=" <> showT argon2TimeCost
diff --git a/src/Data/Password/Internal.hs b/src/Data/Password/Internal.hs
--- a/src/Data/Password/Internal.hs
+++ b/src/Data/Password/Internal.hs
@@ -28,7 +28,11 @@
 import Crypto.Random (getRandomBytes)
 import Data.ByteArray (Bytes, convert)
 import Data.ByteString (ByteString)
+#if MIN_VERSION_base64(1,0,0)
+import Data.ByteString.Base64 (decodeBase64Untyped)
+#else
 import Data.ByteString.Base64 (decodeBase64)
+#endif
 #if !MIN_VERSION_base(4,13,0)
 import Data.Semigroup ((<>))
 #endif
@@ -91,7 +95,11 @@
 
 -- | Decodes a base64 'Text' to a regular 'ByteString' (if possible)
 from64 :: Text -> Maybe ByteString
+#if MIN_VERSION_base64(1,0,0)
+from64 = toMaybe . decodeBase64Untyped . encodeUtf8
+#else
 from64 = toMaybe . decodeBase64 . encodeUtf8
+#endif
   where
     toMaybe = either (const Nothing) Just
 {-# INLINE from64 #-}
@@ -108,7 +116,12 @@
 
 -- | (UNSAFE) Pad a base64 text to "length `rem` 4 == 0" with "="
 --
+#if MIN_VERSION_base64(1,0,0)
+-- >>> import Data.Base64.Types (extractBase64)
+-- prop> \bs -> let b64 = extractBase64 (encodeBase64 bs) in unsafePad64 (T.dropWhileEnd (== '=') b64) == b64
+#else
 -- prop> \bs -> let b64 = encodeBase64 bs in unsafePad64 (T.dropWhileEnd (== '=') b64) == b64
+#endif
 unsafePad64 :: Text -> Text
 unsafePad64 t
     | remains == 0 = t
diff --git a/src/Data/Password/PBKDF2.hs b/src/Data/Password/PBKDF2.hs
--- a/src/Data/Password/PBKDF2.hs
+++ b/src/Data/Password/PBKDF2.hs
@@ -1,3 +1,4 @@
+{-# LANGUAGE CPP #-}
 {-# LANGUAGE LambdaCase #-}
 {-# LANGUAGE OverloadedStrings #-}
 {-# LANGUAGE RecordWildCards #-}
@@ -72,9 +73,12 @@
 import Control.Monad.IO.Class (MonadIO(liftIO))
 import Crypto.Hash.Algorithms as Crypto (MD5(..))
 import Crypto.KDF.PBKDF2 as PBKDF2
+#if MIN_VERSION_base64(1,0,0)
+import Data.Base64.Types (extractBase64)
+#endif
 import Data.ByteArray (ByteArray, ByteArrayAccess, Bytes, constEq, convert)
 import Data.ByteString (ByteString)
-import qualified Data.ByteString.Base64 as Base64
+import Data.ByteString.Base64 (encodeBase64)
 import qualified Data.ByteString.Char8 as C8 (length)
 import Data.Maybe (fromMaybe)
 import Data.Text (Text)
@@ -186,7 +190,11 @@
     , b64 key
     ]
   where
-    b64 = Base64.encodeBase64
+#if MIN_VERSION_base64(1,0,0)
+    b64 = extractBase64 . encodeBase64
+#else
+    b64 = encodeBase64
+#endif
     key = hashPasswordWithSalt' params s pass
 
 -- | Only for internal use
@@ -247,18 +255,16 @@
     -- "pbkdf2:sha256:150000:etc.etc."
     let passHash' = fromMaybe passHash $ "pbkdf2:" `T.stripPrefix` passHash
         paramList = T.split (== ':') passHash'
-    guard $ length paramList == 4
-    let [ algT,
-          iterationsT,
-          salt64,
-          hashedKey64 ] = paramList
-    pbkdf2Algorithm <- textToAlg algT
-    pbkdf2Iterations <- readT iterationsT
-    salt <- from64 salt64
-    hashedKey <- from64 hashedKey64
-    let pbkdf2OutputLength = fromIntegral $ C8.length hashedKey
-        pbkdf2Salt = fromIntegral $ C8.length salt
-    return (PBKDF2Params{..}, Salt salt, hashedKey)
+    case paramList of
+        [algT, iterationsT, salt64, hashedKey64] -> do
+            pbkdf2Algorithm <- textToAlg algT
+            pbkdf2Iterations <- readT iterationsT
+            salt <- from64 salt64
+            hashedKey <- from64 hashedKey64
+            let pbkdf2OutputLength = fromIntegral $ C8.length hashedKey
+                pbkdf2Salt = fromIntegral $ C8.length salt
+            return (PBKDF2Params{..}, Salt salt, hashedKey)
+        _ -> Nothing
 
 -- | Extracts 'PBKDF2Params' from a 'PasswordHash' 'PBKDF2'.
 --
diff --git a/src/Data/Password/Scrypt.hs b/src/Data/Password/Scrypt.hs
--- a/src/Data/Password/Scrypt.hs
+++ b/src/Data/Password/Scrypt.hs
@@ -1,3 +1,4 @@
+{-# LANGUAGE CPP #-}
 {-# LANGUAGE OverloadedStrings #-}
 {-# LANGUAGE RecordWildCards #-}
 {-|
@@ -65,6 +66,9 @@
 import Control.Monad (guard)
 import Control.Monad.IO.Class (MonadIO(liftIO))
 import Crypto.KDF.Scrypt as Scrypt (Parameters(..), generate)
+#if MIN_VERSION_base64(1,0,0)
+import Data.Base64.Types (extractBase64)
+#endif
 import Data.ByteArray (Bytes, constEq, convert)
 import Data.ByteString (ByteString)
 import Data.ByteString.Base64 (encodeBase64)
@@ -180,11 +184,16 @@
     [ showT scryptRounds
     , showT scryptBlockSize
     , showT scryptParallelism
-    , encodeBase64 salt
-    , encodeBase64 key
+    , toB64 salt
+    , toB64 key
     ]
   where
     key = hashPasswordWithSalt' params s pass
+#if MIN_VERSION_base64(1,0,0)
+    toB64 = extractBase64 . encodeBase64
+#else
+    toB64 = encodeBase64
+#endif
 
 -- | Only for internal use
 hashPasswordWithSalt' :: ScryptParams -> Salt Scrypt -> Password -> ByteString
@@ -252,22 +261,20 @@
     return PasswordCheckSuccess
 
 parseScryptPasswordHashParams :: PasswordHash Scrypt -> Maybe (ScryptParams, Salt Scrypt, ByteString)
-parseScryptPasswordHashParams (PasswordHash passHash) = do
-    let paramList = T.split (== '|') passHash
-    guard $ length paramList == 5
-    let [ scryptRoundsT,
-          scryptBlockSizeT,
-          scryptParallelismT,
-          salt64,
-          hashedKey64 ] = paramList
-    scryptRounds <- readT scryptRoundsT
-    scryptBlockSize <- readT scryptBlockSizeT
-    scryptParallelism <- readT scryptParallelismT
-    salt <- from64 salt64
-    hashedKey <- from64 hashedKey64
-    let scryptOutputLength = fromIntegral $ C8.length hashedKey
-        scryptSalt = fromIntegral $ C8.length salt
-    return (ScryptParams{..}, Salt salt, hashedKey)
+parseScryptPasswordHashParams (PasswordHash passHash) =
+    case paramList of
+        [scryptRoundsT, scryptBlockSizeT, scryptParallelismT, salt64, hashedKey64] -> do
+            scryptRounds <- readT scryptRoundsT
+            scryptBlockSize <- readT scryptBlockSizeT
+            scryptParallelism <- readT scryptParallelismT
+            salt <- from64 salt64
+            hashedKey <- from64 hashedKey64
+            let scryptOutputLength = fromIntegral $ C8.length hashedKey
+                scryptSalt = fromIntegral $ C8.length salt
+            return (ScryptParams{..}, Salt salt, hashedKey)
+        _ -> Nothing
+  where
+    paramList = T.split (== '|') passHash
 
 -- | Extracts 'ScryptParams' from a 'PasswordHash' 'Scrypt'.
 --
