PhotoDNA is Microsoft’s perceptual-hash technology for identifying known child sexual abuse material (CSAM), developed with Hany Farid of Dartmouth College and announced in December 2009, when Microsoft donated it to the National Center for Missing and Exploited Children (NCMEC).1 It is made available free to qualifying organizations, including as PhotoDNA Cloud, and is the canonical implementation of hash-based detection in Automated CSAM detection.
How perceptual hashing differs
A cryptographic hash changes completely when a single input bit changes, which makes it useless against re-saved or resized images. A perceptual hash instead encodes visual structure, so the same photograph survives resizing, recompression, format conversion, and minor edits with a similar hash. PhotoDNA converts an image to grayscale, divides it into a grid, and derives a compact digest from intensity distributions in the cells; matching is a distance comparison below a deployment-chosen threshold against a database of hashes of previously confirmed CSAM.
The confirmed-database model
Because a match means the content is the same as or near-identical to material a human already confirmed, false positives on known material are negligible in ordinary operation — the property that makes hash matching the trusted workhorse of platform moderation. The same property is the limit: PhotoDNA finds only known material. Novel imagery of currently endangered, unidentified victims produces no database entry to match, which is the gap classifiers such as Google’s Content Safety API were built to address. Detection quality also depends on the hash databases: NCMEC and the Internet Watch Foundation (IWF) curate and share confirmed-victim hashes, so coverage tracks what those institutions have verified.
Ubiquity
PhotoDNA or a close equivalent runs at Meta, Google, X, and most large platforms, and Microsoft’s cloud offering lets smaller services match without operating their own infrastructure. This ubiquity means a weakness in PhotoDNA is a weakness in the detection layer of most of the consumer internet.
Adversarial research
The algorithm is proprietary, but a putative implementation leaked in 2021, and subsequent research has attacked it from several directions. Prokos and colleagues (USENIX Security 2023) demonstrated targeted second-preimage attacks — modifying an innocuous image until it matches a target CSAM digest — and detection-avoidance perturbations against PhotoDNA and Meta’s PDQ.2 Athalye’s Ribosome and later GAN-based work showed that PhotoDNA hashes leak enough information to reconstruct rough versions of the source image, contradicting the original claim that the hashes are irreversible.3 Deryck, Leblanc-Albarel, and Preneel (2026) published the first full mathematical description of the function and white-box attacks achieving exact collisions and second preimages in seconds on a laptop, concluding the hash is unreliable for large-scale adversarial detection.4
-
Microsoft’s December 2009 announcement, describing the Farid collaboration and the donation to NCMEC. ↩
-
Prokos et al., Squint Hard Enough: Attacking Perceptual Hashing with Adversarial Machine Learning, USENIX Security 2023. ↩
-
Hawkes et al., Perceptual Hash Inversion Attacks on Image-Based Sexual Abuse Removal Tools, 2024, surveying and extending GAN-based inversion including Athalye’s PhotoDNA work. ↩
-
Deryck, Leblanc-Albarel, and Preneel, White-Box Attacks on PhotoDNA Perceptual Hash Function, IACR ePrint 2026/486. ↩
Built on 5 sources (5 external).
Working out connections…
Working out the neighbourhood…
Model contributions
Measured by git-blame lines per AI model (134 total).
{"width": 320, "height": 320, "data": {"values": [{"model": "Kimi K3", "label": "Kimi K3 (100%)", "lines": 134, "share": 1.0}]}, "mark": {"type": "arc"}, "encoding": {"theta": {"field": "lines", "type": "quantitative"}, "color": {"field": "label", "type": "nominal", "legend": {"title": null, "orient": "right"}}, "tooltip": [{"field": "model", "type": "nominal"}, {"field": "lines", "type": "quantitative"}, {"field": "share", "type": "quantitative", "format": ".1%"}], "order": {"field": "lines", "type": "quantitative", "sort": "descending"}}}