cmhteixeira
cmhteixeira

Reputation: 967

Maven Artifact - Why PGP signatures and md5/sha1 hashes?

Why does maven central require both PGP signatures and MD5/SHA-1/etc. hashes? Shouldn't the PGP signature be enough?

On the maven central repository, for each artifact there is a:

  1. .asc file - containing the PGP signature for the artifact.
  2. .md5 file - containing the MD5 digest for the artifact.
  3. .sha1 file - containing the SHA-1 digest for the artifact.
  4. .sha256 file - containing the SHA-256 digest for the artifact.
  5. .sha512 file - containing the SHA-512 digest for the artifact.
  6. .asc.md5 file.
  7. .asc.sha1 file.
  8. .asc.sha256 file
  9. .asc.sha512 file.

As an example, you can check this publication: https://repo1.maven.org/maven2/org/gradle/gradlebuild/configuration-cache-report/1.0/
I am not really sure what the .asc.md5, .asc.sha1, etc. files represent. Are these the digests encrypted with the private key of the signature?

My reasoning is as follows:

  1. I understand the value of the MD5, SHA1, SHA256, and SHA512 digests. It allows you to check if the artifact that you have downloaded is not corrupted. You do this by computing the digest yourself (of the downloaded artifact) and comparing it with corresponding public digest.

  2. I appreciate also that this does not guarantee the authenticity of the artifact. As someone "in-the-middle" could be serving you a malicious artifact and corresponding fake .md5, .sha1, .sha256, and .sha512 files. I understand also that using an https connection to maven central does not solve this. (as, for example, the site could be accessed through a proxy with custom certificates installed on the machine, someone could have uploaded a malicious artifact without the developer's permission, etc.)

  3. My understanding is that PGP signatures solves the issue above by the following mechanism

    Creator of the artifact
    PGP(original-artifact, privateKey) = .asc file
    Where, as I understand it, the .asc file is the signature. Which is basically a digest of the artifact which is then encrypted using the private key, and added with some meta information, namely the hash algorithm.

    MavenClient
    PGP(downloaded-artifact, publicKey, .asc file)

    1. Compute digest of The downloaded artifact using the same hash function used to compute the digest on the signature. This is, I assume, stored as metadata on the signature itself (.asc file).
    2. Decrypt the digest contained within the signature using the public key.
    3. Compare the digest from steps 1 and 2.

    Therefore, I would say, that if the digests match then we verified the authenticity of the artifact, but we also verified that it has not been corrupted. Otherwise the digest would be different, right?

Then this begs the question. Why do we need the extra .md5 and .sha1 files?

As a bonus question. Why isn't the public key required to be stored on maven as well? Wouldn't this make things clearer? As it stands, you don't have all the required files/data to verify authenticity. You have to pick up the public key from a PGP server.

So, to summarize, I have the following 3 questions:

  1. Why does maven central require both PGP signature of the artifact and also md5/sha1 hashes? Why isn't PGP signature enough?
  2. What do the .asc.md5, .asc.sha1, etc. files represent?
  3. Why isn't the public key stored alongside everything else?

Upvotes: 3

Views: 1761

Answers (1)

Cisco
Cisco

Reputation: 22952

https://maven.apache.org/repository/guide-central-repository-upload.html

Quoting the guide above for (1):

To improve the quality of the Central Repository, we require you to provide PGP signatures for all your artifacts (all files except checksums).

As I understand, any artifact such as a JAR, ZIP, TAR, and more must be signed. Checksums such as md5 or sha1 do not need to be signed.

(2) They are the signed checksums. For Gradle specifically, the Signing plugin signs all outputs. So for example, a MavenPublication outputs typically a POM and JAR artifact. When the signing plugin is instructed to sign the publication, then it generates checksum files and signs them for each artifact.

Note that you can disable some checksums: https://docs.gradle.org/6.0.1/release-notes.html#publication-of-sha256-and-sha512-checksums

(3) It's unusual to publish your public key to a Maven repository. Although I don't believe anything is stopping you. Although since it would be treated as any artifact, you would need to sign it...which doesn't make sense.

Upvotes: 3

Related Questions