Encryption: implement RFC9106 recommendations
This commit is contained in:
parent
559900fd3a
commit
97cdc074f9
1 changed files with 7 additions and 6 deletions
|
|
@ -41,17 +41,18 @@ xorWithKey key bs
|
||||||
| B.null key = error "key must not be empty"
|
| B.null key = error "key must not be empty"
|
||||||
| otherwise = B.pack $ B.zipWith xor bs key
|
| otherwise = B.pack $ B.zipWith xor bs key
|
||||||
|
|
||||||
|
-- as recommended by RFC9106
|
||||||
|
argonOptions = defaultOptions { variant = Argon2id }
|
||||||
|
|
||||||
-- format: E[16-byte salt][4-byte big-endian iterations][ciphertext]
|
-- format: E[16-byte salt][4-byte big-endian iterations][ciphertext]
|
||||||
encryptData :: ByteString -> IO ByteString
|
encryptData :: ByteString -> IO ByteString
|
||||||
encryptData privkey = do
|
encryptData privkey = do
|
||||||
iterationTime <- measureIteration
|
iterationTime <- measureIteration
|
||||||
print iterationTime
|
let minIterations = 3 -- as recommended by RFC9106
|
||||||
let iterations = ceiling $ 1 / iterationTime
|
let iterations = max minIterations $ ceiling $ 1 / iterationTime
|
||||||
print iterations
|
|
||||||
salt <- getEntropy 16 :: IO ByteString
|
salt <- getEntropy 16 :: IO ByteString
|
||||||
--let password = "password" :: ByteString
|
|
||||||
password <- getPassword
|
password <- getPassword
|
||||||
key <- throwCryptoErrorIO $ hash defaultOptions { iterations = iterations } password salt 56 :: IO ByteString
|
key <- throwCryptoErrorIO $ hash argonOptions { iterations = iterations } password salt 56 :: IO ByteString
|
||||||
let ciphertext = xorWithKey key privkey
|
let ciphertext = xorWithKey key privkey
|
||||||
-- encode iterations as Word32 big-endian
|
-- encode iterations as Word32 big-endian
|
||||||
let iterWord :: Word32
|
let iterWord :: Word32
|
||||||
|
|
@ -67,7 +68,7 @@ decryptData contents = do
|
||||||
let (salt, rest) = B.splitAt 16 contents
|
let (salt, rest) = B.splitAt 16 contents
|
||||||
(iterBytes, ciphertext) = B.splitAt 4 rest
|
(iterBytes, ciphertext) = B.splitAt 4 rest
|
||||||
iterations = runGet getWord32be (BL.fromStrict iterBytes)
|
iterations = runGet getWord32be (BL.fromStrict iterBytes)
|
||||||
key <- throwCryptoErrorIO $ hash defaultOptions { iterations = iterations } password salt 56 :: IO ByteString
|
key <- throwCryptoErrorIO $ hash argonOptions { iterations = iterations } password salt 56 :: IO ByteString
|
||||||
let plaintext = xorWithKey key ciphertext
|
let plaintext = xorWithKey key ciphertext
|
||||||
case B.head plaintext of
|
case B.head plaintext of
|
||||||
0x53 -> pure plaintext
|
0x53 -> pure plaintext
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue