package cryptodbm
Encrypted layer over the dbm library: access to serverless, key-value databases with symmetric encryption.
Install
Dune Dependency
Authors
Maintainers
Sources
v0.84.2.tar.gz
sha256=388a4a8bf17c9ad0825907251720ba40291a19afb643f64066a29e813be50a7e
md5=7c33f55fca768501d06e2ef0eb583f80
doc/src/cryptodbm.internals/cipher.ml.html
Source file cipher.ml
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123
open Types type passwd = { plain_passwd : string ; strong_passwd : string } type t = passwd let empty_passwd = { plain_passwd = "" ; strong_passwd = "" } let plain_passwd p = p.plain_passwd let strong_passwd p = p.strong_passwd let digest s = Cryptokit.hash_string (Cryptokit.Hash.sha256 ()) s (* Transforms an arbitrary passwd into a 32 bytes passwd. *) let normalize_passwd passwd = Cryptokit.hash_string (Cryptokit.Hash.sha256 ()) passwd (* Encrypts or decrypts a string. *) let transform ~passwd way p = let tr = Cryptokit.Cipher.aes ~pad:Cryptokit.Padding.length (normalize_passwd passwd) way in Cryptokit.transform_string tr p (* Encrypting function. *) let encrypt ~passwd = transform ~passwd:passwd.strong_passwd Cryptokit.Cipher.Encrypt (* Decrypting function. *) let decrypt ~passwd = let f = transform ~passwd:passwd.strong_passwd Cryptokit.Cipher.Decrypt in fun s -> try f s with _ -> raiserror (Bad_password Any) (* Debug versions *) (* let () = Printf.printf "Warning: debug version in cipher !!!\n%!" let esc = String.escaped let encrypt ~passwd s = Printf.sprintf "Encrypted-with(%s):%s" passwd.plain_passwd s let decrypt ~passwd s = Printf.printf "Decrypting {%s} with password {%s}\n%!" (esc s) (esc passwd.plain_passwd) ; Scanf.sscanf s "Encrypted-with(%s@):%s@\014" begin fun pw msg -> assert (pw = passwd.plain_passwd) ; Printf.printf "pw = %s, msg = %s\n%!" (esc pw) msg ; msg end *) (* Compute the number of padding bytes, in a deterministic way. Used for keys. *) let compute_padding ~key ~passwd ~max_pad = let hash = digest (key ^ "*\000z" ^ passwd.strong_passwd ^ "!\000x" ^ string_of_int max_pad) in assert (String.length hash >= 3) ; let numb = (Char.code hash.[0]) lsl 16 + (Char.code hash.[1]) lsl 8 + (Char.code hash.[2]) in numb mod (1 + max_pad) (* Expansive computation to get the strong password. * We compute f^n p, where: * p is the initial password, * n is supposed large enough, * f x is the encryption of x with p, xored with its own hashcode. * the xor operation is used to add some complexity mixing encryption and hashing *) (* xor s1 with (repeating copies of) s2, starting at position pos, finishing at len1. *) let rec circular_xor s1 s2 pos len1 len2 = if pos >= len1 then () else begin let n = min (len1 - pos) len2 in Cryptokit.xor_string s2 0 s1 pos n ; circular_xor s1 s2 (pos + n) len1 len2 end let compute_strong_passwd iterations p = let rec iterate current n = (* Printf.printf "Iterate = %d\n%!" n ; *) if n = 0 then current else (* Encrypt with the password. *) let current2 = transform ~passwd:p Cryptokit.Cipher.Encrypt current in (* Xor with its own hashcode.) *) let current_hash = digest current2 in let current2 = Bytes.of_string current2 in (* circular_xor directly on current2. *) circular_xor current2 current_hash 0 (Bytes.length current2) (String.length current_hash) ; (* Get the digest in order to reduce the password size. *) iterate (digest (Bytes.to_string current2)) (n-1) in (* Start from the password itself. *) try digest (iterate p (abs iterations)) with _ -> assert false (* This is not supposed to fail. *) let mk_passwd ~iterations p = if p = "" then empty_passwd else { plain_passwd = p ; strong_passwd = compute_strong_passwd iterations p } let mk_weak_passwd p = if p = "" then empty_passwd else { plain_passwd = p ; strong_passwd = p } let concat plist = List.fold_left begin fun acu p -> if p == empty_passwd then acu else if acu == empty_passwd then p else { plain_passwd = acu.plain_passwd ^ p.plain_passwd ; strong_passwd = acu.strong_passwd ^ p.strong_passwd } end empty_passwd plist let random_salt ~len = Utils.(random_string Utils.gen len)
sectionYPositions = computeSectionYPositions($el), 10)"
x-init="setTimeout(() => sectionYPositions = computeSectionYPositions($el), 10)"
>