From 7ccd460ace1093f08fcf1062dc4f96c0a7e03cbf Mon Sep 17 00:00:00 2001 From: Chad Cravens Date: Wed, 20 Dec 2023 22:36:22 -0500 Subject: [PATCH 01/11] Update md5 to sha256 for FIPS compliance --- sphinxext/utils.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/sphinxext/utils.py b/sphinxext/utils.py index c3bd2052d..0634c0092 100644 --- a/sphinxext/utils.py +++ b/sphinxext/utils.py @@ -193,8 +193,8 @@ def dict_hash(dct): serialized = json.dumps(dct, sort_keys=True) try: - m = hashlib.md5(serialized) + m = hashlib.sha256(serialized) except TypeError: - m = hashlib.md5(serialized.encode()) + m = hashlib.sha256(serialized.encode()) return m.hexdigest() From 58fb97b4bdbd4c5bfd75031eeefede18a1aa5059 Mon Sep 17 00:00:00 2001 From: Chad Cravens Date: Wed, 20 Dec 2023 22:38:40 -0500 Subject: [PATCH 02/11] Update md5 to sha256 for FIPS compliance --- altair/utils/data.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/altair/utils/data.py b/altair/utils/data.py index 2a3a3474b..888f09635 100644 --- a/altair/utils/data.py +++ b/altair/utils/data.py @@ -257,7 +257,7 @@ def check_data_type(data: DataType) -> None: # Private utilities # ============================================================================== def _compute_data_hash(data_str: str) -> str: - return hashlib.md5(data_str.encode()).hexdigest() + return hashlib.sha256(data_str.encode()).hexdigest() def _data_to_json_string(data: DataType) -> str: From 0d9146b344cb78be2add6d05ad2bdfe506ff26cc Mon Sep 17 00:00:00 2001 From: Chad Cravens Date: Wed, 20 Dec 2023 22:39:26 -0500 Subject: [PATCH 03/11] Update md5 to sha256 for FIPS compliance --- sphinxext/altairgallery.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sphinxext/altairgallery.py b/sphinxext/altairgallery.py index f76805c90..a0aef50be 100644 --- a/sphinxext/altairgallery.py +++ b/sphinxext/altairgallery.py @@ -166,7 +166,7 @@ def save_example_pngs(examples, image_dir, make_thumbnails=True): filename = example["name"] + (".svg" if example["use_svg"] else ".png") image_file = os.path.join(image_dir, filename) - example_hash = hashlib.md5(example["code"].encode()).hexdigest() + example_hash = hashlib.sha256(example["code"].encode()).hexdigest() hashes_match = hashes.get(filename, "") == example_hash if hashes_match and os.path.exists(image_file): From 76b8a3f7d1238f716c41aac7323ac7ceeb181506 Mon Sep 17 00:00:00 2001 From: Chad Cravens Date: Wed, 20 Dec 2023 22:40:14 -0500 Subject: [PATCH 04/11] Update api.py --- altair/vegalite/v5/api.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/altair/vegalite/v5/api.py b/altair/vegalite/v5/api.py index c87c2e85d..d985abff8 100644 --- a/altair/vegalite/v5/api.py +++ b/altair/vegalite/v5/api.py @@ -57,7 +57,7 @@ def _dataset_name(values: Union[dict, list, core.InlineDataset]) -> str: if values == [{}]: return "empty" values_json = json.dumps(values, sort_keys=True) - hsh = hashlib.md5(values_json.encode()).hexdigest() + hsh = hashlib.sha256(values_json.encode()).hexdigest() return "data-" + hsh From 49ea08e20e87ad6d5e278aaefcd5a7943e31b59b Mon Sep 17 00:00:00 2001 From: Stefan Binder Date: Thu, 21 Dec 2023 20:53:51 +0100 Subject: [PATCH 05/11] Adapt url encoding in test_to_url. It changed because the specification changed due to the different hash algorithm which is used for the dataset name --- tests/vegalite/v5/test_api.py | 9 +-------- 1 file changed, 1 insertion(+), 8 deletions(-) diff --git a/tests/vegalite/v5/test_api.py b/tests/vegalite/v5/test_api.py index 638eaac46..738e85166 100644 --- a/tests/vegalite/v5/test_api.py +++ b/tests/vegalite/v5/test_api.py @@ -382,14 +382,7 @@ def test_save_html(basic_chart, inline): def test_to_url(basic_chart): share_url = basic_chart.to_url() - expected_vegalite_encoding = ( - "N4Igxg9gdgZglgcxALlANzgUwO4tJKAFzigFcJSBnAdTgBNCALFAZgAY2AacaYsiygAlMiRoVYcAvpO5" - "0AhoTl4QUOQFtMKEPMUBaMACY5LTAA4AnACM55ugFY6ARgBspgOz2zh03Wfs5bCwsIDIganIATgDWyoQ" - "AngAOmsgg1hEh3JhQkHQkSKggAB7K8JgANnRaStzxSVpQEGokcmUZIHElWBValiA1ickgAI6kckRwisR" - "omtLcACSUYIyY4VpihAmUyAD029MIcgB0CBOMpJaHcBDbi8vhe5gHumUTmHt2hy6HLIcAVpTQPraBRyS" - "iYQiUZQ6OT6IwmCzWWwOFzuTymby+fyBYLIADaoCUKQAgkDesgDKYZAStAAhUkoOx2KkgQkgADC9OQABY" - "WMzWQARTnmRx8rQAUU5phFnGpKQAYpy7LyZSytABxTmOcyilKCSVuHUgACSioMkgAutIgA" - ) + expected_vegalite_encoding = "N4Igxg9gdgZglgcxALlANzgUwO4tJKAFzigFcJSBnAdTgBNCALFAZgAY2AacaYsiygAlMiRoVYcAvpO50AhoTl4QUOQFtMKEPMUBaAOwA2ABwAWFi1NyTcgEb7TtuabAswc-XTZhMczLdNDAEZnAFY2e0MAJhgwfTZTGBZDHyM6AE46TDArYxgkwxAZEDU5ACcAa2VCAE8AB01kECcyou5MKEg6EiRUEAAPZXhMABs6LSVuWoatKAg1EjkRtpAaoawxrVsQKfrGkABHUjkiOEViNE1pbgASSjBGTFKtMUI6ymQAek-LhDkAOgQZ0YpFs-zgEE+90epR+mD+uhGZ0wP1C-yChn+LH+ACtKNAdtoFHJKJhCJRlDo5AYTOZLNZjHYHE4XG4PF4fH4AsEwhEjDE4gkCqlDBksjk5HkCigANqgJRNACChO2yCixhk8q0ACEVShQqFNSAFSAAMJ65DmI0mgAiFvSQWtWgAohbjI7OFqmgAxC2hFhOpoAcQtQXSgZAgjd+gjAEk-VFJABdaRAA" assert ( share_url From 8b0bc62497a0ee8aa7f9d685f51bdb0f70fa9897 Mon Sep 17 00:00:00 2001 From: Chad Cravens Date: Thu, 21 Dec 2023 17:57:49 -0500 Subject: [PATCH 06/11] Truncate hash value to be same size as md5 --- altair/utils/data.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/altair/utils/data.py b/altair/utils/data.py index 888f09635..7fba7adaa 100644 --- a/altair/utils/data.py +++ b/altair/utils/data.py @@ -257,7 +257,7 @@ def check_data_type(data: DataType) -> None: # Private utilities # ============================================================================== def _compute_data_hash(data_str: str) -> str: - return hashlib.sha256(data_str.encode()).hexdigest() + return hashlib.sha256(data_str.encode()).hexdigest()[:32] def _data_to_json_string(data: DataType) -> str: From ad1106b794ed3af79285eeaadb8b4aa82d1c2e6a Mon Sep 17 00:00:00 2001 From: Chad Cravens Date: Thu, 21 Dec 2023 17:59:03 -0500 Subject: [PATCH 07/11] Truncate sha256 hash to match md5 hash length --- altair/vegalite/v5/api.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/altair/vegalite/v5/api.py b/altair/vegalite/v5/api.py index d985abff8..56b15db79 100644 --- a/altair/vegalite/v5/api.py +++ b/altair/vegalite/v5/api.py @@ -57,7 +57,7 @@ def _dataset_name(values: Union[dict, list, core.InlineDataset]) -> str: if values == [{}]: return "empty" values_json = json.dumps(values, sort_keys=True) - hsh = hashlib.sha256(values_json.encode()).hexdigest() + hsh = hashlib.sha256(values_json.encode()).hexdigest()[:32] return "data-" + hsh From cebc38974551b37781d9eb9f96def6e19a5932f6 Mon Sep 17 00:00:00 2001 From: Chad Cravens Date: Thu, 21 Dec 2023 17:59:49 -0500 Subject: [PATCH 08/11] Truncate sha256 to match md5 hash size --- sphinxext/altairgallery.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sphinxext/altairgallery.py b/sphinxext/altairgallery.py index a0aef50be..a6310ddd9 100644 --- a/sphinxext/altairgallery.py +++ b/sphinxext/altairgallery.py @@ -166,7 +166,7 @@ def save_example_pngs(examples, image_dir, make_thumbnails=True): filename = example["name"] + (".svg" if example["use_svg"] else ".png") image_file = os.path.join(image_dir, filename) - example_hash = hashlib.sha256(example["code"].encode()).hexdigest() + example_hash = hashlib.sha256(example["code"].encode()).hexdigest()[:32] hashes_match = hashes.get(filename, "") == example_hash if hashes_match and os.path.exists(image_file): From 917850065664d280808c3fd14878ce0647b8978b Mon Sep 17 00:00:00 2001 From: Chad Cravens Date: Thu, 21 Dec 2023 18:00:36 -0500 Subject: [PATCH 09/11] Truncate sha265 hash to be same size as md5 --- sphinxext/utils.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/sphinxext/utils.py b/sphinxext/utils.py index 0634c0092..50d17608c 100644 --- a/sphinxext/utils.py +++ b/sphinxext/utils.py @@ -193,8 +193,8 @@ def dict_hash(dct): serialized = json.dumps(dct, sort_keys=True) try: - m = hashlib.sha256(serialized) + m = hashlib.sha256(serialized)[:32] except TypeError: - m = hashlib.sha256(serialized.encode()) + m = hashlib.sha256(serialized.encode())[:32] return m.hexdigest() From 0763733d047d0a1e854b366e35bf6e593991129a Mon Sep 17 00:00:00 2001 From: mattijn Date: Fri, 22 Dec 2023 14:54:21 +0100 Subject: [PATCH 10/11] update test --- tests/vegalite/v5/test_api.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/vegalite/v5/test_api.py b/tests/vegalite/v5/test_api.py index 738e85166..af963be7d 100644 --- a/tests/vegalite/v5/test_api.py +++ b/tests/vegalite/v5/test_api.py @@ -382,7 +382,7 @@ def test_save_html(basic_chart, inline): def test_to_url(basic_chart): share_url = basic_chart.to_url() - expected_vegalite_encoding = "N4Igxg9gdgZglgcxALlANzgUwO4tJKAFzigFcJSBnAdTgBNCALFAZgAY2AacaYsiygAlMiRoVYcAvpO50AhoTl4QUOQFtMKEPMUBaAOwA2ABwAWFi1NyTcgEb7TtuabAswc-XTZhMczLdNDAEZnAFY2e0MAJhgwfTZTGBZDHyM6AE46TDArYxgkwxAZEDU5ACcAa2VCAE8AB01kECcyou5MKEg6EiRUEAAPZXhMABs6LSVuWoatKAg1EjkRtpAaoawxrVsQKfrGkABHUjkiOEViNE1pbgASSjBGTFKtMUI6ymQAek-LhDkAOgQZ0YpFs-zgEE+90epR+mD+uhGZ0wP1C-yChn+LH+ACtKNAdtoFHJKJhCJRlDo5AYTOZLNZjHYHE4XG4PF4fH4AsEwhEjDE4gkCqlDBksjk5HkCigANqgJRNACChO2yCixhk8q0ACEVShQqFNSAFSAAMJ65DmI0mgAiFvSQWtWgAohbjI7OFqmgAxC2hFhOpoAcQtQXSgZAgjd+gjAEk-VFJABdaRAA" + expected_vegalite_encoding = "N4Igxg9gdgZglgcxALlANzgUwO4tJKAFzigFcJSBnAdTgBNCALFAZgAY2AacaYsiygAlMiRoVYcAvpO50AhoTl4QUOQFtMKEPMUBaAOwA2ABwAWFi1NyTcgEb7TtuabAswc-XTZhMczLdNDAEYQGRA1OQAnAGtlQgBPAAdNZBAnSNDuTChIOhIkVBAAD2V4TAAbOi0lbgTkrSgINRI5csyQeNKsSq1bEFqklJAAR1I5IjhFYjRNaW4AEkowRkwIrTFCRMpkAHodmYQ5ADoEScZSWyO4CB2llYj9zEPdcsnMfYBWI6DDI5YjgBWlGg-W0CjklEwhEoyh0cgMJnMlmsxjsDicLjcHi8Pj8AWCKAA2qAlKkAIKgvrIABMxhkJK0ACFKSgPh96SBSSAAMIs5DmDlcgAifIAnEFBVoAKJ84wSzgM1IAMT5HxYktSAHE+UFRRqQIJZfp9QBJVXUyQAXWkQA" assert ( share_url From 05de4dbe34ff9a61b6037e7ec5696898f006bf88 Mon Sep 17 00:00:00 2001 From: mattijn Date: Fri, 22 Dec 2023 14:54:42 +0100 Subject: [PATCH 11/11] add change note --- doc/releases/changes.rst | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/doc/releases/changes.rst b/doc/releases/changes.rst index 206e7f8c3..998fbe3e9 100644 --- a/doc/releases/changes.rst +++ b/doc/releases/changes.rst @@ -8,10 +8,14 @@ Version 5.3.0 (unreleased month day, year) Enhancements ~~~~~~~~~~~~ +- Support restrictive FIPS-compliant environment (#3291) + Bug Fixes ~~~~~~~~~ + Backward-Incompatible Changes ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +- Changed hash function from ``md5`` to a truncated ``sha256`` non-cryptograhic hash (#3291) Version 5.2.0 (released Nov 28, 2023) -------------------------------------------