Update tutorial based on suggestions
This commit is contained in:
parent
fd75eac415
commit
f639ac9f0d
@ -1,12 +1,12 @@
|
|||||||
|
|
||||||
{- How to use @cryptonite@ with symmetric block ciphers
|
{- How to use @cryptonite@ with symmetric block ciphers
|
||||||
|
|
||||||
> {-# LANGUAGE OverloadedStrings #-}
|
> {-# LANGUAGE OverloadedStrings #-}
|
||||||
> {-# LANGUAGE ScopedTypeVariables #-}
|
> {-# LANGUAGE ScopedTypeVariables #-}
|
||||||
> {-# LANGUAGE GADTs #-}
|
> {-# LANGUAGE GADTs #-}
|
||||||
>
|
>
|
||||||
> import Crypto.Cipher.AES (AES256)
|
> import Crypto.Cipher.AES (AES256)
|
||||||
> import Crypto.Cipher.Types (BlockCipher(..), Cipher(..), nullIV, KeySizeSpecifier(..))
|
> import Crypto.Cipher.Types (BlockCipher(..), Cipher(..), nullIV, KeySizeSpecifier(..), IV, makeIV)
|
||||||
> import Crypto.Error (CryptoFailable(..), CryptoError(..))
|
> import Crypto.Error (CryptoFailable(..), CryptoError(..))
|
||||||
>
|
>
|
||||||
> import qualified Crypto.Random.Types as CRT
|
> import qualified Crypto.Random.Types as CRT
|
||||||
@ -18,40 +18,47 @@
|
|||||||
> data Key c a where
|
> data Key c a where
|
||||||
> Key :: (BlockCipher c, ByteArray a) => a -> Key c a
|
> Key :: (BlockCipher c, ByteArray a) => a -> Key c a
|
||||||
>
|
>
|
||||||
> genPrivateKey :: forall m c a. (CRT.MonadRandom m, BlockCipher c, ByteArray a)
|
> -- | Generates a string of bytes (key) of a specific length for a given block cipher
|
||||||
> => c -> m (Key c a)
|
> genSecretKey :: forall m c a. (CRT.MonadRandom m, BlockCipher c, ByteArray a) => c -> Int -> m (Key c a)
|
||||||
> genPrivateKey _ = fmap Key $ CRT.getRandomBytes $
|
> genSecretKey _ = fmap Key . CRT.getRandomBytes
|
||||||
> case cipherKeySize (undefined :: c) of
|
>
|
||||||
> KeySizeRange _ maxSize -> maxSize
|
> -- | Generate a random initialization vector for a given block cipher
|
||||||
> KeySizeFixed ks -> ks
|
> genRandomIV :: forall m c. (CRT.MonadRandom m, BlockCipher c) => c -> m (Maybe (IV c))
|
||||||
> KeySizeEnum [] -> error "No key size specified"
|
> genRandomIV _ = do
|
||||||
> KeySizeEnum kss -> last kss -- largest key size
|
> bytes :: ByteString <- CRT.getRandomBytes $ blockSize (undefined :: c)
|
||||||
>
|
> return $ makeIV bytes
|
||||||
|
>
|
||||||
|
> -- | Initialize a block cipher
|
||||||
> initCipher :: (BlockCipher c, ByteArray a) => Key c a -> Either CryptoError c
|
> initCipher :: (BlockCipher c, ByteArray a) => Key c a -> Either CryptoError c
|
||||||
> initCipher (Key k) = case cipherInit k of
|
> initCipher (Key k) = case cipherInit k of
|
||||||
> CryptoFailed e -> Left e
|
> CryptoFailed e -> Left e
|
||||||
> CryptoPassed a -> Right a
|
> CryptoPassed a -> Right a
|
||||||
>
|
>
|
||||||
> encrypt :: (BlockCipher c, ByteArray a) => Key c a -> a -> Either CryptoError a
|
> encrypt :: (BlockCipher c, ByteArray a) => Key c a -> IV c -> a -> Either CryptoError a
|
||||||
> encrypt privKey msg =
|
> encrypt secretKey initIV msg =
|
||||||
> case initCipher privKey of
|
> case initCipher secretKey of
|
||||||
> Left e -> Left e
|
> Left e -> Left e
|
||||||
> Right c -> Right $ ctrCombine c nullIV msg
|
> Right c -> Right $ ctrCombine c initIV msg
|
||||||
>
|
>
|
||||||
> decrypt :: (BlockCipher c, ByteArray a) => Key c a -> a -> Either CryptoError a
|
> decrypt :: (BlockCipher c, ByteArray a) => Key c a -> IV c -> a -> Either CryptoError a
|
||||||
> decrypt = encrypt
|
> decrypt = encrypt
|
||||||
>
|
>
|
||||||
> exampleAES256 :: ByteString -> IO ()
|
> exampleAES256 :: ByteString -> IO ()
|
||||||
> exampleAES256 msg = do
|
> exampleAES256 msg = do
|
||||||
> privKey <- genPrivateKey (undefined :: AES256)
|
> -- secret key needs 256 bits (32 * 8)
|
||||||
> let eMsg = encrypt privKey msg >>= decrypt privKey
|
> secretKey <- genSecretKey (undefined :: AES256) 32
|
||||||
> case eMsg of
|
> mInitIV <- genRandomIV (undefined :: AES256)
|
||||||
> Left err -> error $ show err
|
> case mInitIV of
|
||||||
> Right msg' -> do
|
> Nothing -> error "Failed to generate and initialization vector."
|
||||||
> putStrLn $ "Original Message: " ++ show msg
|
> Just initIV -> do
|
||||||
> putStrLn $ "Message after encryption & decryption: " ++ show msg'
|
> let encryptedMsg = encrypt secretKey initIV msg
|
||||||
>
|
> decryptedMsg = decrypt secretKey initIV =<< encryptedMsg
|
||||||
> -- | More Examples... ?
|
> case (,) <$> encryptedMsg <*> decryptedMsg of
|
||||||
|
> Left err -> error $ show err
|
||||||
|
> Right (eMsg, dMsg) -> do
|
||||||
|
> putStrLn $ "Original Message: " ++ show msg
|
||||||
|
> putStrLn $ "Message after encryption: " ++ show eMsg
|
||||||
|
> putStrLn $ "Message after decryption: " ++ show dMsg
|
||||||
|
|
||||||
|-}
|
|-}
|
||||||
|
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user