Safeguard
Best Practices

Installing and Verifying Java on macOS Securely

A SHA-256 checksum only proves a JDK download wasn't corrupted in transit — it takes a GPG signature check to prove it actually came from the vendor you trust.

Safeguard Research Team
Research
6 min read

Most macOS developers install a JDK the same way they install anything else — download a .pkg, double-click it, and move on — without ever checking whether the file that landed on disk is the one the vendor actually published. That gap matters more than it looks: the Eclipse Adoptium project, which produces the Temurin OpenJDK builds used by an estimated large share of production Java deployments, publishes a SHA-256 checksum and a GPG signature alongside every single release artifact, specifically because a checksum alone cannot prove where a file came from. In 2024, Adoptium's build and release pipeline underwent an independent security audit funded by the Open Source Technology Improvement Fund (OSTIF), the same nonprofit that has audited projects like curl and Node.js — a signal of how seriously the OpenJDK distribution ecosystem now treats provenance, not just availability. Meanwhile macOS itself has quietly picked up its own verification layer: every notarized .pkg or .dmg installer carries an Apple-issued ticket that Gatekeeper checks before it will run, and spctl -a -vv can confirm that status before you double-click anything. This piece walks through choosing a trustworthy JDK vendor, verifying what you download before you install it, and confirming what actually ended up on your machine afterward.

Which JDK vendor should you actually trust on macOS?

Four vendors dominate the legitimate OpenJDK distribution landscape, and the right pick depends on what you're optimizing for, not brand loyalty. Eclipse Temurin, produced by the Adoptium Working Group (the successor to AdoptOpenJDK), is vendor-neutral, TCK-certified against the Java SE compatibility suite, and backed by a multi-company steering committee rather than a single vendor's roadmap. Amazon Corretto is a free, production-ready OpenJDK build with published long-term-support commitments, popular for teams already running on AWS. Azul Zulu offers TCK-certified builds in both a free Community edition and a paid Enterprise tier with extended support windows. Oracle JDK remains the reference implementation and, since JDK 17, has shipped under Oracle's No-Fee Terms and Conditions (NFTC) license, which permits free use in production — but only for a limited window after each release, after which continuing to receive updates on that version requires a paid Oracle subscription unless you upgrade to a newer LTS — a licensing detail that trips up teams who assume "free to start" means "free forever." All four publish checksums and signatures; the wrong choice isn't picking one of these, it's pulling a JDK from a third-party mirror or a search-result link that isn't one of them.

Why isn't a SHA-256 checksum enough to trust a download?

A checksum proves integrity, not authenticity, and conflating the two is the single most common mistake in JDK installation guides. If a .tar.gz or .pkg is corrupted mid-download, its computed SHA-256 hash won't match the published one, and a checksum check catches that reliably. But if an attacker intercepts the download in a man-in-the-middle position — or compromises the mirror serving both the file and the checksum page next to it — they can simply publish a matching checksum for their tampered file, and the check passes cleanly while verifying nothing about origin. This is exactly why Adoptium signs releases with GPG in addition to publishing SHA-256 sums: the GPG signature is generated with a private key the Adoptium release team controls, so verifying it (rather than just diffing a hash) is the step that actually proves the artifact came from Adoptium's own build pipeline and hasn't been substituted anywhere along the delivery chain, including on your own machine after download.

How do you verify a Temurin download with GPG on macOS?

Import Adoptium's public signing key once, then verify every release against it going forward. On a Mac with GnuPG installed (brew install gnupg if you don't have it), the sequence is:

curl -s https://packages.adoptium.net/artifactory/api/gpg/key/public | gpg --import

Then, after downloading both the .pkg installer and its matching .sig file from Adoptium's release page:

gpg --verify OpenJDK21U-jdk_x64_mac_hotspot_21.0.x_y.pkg.sig OpenJDK21U-jdk_x64_mac_hotspot_21.0.x_y.pkg

A "Good signature" line confirms provenance; anything else means stop before opening the installer. It's worth also confirming the SHA-256 checksum listed on the same release page with shasum -a 256 <file> — the two checks are complementary, not redundant, since the signature verifies the signer's identity while the hash confirms the exact bytes match what was signed.

What does Gatekeeper add on top of vendor checksums?

Gatekeeper and Apple notarization add an OS-level provenance check that's independent of anything the JDK vendor publishes. Since macOS Catalina, Apple requires developers distributing software outside the Mac App Store to submit binaries for automated malware scanning and staple a notarization ticket to the resulting .pkg or .dmg; Gatekeeper checks for that ticket, plus a valid Developer ID signature, before it will let the installer run without a manual override. You can check this yourself before opening any downloaded installer with:

spctl -a -vv /path/to/OpenJDK21U-jdk_x64_mac_hotspot.pkg

A response of "accepted" with a "Developer ID Installer" origin confirms Apple's checks passed. This doesn't replace vendor-side GPG verification — Gatekeeper only confirms Apple's notarization service saw and cleared the binary, not that it's the specific JDK release you intended to install — but it's a free, built-in second signal that costs nothing to check.

How do you confirm what's actually installed afterward?

Once installed, macOS's own java_home utility lets you audit exactly which JDK vendors and versions are present and which one is active, which matters because Homebrew casks, manual .pkg installs, and IDE-bundled JDKs frequently coexist on the same machine without anyone tracking it. Running:

/usr/libexec/java_home -V

lists every registered JDK with its vendor string and version path, so you can confirm the Temurin, Corretto, or Zulu build you verified is the one java -version actually resolves to — rather than an older, unverified JDK left behind by a previous install still sitting first in the JVM lookup order.

How Safeguard Helps

Verifying a single JDK download by hand is a five-minute task; verifying that every binary, container base image, and package your organization pulls in has intact provenance at scale is a different problem, and it's the one Safeguard's supply chain platform is built around. Safeguard's attestation and signing layer verifies SLSA provenance and Sigstore signatures on artifacts your pipelines consume the same way a GPG check verifies a JDK release — confirming an artifact was built by the pipeline it claims, from the source it claims, rather than trusting a checksum sitting next to the file it's meant to validate. For teams standardizing base images and dependencies, Safeguard's Gold registry applies that same provenance-first philosophy upstream, offering pre-verified, continuously rescanned artifacts across ten ecosystems so the "did I get the real thing" question gets answered once, centrally, instead of separately by every engineer who runs a curl command.

Never miss an update

Weekly insights on software supply chain security, delivered to your inbox.