#digest #privacy #crypto #iop #hash #json #privacy-preserving

json-digest

Allow selective masking of JSON subdocuments for privacy, preserving the digest of the whole document

3 releases

0.0.16 Jun 30, 2022
0.0.15 Nov 9, 2021
0.0.5 Sep 21, 2020

#6 in #iop

Download history 51/week @ 2023-12-04 74/week @ 2023-12-11 58/week @ 2023-12-18 66/week @ 2023-12-25 59/week @ 2024-01-01 74/week @ 2024-01-08 52/week @ 2024-01-15 21/week @ 2024-01-22 46/week @ 2024-01-29 37/week @ 2024-02-05 71/week @ 2024-02-12 36/week @ 2024-02-19 86/week @ 2024-02-26 49/week @ 2024-03-04 66/week @ 2024-03-11 80/week @ 2024-03-18

283 downloads per month
Used in 13 crates (9 directly)

LGPL-3.0-or-later

27KB
415 lines

This library provides some algorithms to calculate cryptographically secure digests of JSON documents. Since JSON is an ambiguous serialization format, we also had to define a canonical deterministic subset of all allowed documents. Order of keys in an object and Unicode normalization are well-defined in this subset, making it suitable for hashing.

let data = serde_json::json!({
  "address": {
    "value": "6 Unter den Linden, Berlin, Germany",
    "nonce": "uN_FTaYe8JM-EZ8SU94kAOf0k0YvnhLcZgdpQ3BU9Ymbu"
  },
  "dateOfBirth": {
    "value": "16/02/2002",
    "nonce": "ufxkENKgXuf4yG50p6xpSyaQ8Gz7KsuqXid2yw533TUMK"
  },
  "placeOfBirth": {
    "city": "Berlin",
    "country": "Germany",
    "nonce": "ukhFsI4a6vIZEDUOBRxJmLroPEQ8FQCjJwbI-Z7bEocGo"
  },
});

let digest = json_digest::digest_data(&data).unwrap();
assert_eq!(digest, "cjuQR3pDJeaiRv9oCZ-fBE7T8QWpUGfjP40sAXq0bLwr-8");

let partial_digest = json_digest::selective_digest_data(&data, ".dateOfBirth").unwrap();
let expected_partial_digest = serde_json::json!({
  "address": "cjuvIf1PmPH_31JN5XqJ1xkcNDJyiw9zQ-7ansSB78gnt4",
  "dateOfBirth": {
    "nonce": "ufxkENKgXuf4yG50p6xpSyaQ8Gz7KsuqXid2yw533TUMK",
    "value":"16/02/2002"
  },
  "placeOfBirth": "cjub0Nxb0Kz0pI4bWCdSbaCutk1s5qieFT-ZmqUU1xcuAc"
});
assert_eq!(partial_digest, serde_json::to_string(&expected_partial_digest).unwrap());

let digest_from_partial = json_digest::digest_json_str(&partial_digest).unwrap();
assert_eq!(digest, digest_from_partial);

Dependencies

~2.6–4MB
~101K SLoC