An example NPM package metadata JSON looks like this (with dist
moved toward the top):
{
"name": "lodash",
"version": "4.17.21",
"description": "Lodash modular utilities.",
"dist": {
"integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==",
"shasum": "679591c564c3bffaae8454cf0b3df370c3d6911c",
"tarball": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz",
"fileCount": 1054,
"unpackedSize": 1412415,
"npm-signature": "-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJgMS3ZCRA9TVsSAnZWagAA8+4P/jx+SJ6Ue5oAJjz0L7gw\nLDD5YvP8aoliFq4GYkwUXfVQvOwomIPfa+U5Kao/hDfuwFQ/Bq5D5nSsl2bj\nrjJgvlKXna0SId8AgDgY2fB7zSfninuJvalY4iTWMN8DFSpG0XE2QFfoKpd3\njDmuzcNtgr79QV6DgjOVkHiP1IGNDlLTc1QEKiwo/5CdGQi1q/iCj6dViQMJ\nByuuuV2Qzi3f/FI25cG797WZar1MHhhlcnB50HiVBGp54IZOyuqdqWPduZQo\nvhONtonxPGBm3/J+uAkeUSSyL3Ud+FzLvdg8WEI9gDL0yvU4k0FcsnOONEYn\nngLaKEsw2xAnPBYW3Lf73Jnpwx6FAT3k49kgzxiNYSxEo7x4wiuNtBoDMyNw\nEKj6SZ0bUNmaJgiMfDnnDjCKjI3JrO1hho8z6CkwuvxuWLlW9wSsVayggzAI\nEhfeTeISugVHh332oDY2MI/Ysu8MnVN8fGmqeYQBBFj3aWatuA2NvVjACnX/\n54G7FtCU8TxZpm9shFRSopBx8PeI3r+icx1CT8YVFypY416PLnidHyqtME1G\neuRd1nWEz18hvVUAEHmuvHo+EPP3tITmTTUPQcZGMdBcZC+4UBmPMWX466HE\nbHw4aOnUWMa0sWfsERC5xzRZAb4lgMPEoTOnZyN4usMy7x9TzGZKZvU24HUE\nmpae\r\n=NOmG\r\n-----END PGP SIGNATURE-----\r\n",
"signatures": [
{
"keyid": "SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA",
"sig": "MEUCIF3Yithbtmy1aEBNlfNWbLswAfPIyQUuNUGARD3Ex2t4AiEA6TlN2ZKJCUpS/Sf2Z6MduF1BNSvayHIpu5wAcICcKXw="
}
]
},
"keywords": [
"modules",
"stdlib",
"util"
],
"homepage": "https://lodash.com/",
"repository": {
"type": "git",
"url": "git+https://github.com/lodash/lodash.git"
},
"icon": "https://lodash.com/icon.svg",
"license": "MIT",
"main": "lodash.js",
"author": {
"name": "John-David Dalton",
"email": "john.david.dalton@gmail.com"
},
"contributors": [
{
"name": "John-David Dalton",
"email": "john.david.dalton@gmail.com"
},
{
"name": "Mathias Bynens",
"email": "mathias@qiwi.be"
}
],
"scripts": {
"test": "echo \"See https://travis-ci.org/lodash-archive/lodash-cli for testing details.\""
},
"gitHead": "c6e281b878b315c7a10d90f9c2af4cdb112d9625",
"bugs": {
"url": "https://github.com/lodash/lodash/issues"
},
"_id": "lodash@4.17.21",
"_nodeVersion": "14.15.5",
"_npmVersion": "6.14.11",
"_npmUser": {
"name": "bnjmnt4n",
"email": "benjamin@dev.ofcr.se"
},
"directories": {
},
"maintainers": [
{
"name": "mathias",
"email": "mathias@qiwi.be"
},
{
"name": "jdalton",
"email": "john.david.dalton@gmail.com"
},
{
"name": "bnjmnt4n",
"email": "benjamin@dev.ofcr.se"
}
],
"_npmOperationalInternal": {
"host": "s3://npm-registry-packages",
"tmp": "tmp/lodash_4.17.21_1613835736675_0.01913912595366596"
},
"_hasShrinkwrap": false
}
Here are my questions related to the 3 fields:
dist.shasum
: This is said to be the shasum <tarball>
of the tarball (CLI command), using SHA-1.dist.integrity
: ChatGPT says (I think...) that this serves the same purpose as the shasum
, but is "more secure" (because sometimes it uses SHA-256 or SHA-512 encoding. But what is the real difference or reason for having both dist.shasum
and dist.integrity
? Do they differ in any other way? Do you need to check both?dist.signatures[*].sig
: What does this signature do? How do you use it? ChatGPT seems to say this is tested using public keys, but who has which sides of the keys, and when does this get used? When/why would you have more than one?Since we're here, too, how does dist.npm-signature
relate to the 3 things above?
https://blog.npmjs.org/post/172999548390/new-pgp-machinery seems to have the answers you are looking for, in particular
The
shasum
is a SHA-1 sum of the file. We’ve supplemented this to the side with anintegrity
field, based on the subresource integrity specification, to allow us to migrate to different hashing algorithms
and
The shasums above […] do not, however, protect against man-in-the-middle attacks. […] We offer you a way to detect this kind of tampering by signing package integrity fields along with some data that uniquely identifies the package-version. […] The registry signs the following data for each new package-version published:
<package>@<version>:<integrity>
. […] The detached signature is stored in thenpm-signature
field indist
.
then https://docs.npmjs.com/about-registry-signatures says
The public npm registry is migrating away from the existing PGP signatures [which were deprecated on April 25th 2023] to ECDSA signatures that are more compact and can be verified without extra dependencies in the
npm
CLI. […] Signatures are provided in the package's packument in each published version within thedist
object.
See also How does npm’s ECDSA signing system improve security?.