This repository was archived by the owner on Sep 20, 2023. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 145
Add equivalent of OpenSSL's EVP_BytesToKey (e.g. generate key and IV from some password) #214
Copy link
Copy link
Open
Description
Maybe I've overlooked it in the library, but would that be a feature worth adding?
For my current project, I adapted some code from here: https://hackage.haskell.org/package/shadowsocks-1.20151028/src/Shadowsocks/Encrypt.hs
crypter :: ByteString -> ByteString -> ByteString
crypter password =
cbcEncrypt (cipher :: AES256) iv . pad (PKCS7 16)
where
(key, iv_) = evpBytesToKey password 32 16 -- key size, iv size for AES256
Just iv = makeIV iv_
CryptoPassed cipher = cipherInit key
-- Haskell implementation of OpenSSL's EVP_BytesToKey
-- generate key and iv from a given password
evpBytesToKey :: ByteString -> Int -> Int -> (ByteString, ByteString)
evpBytesToKey password keyLen ivLen =
let ms' = B.concat $ ms 0 []
key = B.take keyLen ms'
iv = B.take ivLen $ B.drop keyLen ms'
in (key, iv)
where
hash' :: ByteString -> ByteString
hash' bs = convert (Crypto.hash bs :: Digest MD5)
ms :: Int -> [ByteString] -> [ByteString]
ms 0 _ = ms 1 [hash' password]
ms i m
| B.length (B.concat m) < keyLen + ivLen =
ms (i+1) (m ++ [hash' (last m <> password)])
| otherwise = m
Being just a quick hack, I see some things that would make it a good fit for adding it to cryptonite
, like e.g.:
- parametrize for different
Digest
(sometimes some SHA implementation is used) - adjust types (e.g. returning an
IV a
instead of aByteString
) to make it compose well with other primitives / functions incryptonite
- get key and IV length from the instance of
Cipher
- add optional salt to the byte sequence the
ms
function generates (as OpenSSL does) - optimize performance (strict vs. lazy
ByteString
)?
What do you think?
Metadata
Metadata
Assignees
Labels
No labels