You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
In #1167 and #1168, Google confirmed that hashed_first_name, hashed_last_name and hashed_street_address should be calculated from:
UTF-8(NFC(lowercase(trim(original_value))))
Internal whitespace, punctuation, digits and diacritics should be preserved.
This confirmation conflicts with existing Google documentation and language examples that remove internal whitespace, punctuation, digits or symbols before hashing. Following different official Google sources therefore produces different hashes for the same customer data.
The SHA-256 vectors supplied with the clarification are also incorrect. They cannot be reproduced from the input strings shown by Google.
JavaScript: Node.js crypto.createHash() and Web Crypto subtle.digest() with TextEncoder
PHP: hash('sha256', $value)
Python: hashlib.sha256(value.encode('utf-8'))
OpenSSL and sha256sum
All implementations returned the values in the Standard SHA-256 column. None returned the values published by Google.
There is also an unambiguous error across the two responses: Google assigned the same digest, 6f19430c..., to both jan<TAB>kowalski and anna<TAB>maria. These are different byte sequences and their SHA-256 digests are different.
Broader concern
This is not only an isolated error in one table. The confirmed method differs from other official Google documentation and code samples, while the vectors intended to define the correct method are themselves invalid.
Without valid canonical vectors, developers cannot determine which Google implementation matches production behavior. This creates a reasonable concern that other official samples or integrations may also generate incorrect hashes. Such hashes remain syntactically valid and can be accepted by the APIs while silently failing to match.
The exact pre-hash bytes and runnable code used to generate every corrected vector.
One authoritative hashing and preprocessing specification shared by Google Ads API, Data Manager API and GA4 Measurement Protocol, or an explicit specification of their differences.
Confirmation that Google's production systems use standard FIPS 180-4 SHA-256 without an undocumented transformation, salt, HMAC or additional hashing pass.
A review and correction of all official language examples and field documentation that currently produce different hashes.
Problem
In #1167 and #1168, Google confirmed that
hashed_first_name,hashed_last_nameandhashed_street_addressshould be calculated from:Internal whitespace, punctuation, digits and diacritics should be preserved.
This confirmation conflicts with existing Google documentation and language examples that remove internal whitespace, punctuation, digits or symbols before hashing. Following different official Google sources therefore produces different hashes for the same customer data.
The SHA-256 vectors supplied with the clarification are also incorrect. They cannot be reproduced from the input strings shown by Google.
Reproduction
anna maria616e6e61206d61726961833e2dd6d6349d9c79e6027c9be7bfeb5f5148003666d92ef1f35fb0800b3967dfa29cee752c3d2bb1a935e9ea1a3d474b5634a9086fd5cc66be4178dffa865fjan<TAB>kowalski6a616e096b6f77616c736b696f19430c50dcf1a21dcf5ed1340b37cb3a0dbe0ff148d488f8d6df022a1ce092d91b4c77588fde5baeef0cbea9ccc382aaf57748f089a2396b519d4dea0f5656anna<TAB>maria616e6e61096d617269616f19430c50dcf1a21dcf5ed1340b37cb3a0dbe0ff148d488f8d6df022a1ce09267a989bd9bac801d9a1cf2c67cb44514dd6d559391954fa92b5decc45c63810féc3a9a3248310c812cf518778f2441c2c31e6730700889f81a1795c762dd3a669cfeb4a99557e4033c3539de2eb65472017cad5f9557f7a0625a09f1c3f6e2ba69c4cThe same calculation was performed with:
crypto.createHash()and Web Cryptosubtle.digest()withTextEncoderhash('sha256', $value)hashlib.sha256(value.encode('utf-8'))sha256sumAll implementations returned the values in the
Standard SHA-256column. None returned the values published by Google.There is also an unambiguous error across the two responses: Google assigned the same digest,
6f19430c..., to bothjan<TAB>kowalskiandanna<TAB>maria. These are different byte sequences and their SHA-256 digests are different.Broader concern
This is not only an isolated error in one table. The confirmed method differs from other official Google documentation and code samples, while the vectors intended to define the correct method are themselves invalid.
Without valid canonical vectors, developers cannot determine which Google implementation matches production behavior. This creates a reasonable concern that other official samples or integrations may also generate incorrect hashes. Such hashes remain syntactically valid and can be accepted by the APIs while silently failing to match.
Required clarification
Please provide:
References: