Skip to content

Conflicting Google hashing implementations and invalid SHA-256 test vectors, In #1167 and #1168 #1173

Description

@frankii91

Problem

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.

Reproduction

Source Input after the confirmed preprocessing UTF-8 bytes Google result Standard SHA-256
#1168 anna maria 616e6e61206d61726961 833e2dd6d6349d9c79e6027c9be7bfeb5f5148003666d92ef1f35fb0800b3967 dfa29cee752c3d2bb1a935e9ea1a3d474b5634a9086fd5cc66be4178dffa865f
#1168 jan<TAB>kowalski 6a616e096b6f77616c736b69 6f19430c50dcf1a21dcf5ed1340b37cb3a0dbe0ff148d488f8d6df022a1ce092 d91b4c77588fde5baeef0cbea9ccc382aaf57748f089a2396b519d4dea0f5656
#1167 anna<TAB>maria 616e6e61096d61726961 6f19430c50dcf1a21dcf5ed1340b37cb3a0dbe0ff148d488f8d6df022a1ce092 67a989bd9bac801d9a1cf2c67cb44514dd6d559391954fa92b5decc45c63810f
#1167 é c3a9 a3248310c812cf518778f2441c2c31e6730700889f81a1795c762dd3a669cfeb 4a99557e4033c3539de2eb65472017cad5f9557f7a0625a09f1c3f6e2ba69c4c

The same calculation was performed with:

  • 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.

Required clarification

Please provide:

  1. Correct SHA-256 vectors for Clarify AddressInfo normalization rules for whitespace, punctuation, digits, and Unicode #1167 and Enhanced conversions address_info normalization #1168.
  2. The exact pre-hash bytes and runnable code used to generate every corrected vector.
  3. 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.
  4. Confirmation that Google's production systems use standard FIPS 180-4 SHA-256 without an undocumented transformation, salt, HMAC or additional hashing pass.
  5. A review and correction of all official language examples and field documentation that currently produce different hashes.

References:

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't workingtriageNeed triage

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions