diff --git a/Cargo.lock b/Cargo.lock
index fd66718b3c6b1c8b84d9672f2c93da7e54f9c698..1e38e08fd817f0966bcc46c6c6e5f89ea6331507 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -16,9 +16,9 @@ checksum = "904dfeac50f3cdaba28fc6f57fdcddb75f49ed61346676a78c4ffe55877802fd"
 
 [[package]]
 name = "base64ct"
-version = "1.0.1"
+version = "1.2.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "8a32fd6af2b5827bce66c29053ba0e7c42b9dcab01835835058558c10851a46b"
+checksum = "392c772b012d685a640cdad68a5a21f4a45e696f85a2c2c907aab2fe49a91e19"
 
 [[package]]
 name = "bitflags"
@@ -43,9 +43,9 @@ checksum = "771fe0050b883fcc3ea2359b1a96bcfbc090b7116eae7c3c512c7a083fdf23d3"
 
 [[package]]
 name = "bumpalo"
-version = "3.7.0"
+version = "3.8.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "9c59e7af012c713f529e7a3ee57ce9b31ddd858d4b512923602f74608b009631"
+checksum = "8f1e260c3a9040a7c19a12468758f4c16f31a81a1fe087482be9570ec864bb6c"
 
 [[package]]
 name = "bytes"
@@ -55,9 +55,9 @@ checksum = "c4872d67bab6358e59559027aa3b9157c53d9358c51423c17554809a8858e0f8"
 
 [[package]]
 name = "cc"
-version = "1.0.69"
+version = "1.0.71"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "e70cc2f62c6ce1868963827bd677764c62d07c3d9a3e1fb1177ee1a9ab199eb2"
+checksum = "79c2681d6594606957bbb8631c4b90a7fcaaa72cdb714743a437b156d6a7eedd"
 
 [[package]]
 name = "cfg-if"
@@ -76,9 +76,9 @@ dependencies = [
 
 [[package]]
 name = "core-foundation"
-version = "0.9.1"
+version = "0.9.2"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "0a89e2ae426ea83155dccf10c0fa6b1463ef6d5fcb44cee0b224a408fa640a62"
+checksum = "6888e10551bb93e424d8df1d07f1a8b4fceb0001a3a4b048bfc47554946f47b3"
 dependencies = [
  "core-foundation-sys",
  "libc",
@@ -86,15 +86,15 @@ dependencies = [
 
 [[package]]
 name = "core-foundation-sys"
-version = "0.8.2"
+version = "0.8.3"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "ea221b5284a47e40033bf9b66f35f984ec0ea2931eb03505246cd27a963f981b"
+checksum = "5827cebf4670468b8772dd191856768aedcb1b0278a04f989f7766351917b9dc"
 
 [[package]]
 name = "cpufeatures"
-version = "0.1.5"
+version = "0.2.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "66c99696f6c9dd7f35d486b9d04d7e6e202aa3e8c40d553f2fdf5e7e0c6a71ef"
+checksum = "95059428f66df56b63431fdb4e1947ed2190586af5c5a8a8b71122bdf5a7f469"
 dependencies = [
  "libc",
 ]
@@ -111,9 +111,9 @@ dependencies = [
 
 [[package]]
 name = "cryptoxide"
-version = "0.3.3"
+version = "0.3.6"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "b8c4fdc86023bc33b265f256ce8205329125b86c38a8a96e243a6a705b7230ec"
+checksum = "42014d4c82e74bc17aaccc4bd75d3615d2b8236198de81c51bed5ddefaae6435"
 
 [[package]]
 name = "digest"
@@ -135,13 +135,14 @@ dependencies = [
  "scrypt",
  "serde",
  "serde_json",
+ "tempfile",
 ]
 
 [[package]]
 name = "encoding_rs"
-version = "0.8.28"
+version = "0.8.29"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "80df024fbc5ac80f87dfef0d9f5209a252f2a497f7f42944cff24d8253cac065"
+checksum = "a74ea89a0a1b98f6332de42c95baff457ada66d1cb4030f9ff151b2041a1c746"
 dependencies = [
  "cfg-if",
 ]
@@ -249,9 +250,9 @@ dependencies = [
 
 [[package]]
 name = "h2"
-version = "0.3.4"
+version = "0.3.7"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "d7f3675cfef6a30c8031cf9e6493ebdc3bb3272a3fea3923c4210d1830e6a472"
+checksum = "7fd819562fcebdac5afc5c113c3ec36f902840b70fd4fc458799c8ce4607ae55"
 dependencies = [
  "bytes",
  "fnv",
@@ -293,9 +294,9 @@ dependencies = [
 
 [[package]]
 name = "http"
-version = "0.2.4"
+version = "0.2.5"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "527e8c9ac747e28542699a951517aa9a6945af506cd1f2e1b53a576c17b6cc11"
+checksum = "1323096b05d41827dadeaee54c9981958c0f94e670bc94ed80037d1a7b8b186b"
 dependencies = [
  "bytes",
  "fnv",
@@ -304,9 +305,9 @@ dependencies = [
 
 [[package]]
 name = "http-body"
-version = "0.4.3"
+version = "0.4.4"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "399c583b2979440c60be0821a6199eca73bc3c8dcd9d070d75ac726e2c6186e5"
+checksum = "1ff4f84919677303da5f147645dbea6b1881f368d03ac84e1dc09031ebd7b2c6"
 dependencies = [
  "bytes",
  "http",
@@ -327,9 +328,9 @@ checksum = "6456b8a6c8f33fee7d958fcd1b60d55b11940a79e63ae87013e6d22e26034440"
 
 [[package]]
 name = "hyper"
-version = "0.14.12"
+version = "0.14.14"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "13f67199e765030fa08fe0bd581af683f0d5bc04ea09c2b1102012c5fb90e7fd"
+checksum = "2b91bb1f221b6ea1f1e4371216b70f40748774c2fb5971b450c07773fb92d26b"
 dependencies = [
  "bytes",
  "futures-channel",
@@ -397,9 +398,9 @@ checksum = "b71991ff56294aa922b450139ee08b3bfc70982c6b2c7562771375cf73542dd4"
 
 [[package]]
 name = "js-sys"
-version = "0.3.53"
+version = "0.3.55"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "e4bf49d50e2961077d9c99f4b7997d770a1114f087c3c2e0069b36c13fc2979d"
+checksum = "7cc9ffccd38c451a86bf13657df244e9c3f37493cce8e5e21e940963777acc84"
 dependencies = [
  "wasm-bindgen",
 ]
@@ -412,9 +413,9 @@ checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646"
 
 [[package]]
 name = "libc"
-version = "0.2.100"
+version = "0.2.106"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "a1fa8cddc8fbbee11227ef194b5317ed014b8acbf15139bd716a18ad3fe99ec5"
+checksum = "a60553f9a9e039a333b4e9b20573b9e9b9c0bb3a11e201ccc48ef4283456d673"
 
 [[package]]
 name = "log"
@@ -445,9 +446,9 @@ checksum = "2a60c7ce501c71e03a9c9c0d35b861413ae925bd979cc7a4e30d060069aaac8d"
 
 [[package]]
 name = "mio"
-version = "0.7.13"
+version = "0.7.14"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "8c2bdb6314ec10835cd3293dd268473a835c02b7b352e788be788b3c6ca6bb16"
+checksum = "8067b404fe97c70829f082dec8bcf4f71225d7eaea1d8645349cb76fa06205cc"
 dependencies = [
  "libc",
  "log",
@@ -516,9 +517,9 @@ checksum = "624a8340c38c1b80fd549087862da4ba43e08858af025b236e509b6649fc13d5"
 
 [[package]]
 name = "openssl"
-version = "0.10.36"
+version = "0.10.38"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "8d9facdb76fec0b73c406f125d44d86fdad818d66fef0531eec9233ca425ff4a"
+checksum = "0c7ae222234c30df141154f159066c5093ff73b63204dcda7121eb082fc56a95"
 dependencies = [
  "bitflags",
  "cfg-if",
@@ -536,9 +537,9 @@ checksum = "28988d872ab76095a6e6ac88d99b54fd267702734fd7ffe610ca27f533ddb95a"
 
 [[package]]
 name = "openssl-sys"
-version = "0.9.66"
+version = "0.9.70"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "1996d2d305e561b70d1ee0c53f1542833f4e1ac6ce9a6708b6ff2738ca67dc82"
+checksum = "c6517987b3f8226b5da3661dad65ff7f300cc59fb5ea8333ca191fc65fde3edf"
 dependencies = [
  "autocfg",
  "cc",
@@ -587,30 +588,30 @@ checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184"
 
 [[package]]
 name = "pkg-config"
-version = "0.3.19"
+version = "0.3.22"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "3831453b3449ceb48b6d9c7ad7c96d5ea673e9b470a1dc578c2ce6521230884c"
+checksum = "12295df4f294471248581bc09bef3c38a5e46f1e36d6a37353621a0c6c357e1f"
 
 [[package]]
 name = "ppv-lite86"
-version = "0.2.10"
+version = "0.2.15"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "ac74c624d6b2d21f425f752262f42188365d7b8ff1aff74c82e45136510a4857"
+checksum = "ed0cfbc8191465bed66e1718596ee0b0b35d5ee1f41c5df2189d0fe8bde535ba"
 
 [[package]]
 name = "proc-macro2"
-version = "1.0.28"
+version = "1.0.32"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "5c7ed8b8c7b886ea3ed7dde405212185f423ab44682667c8c6dd14aa1d9f6612"
+checksum = "ba508cc11742c0dc5c1659771673afbab7a0efab23aa17e854cbab0837ed0b43"
 dependencies = [
  "unicode-xid",
 ]
 
 [[package]]
 name = "quote"
-version = "1.0.9"
+version = "1.0.10"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "c3d0b9745dc2debf507c8422de05d7226cc1f0644216dfdfead988f9b1ab32a7"
+checksum = "38bc8cc6a5f2e3655e0899c1b848643b2562f853f114bfec7be120678e3ace05"
 dependencies = [
  "proc-macro2",
 ]
@@ -675,9 +676,9 @@ dependencies = [
 
 [[package]]
 name = "reqwest"
-version = "0.11.4"
+version = "0.11.6"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "246e9f61b9bb77df069a947682be06e31ac43ea37862e244a69f177694ea6d22"
+checksum = "66d2927ca2f685faf0fc620ac4834690d29e7abb153add10f5812eef20b5e280"
 dependencies = [
  "base64",
  "bytes",
@@ -792,9 +793,9 @@ dependencies = [
 
 [[package]]
 name = "serde_json"
-version = "1.0.67"
+version = "1.0.68"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "a7f9e390c27c3c0ce8bc5d725f6e4d30a29d26659494aa4b17535f7522c5c950"
+checksum = "0f690853975602e1bfe1ccbf50504d67174e3bcf340f23b5ea9992e0587a52d8"
 dependencies = [
  "itoa",
  "ryu",
@@ -815,9 +816,9 @@ dependencies = [
 
 [[package]]
 name = "sha2"
-version = "0.9.5"
+version = "0.9.8"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "b362ae5752fd2137731f9fa25fd4d9058af34666ca1966fb969119cc35719f12"
+checksum = "b69f9a4c9740d74c5baa3fd2e547f9525fa8088a8a958e0ca2409a514e33f5fa"
 dependencies = [
  "block-buffer",
  "cfg-if",
@@ -828,15 +829,15 @@ dependencies = [
 
 [[package]]
 name = "slab"
-version = "0.4.4"
+version = "0.4.5"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "c307a32c1c5c437f38c7fd45d753050587732ba8628319fbdf12a7e289ccc590"
+checksum = "9def91fd1e018fe007022791f865d0ccc9b3a0d5001e01aabb8b40e46000afb5"
 
 [[package]]
 name = "socket2"
-version = "0.4.1"
+version = "0.4.2"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "765f090f0e423d2b55843402a07915add955e7d60657db13707a159727326cad"
+checksum = "5dc90fe6c7be1a323296982db1836d1ea9e47b6839496dde9a541bc496df3516"
 dependencies = [
  "libc",
  "winapi",
@@ -850,9 +851,9 @@ checksum = "6bdef32e8150c2a081110b42772ffe7d7c9032b606bc226c8260fd97e0976601"
 
 [[package]]
 name = "syn"
-version = "1.0.75"
+version = "1.0.81"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "b7f58f7e8eaa0009c5fec437aabf511bd9933e4b2d7407bd05273c01a8906ea7"
+checksum = "f2afee18b8beb5a596ecb4a2dce128c719b4ba399d34126b9e4396e3f9860966"
 dependencies = [
  "proc-macro2",
  "quote",
@@ -875,9 +876,9 @@ dependencies = [
 
 [[package]]
 name = "tinyvec"
-version = "1.3.1"
+version = "1.5.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "848a1e1181b9f6753b5e96a092749e29b11d19ede67dfbbd6c7dc7e0f49b5338"
+checksum = "f83b2a3d4d9091d0abd7eba4dc2710b1718583bd4d8992e2190720ea38f391f7"
 dependencies = [
  "tinyvec_macros",
 ]
@@ -890,9 +891,9 @@ checksum = "cda74da7e1a664f795bb1f8a87ec406fb89a02522cf6e50620d016add6dbbf5c"
 
 [[package]]
 name = "tokio"
-version = "1.10.1"
+version = "1.13.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "92036be488bb6594459f2e03b60e42df6f937fe6ca5c5ffdcb539c6b84dc40f5"
+checksum = "588b2d10a336da58d877567cd8fb8a14b463e2104910f8132cd054b4b96e29ee"
 dependencies = [
  "autocfg",
  "bytes",
@@ -916,9 +917,9 @@ dependencies = [
 
 [[package]]
 name = "tokio-util"
-version = "0.6.7"
+version = "0.6.9"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "1caa0b0c8d94a049db56b5acf8cba99dc0623aab1b26d5b5f5e2d945846b3592"
+checksum = "9e99e1983e5d376cd8eb4b66604d2e99e79f5bd988c3055891dcd8c9e2604cc0"
 dependencies = [
  "bytes",
  "futures-core",
@@ -936,9 +937,9 @@ checksum = "360dfd1d6d30e05fda32ace2c8c70e9c0a9da713275777f5a4dbb8a1893930c6"
 
 [[package]]
 name = "tracing"
-version = "0.1.26"
+version = "0.1.29"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "09adeb8c97449311ccd28a427f96fb563e7fd31aabf994189879d9da2394b89d"
+checksum = "375a639232caf30edfc78e8d89b2d4c375515393e7af7e16f01cd96917fb2105"
 dependencies = [
  "cfg-if",
  "pin-project-lite",
@@ -947,9 +948,9 @@ dependencies = [
 
 [[package]]
 name = "tracing-core"
-version = "0.1.19"
+version = "0.1.21"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "2ca517f43f0fb96e0c3072ed5c275fe5eece87e8cb52f4a77b69226d3b1c9df8"
+checksum = "1f4ed65637b8390770814083d20756f87bfa2c21bf2f110babdc5438351746e4"
 dependencies = [
  "lazy_static",
 ]
@@ -962,15 +963,15 @@ checksum = "59547bce71d9c38b83d9c0e92b6066c4253371f15005def0c30d9657f50c7642"
 
 [[package]]
 name = "typenum"
-version = "1.13.0"
+version = "1.14.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "879f6906492a7cd215bfa4cf595b600146ccfac0c79bcbd1f3000162af5e8b06"
+checksum = "b63708a265f51345575b27fe43f9500ad611579e764c79edbc2037b1121959ec"
 
 [[package]]
 name = "unicode-bidi"
-version = "0.3.6"
+version = "0.3.7"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "246f4c42e67e7a4e3c6106ff716a5d067d4132a642840b242e357e468a2a0085"
+checksum = "1a01404663e3db436ed2746d9fefef640d868edae3cceb81c3b8d5732fda678f"
 
 [[package]]
 name = "unicode-normalization"
@@ -1029,21 +1030,19 @@ checksum = "fd6fbd9a79829dd1ad0cc20627bf1ed606756a7f77edff7b66b7064f9cb327c6"
 
 [[package]]
 name = "wasm-bindgen"
-version = "0.2.76"
+version = "0.2.78"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "8ce9b1b516211d33767048e5d47fa2a381ed8b76fc48d2ce4aa39877f9f183e0"
+checksum = "632f73e236b219150ea279196e54e610f5dbafa5d61786303d4da54f84e47fce"
 dependencies = [
  "cfg-if",
- "serde",
- "serde_json",
  "wasm-bindgen-macro",
 ]
 
 [[package]]
 name = "wasm-bindgen-backend"
-version = "0.2.76"
+version = "0.2.78"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "cfe8dc78e2326ba5f845f4b5bf548401604fa20b1dd1d365fb73b6c1d6364041"
+checksum = "a317bf8f9fba2476b4b2c85ef4c4af8ff39c3c7f0cdfeed4f82c34a880aa837b"
 dependencies = [
  "bumpalo",
  "lazy_static",
@@ -1056,9 +1055,9 @@ dependencies = [
 
 [[package]]
 name = "wasm-bindgen-futures"
-version = "0.4.26"
+version = "0.4.28"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "95fded345a6559c2cfee778d562300c581f7d4ff3edb9b0d230d69800d213972"
+checksum = "8e8d7523cb1f2a4c96c1317ca690031b714a51cc14e05f712446691f413f5d39"
 dependencies = [
  "cfg-if",
  "js-sys",
@@ -1068,9 +1067,9 @@ dependencies = [
 
 [[package]]
 name = "wasm-bindgen-macro"
-version = "0.2.76"
+version = "0.2.78"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "44468aa53335841d9d6b6c023eaab07c0cd4bddbcfdee3e2bb1e8d2cb8069fef"
+checksum = "d56146e7c495528bf6587663bea13a8eb588d39b36b679d83972e1a2dbbdacf9"
 dependencies = [
  "quote",
  "wasm-bindgen-macro-support",
@@ -1078,9 +1077,9 @@ dependencies = [
 
 [[package]]
 name = "wasm-bindgen-macro-support"
-version = "0.2.76"
+version = "0.2.78"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "0195807922713af1e67dc66132c7328206ed9766af3858164fb583eedc25fbad"
+checksum = "7803e0eea25835f8abdc585cd3021b3deb11543c6fe226dcd30b228857c5c5ab"
 dependencies = [
  "proc-macro2",
  "quote",
@@ -1091,15 +1090,15 @@ dependencies = [
 
 [[package]]
 name = "wasm-bindgen-shared"
-version = "0.2.76"
+version = "0.2.78"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "acdb075a845574a1fa5f09fd77e43f7747599301ea3417a9fbffdeedfc1f4a29"
+checksum = "0237232789cf037d5480773fe568aac745bfe2afbc11a863e97901780a6b47cc"
 
 [[package]]
 name = "web-sys"
-version = "0.3.53"
+version = "0.3.55"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "224b2f6b67919060055ef1a67807367c2066ed520c3862cc013d26cf893a783c"
+checksum = "38eb105f1c59d9eaa6b5cdc92b859d85b926e82cb2e0945cd0c9259faa6fe9fb"
 dependencies = [
  "js-sys",
  "wasm-bindgen",
diff --git a/Cargo.toml b/Cargo.toml
index 217a318bb415c075c88f981437b7901631c0974c..42c68e377afbced1d9e078f8074e65cc50b3f265 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -12,4 +12,5 @@ bs58 = "0.4.0"
 cryptoxide = "0.3.3"
 reqwest = { version = "0.11.4", features = ["json", "blocking"] }
 serde = { version = "1.0.130", features = ["derive"] }
-serde_json = "1.0.67"
\ No newline at end of file
+serde_json = "1.0.67"
+tempfile = "3.2.0"
diff --git a/src/cli/adhere.rs b/src/cli/adhere.rs
index 41bb49db9be8fd39def2bb0895dcc7fa06e923ab..b5039d31ba0f557d10f7ace4a71810c3ad057b87 100644
--- a/src/cli/adhere.rs
+++ b/src/cli/adhere.rs
@@ -1,14 +1,13 @@
 use crate::bma::BmaNode;
 use crate::bma::lookup_identity::{LookupResult, lookup2identities, lookup_print};
-use crate::crypto::duniter_key::scrypt_duniter_key::ScryptDuniterKey;
 use crate::crypto::duniter_key::ToDuniterKey;
 use crate::dubp::documents::membership::Membership;
 use crate::dubp::signable::Signable;
 
-pub fn adhere(node: &BmaNode) -> Result<(), String> {
+pub fn adhere(keyring: &Box<dyn ToDuniterKey>, node: &BmaNode) -> Result<(), String> {
 
     println!("Deriving key for signature...");
-    let keyring = ScryptDuniterKey::new(String::from("fakesalt"), String::from("fakepasswd")).derive(); // TODO: get salt/passwd from file/cli
+    let keyring = keyring.derive();
 
     let uid_or_pub = keyring.get_public_base58();
     let address = node.get_address();
diff --git a/src/cli/certify.rs b/src/cli/certify.rs
index b6441c9a709cca71aa39d4eeb47c8e98b69dbb8a..f7dd41351ecb72d7a45db999641ccc24e9036bf6 100644
--- a/src/cli/certify.rs
+++ b/src/cli/certify.rs
@@ -1,11 +1,10 @@
 use crate::bma::BmaNode;
 use crate::bma::lookup_identity::{LookupResult, lookup2identities, lookup_print};
-use crate::crypto::duniter_key::scrypt_duniter_key::ScryptDuniterKey;
 use crate::crypto::duniter_key::ToDuniterKey;
 use crate::dubp::documents::certification::Certification;
 use crate::dubp::signable::Signable;
 
-pub fn certify(node: &BmaNode, uid_or_pub: &String) -> Result<(), String> {
+pub fn certify(keyring: &Box<dyn ToDuniterKey>, node: &BmaNode, uid_or_pub: &String) -> Result<(), String> {
     let address = node.get_address();
     println!("Fetching identity using \"{}\" pattern...", uid_or_pub);
     let resp = reqwest::blocking::get(format!("{}/wot/lookup/{}", address, uid_or_pub)).expect("Could not fetch lookup data from distant node");
@@ -26,7 +25,7 @@ pub fn certify(node: &BmaNode, uid_or_pub: &String) -> Result<(), String> {
     }
 
     println!("Deriving key for signature...");
-    let keyring = ScryptDuniterKey::new(String::from("fakesalt"), String::from("fakepasswd")).derive(); // TODO: get salt/passwd from file/cli
+    let keyring = keyring.derive();
     println!("Get current block for blockstamp...");
     let current = crate::bma::blockchain::current(&node);
     let currency = &current.currency;
diff --git a/src/cli/mod.rs b/src/cli/mod.rs
index 311154d5f5d3f07b6548a6a3095bb2e311a05902..33f33188b188239f1f630646e4579a6a7bc66a2e 100644
--- a/src/cli/mod.rs
+++ b/src/cli/mod.rs
@@ -1,16 +1,17 @@
-use std::env::Args;
-
-use crate::cli::Command::*;
-use crate::bma::BmaNode;
 use std::env;
+use std::path::PathBuf;
+
 use crate::{bma, cli, compute_key, compute_pub, compute_sec};
-use crate::crypto::duniter_key::ScryptDuniterKey;
-use core::fmt;
+use crate::bma::BmaNode;
+use crate::cli::Command::*;
+use crate::crypto::duniter_key::{ScryptDuniterKey, ToDuniterKey};
+use crate::crypto::duniter_key::file_base58_duniter_key::FileBase58DuniterKey;
 
 pub mod certify;
 pub mod adhere;
 
 const DEFAULT_NODE: &str = "https://g1-test.duniter.org";
+const DEFAULT_KEYRING_PATH: &str = "keyring-base58.txt";
 const CMD_PUB: &str = "pub";
 const CMD_SEC: &str = "sec";
 const CMD_KEYRING: &str = "keyring";
@@ -28,9 +29,9 @@ pub enum Command {
     /// Search an identity on a Duniter node (BMA API)
     LOOKUP(String, BmaNode, String),
     /// Search an identity on a Duniter node (BMA API) and certify it
-    CERTIFY(String, BmaNode, String),
+    CERTIFY(String, Box<dyn ToDuniterKey>, BmaNode, String),
     /// Search an identity matching local pubkey on a Duniter node (BMA API) and send a membership based on it
-    ADHERE(String, BmaNode),
+    ADHERE(String, Box<dyn ToDuniterKey>, BmaNode),
     /// Some unknown command
     UNKNOWN(String),
 }
@@ -58,8 +59,8 @@ impl Command {
             SEC(_, salt, passwd) => println!("{}", compute_sec(ScryptDuniterKey::new(salt.to_string(), passwd.to_string()))),
             KEYRING(_, salt, passwd) => println!("{}", compute_key(ScryptDuniterKey::new(salt.to_string(), passwd.to_string()))),
             LOOKUP(_, bma_node, uid_or_pub) => bma::lookup_identity::lookup(bma_node, uid_or_pub),
-            CERTIFY(_, bma_node, uid_or_pub) => cli::certify::certify(bma_node, uid_or_pub).unwrap_or_else(|e| eprintln!("{}", e)),
-            ADHERE(_, bma_node) => cli::adhere::adhere(bma_node).unwrap_or_else(|e| eprintln!("{}", e)),
+            CERTIFY(_, keyring, bma_node, uid_or_pub) => cli::certify::certify(keyring, bma_node, uid_or_pub).unwrap_or_else(|e| eprintln!("{}", e)),
+            ADHERE(_, keyring, bma_node) => cli::adhere::adhere(keyring, bma_node).unwrap_or_else(|e| eprintln!("{}", e)),
             UNKNOWN(cmd) => eprintln!("Unknown command {}", cmd),
         }
         Ok(())
@@ -74,6 +75,11 @@ impl Command {
         };
 
         let command = command.as_str();
+        let bma_node = BmaNode::new(env::var("DUNITER_NODE").unwrap_or(DEFAULT_NODE.to_string()).as_str());
+        let keyring = Box::from(
+            FileBase58DuniterKey::from(
+                PathBuf::from(
+                    env::var("DUNITER_KEYRING_PATH").unwrap_or(DEFAULT_KEYRING_PATH.to_string()))));
         match command {
             CMD_PUB => {
                 let salt = args.next().expect("Salt must be provided");
@@ -92,20 +98,14 @@ impl Command {
             },
             CMD_LOOKUP => {
                 let uid_or_pub = args.next().expect("UID or pubkey must be provided");
-                let default = String::from(DEFAULT_NODE);
-                let bma_node = BmaNode::new(env::var("DUNITER_NODE").unwrap_or(default).as_str());
                 Some(LOOKUP(command.to_string(), bma_node, uid_or_pub))
             },
             CMD_CERTIFY => {
                 let uid_or_pub = args.next().expect("UID or pubkey must be provided");
-                let default = String::from(DEFAULT_NODE);
-                let bma_node = BmaNode::new(env::var("DUNITER_NODE").unwrap_or(default).as_str());
-                Some(CERTIFY(command.to_string(), bma_node, uid_or_pub))
+                Some(CERTIFY(command.to_string(), keyring, bma_node, uid_or_pub))
             },
             CMD_ADHERE => {
-                let default = String::from(DEFAULT_NODE);
-                let bma_node = BmaNode::new(env::var("DUNITER_NODE").unwrap_or(default).as_str());
-                Some(ADHERE(command.to_string(), bma_node))
+                Some(ADHERE(command.to_string(), keyring, bma_node))
             },
             _ => Some(UNKNOWN(command.to_string())),
         }
@@ -115,7 +115,6 @@ impl Command {
 #[cfg(test)]
 mod tests {
     use crate::cli::Command;
-    use crate::cli::Command::PUB;
 
     #[test]
     fn known_command () {
diff --git a/src/crypto/duniter_key/file_base58_duniter_key.rs b/src/crypto/duniter_key/file_base58_duniter_key.rs
new file mode 100644
index 0000000000000000000000000000000000000000..5075c57efad431d9b39ed2cdbad43fb2e2a0364f
--- /dev/null
+++ b/src/crypto/duniter_key/file_base58_duniter_key.rs
@@ -0,0 +1,53 @@
+use std::fs;
+use std::path::{PathBuf};
+
+use crate::crypto::duniter_key::{DuniterKey, PUBLIC_KEY_LEN, SECRET_KEY_LEN, ToDuniterKey};
+
+pub struct FileBase58DuniterKey(PathBuf);
+
+impl From<PathBuf> for FileBase58DuniterKey {
+    fn from(path_buf: PathBuf) -> Self {
+        FileBase58DuniterKey(path_buf)
+    }
+}
+
+impl ToDuniterKey for FileBase58DuniterKey {
+
+    fn derive(&self) -> DuniterKey {
+        let content = fs::read_to_string(&self.0)
+            .map(|s| s.replace("\n", ""))
+            .map(|s| s.split(":")
+                .map(str::to_owned).collect::<Vec<_>>().into_iter());
+        if let Ok(mut split) = content {
+            let public_vec = bs58::decode(split.next().expect("Should have read the public key")).into_vec().unwrap();
+            let secret_vec = bs58::decode(split.next().expect("Should have read the private key")).into_vec().unwrap();
+            let mut public = [0u8; PUBLIC_KEY_LEN];
+            let mut secret = [0u8; SECRET_KEY_LEN];
+            for i in 0..PUBLIC_KEY_LEN { public[i] = public_vec[i] }
+            for i in 0..SECRET_KEY_LEN { secret[i] = secret_vec[i] }
+            return DuniterKey { public, secret }
+        }
+        panic!("Could not extract base58 keyring from path {}", self.0.display());
+    }
+}
+
+#[cfg(test)]
+mod tests {
+    use std::io::Write;
+
+    use crate::crypto::duniter_key::file_base58_duniter_key::FileBase58DuniterKey;
+    use crate::crypto::duniter_key::ToDuniterKey;
+
+    const PUBKEY: &str = "953SE7QJoDC2vFFwkSDojGKjUFU6BCu1kH6s4MnoyQCw";
+    const SECKEY: &str = "s3G7v2FPuTSWh8f9BSrU8EurwcM214x4fMLWFDLYmH7doqfyCqM96Ai5q4xB8y4GBKTCUvHoR3Et8AJKf7XTTZR";
+
+    #[test]
+    fn load_from_file() {
+        let file = tempfile::NamedTempFile::new().unwrap();
+        writeln!(&file, "{}:{}", PUBKEY, SECKEY).expect("Could not write temporary key");
+        let path = &file.into_temp_path();
+        let key = FileBase58DuniterKey(path.to_path_buf()).derive();
+        assert_eq!(PUBKEY, key.get_public_base58());
+        assert_eq!(SECKEY, key.get_secret_base58());
+    }
+}
\ No newline at end of file
diff --git a/src/crypto/duniter_key/mod.rs b/src/crypto/duniter_key/mod.rs
index c2e393df08d38f591542800d168e5e2b2fc536be..6205e7f71b7281a4a09a7cb1771c39370e623625 100644
--- a/src/crypto/duniter_key/mod.rs
+++ b/src/crypto/duniter_key/mod.rs
@@ -13,6 +13,7 @@ use crate::dubp::signable::Signable;
 pub mod scrypt_duniter_key;
 pub mod seed_duniter_key;
 pub mod base58_duniter_key;
+pub mod file_base58_duniter_key;
 
 pub const PUBLIC_KEY_LEN: usize = 32;
 pub const SECRET_KEY_LEN: usize = 64;
diff --git a/src/main.rs b/src/main.rs
index 8d327d315c38e03db795e253465878e1fda2fead..a1bba3388f90ff6c62883eaf65d3e5130388d07b 100644
--- a/src/main.rs
+++ b/src/main.rs
@@ -1,10 +1,7 @@
 use std::env;
 use std::process::exit;
 
-use duniter_mini_client::{compute_pub, compute_sec, compute_key, cli, bma};
 use duniter_mini_client::cli::Command;
-use duniter_mini_client::cli::Command::{PUB, SEC, KEYRING, LOOKUP, CERTIFY};
-use duniter_mini_client::crypto::duniter_key::ScryptDuniterKey;
 
 fn main() {
     let command = Command::from(env::args());