Introduction to Apt Authentication
Apt-get package management uses public key cryptography to authenticate downloaded packages.
Debian does an excellent job of explaining Secure apt on this wiki page.
What follows is a short summary of the key acquisition and verification process gleaned from Debian's wiki page.
Public key cryptography is based on pairs of keys, a public key and a private key. The public key is given out to the world; the private key must be kept a secret. Anyone possessing the public key can encrypt a message so that it can only be read by someone possessing the private key. It's also possible to use a private key to sign a file, not encrypt it. If a private key is used to sign a file, then anyone who has the public key can check that the file was signed by that key. No one who doesn't have the private key can forge such a signature.
gpg (GNU Privacy Guard) is the tool used in secure apt to sign files and check their signatures.
apt-key is a program that is used to manage a keyring of gpg keys for secure apt. The keyring is kept in the file '/etc/apt/trusted.gpg' (not to be confused with the related but not very interesting /etc/apt/trustdb.gpg). apt-key can be used to show the keys in the keyring, and to add or remove a key.
Each time you add another apt repository to /etc/apt/sources.list, you'll also have to give apt its key if you want apt to trust it. Once you have obtained the key, you can validate it by checking the key's fingerprint and then signing this public key with your private key. You can then add the key to apt's keyring with apt-key add <key>
How to Find a Key
There is not yet a standard location where you can find the key for a given apt repository. You will most likely find the key on the repository's web page or as a file in the repository itself.
gpg itself has a standard way to distribute keys, using keyservers that gpg can download a key from and add to its keyring. For example:
joey@dragon:~>gpg --keyserver pgpkeys.mit.edu --recv-key 2D230C5F gpg: requesting key 2D230C5F from hkp server pgpkeys.mit.edu gpg: key 2D230C5F: public key "Debian Archive Automatic Signing Key (2006) <ftpm firstname.lastname@example.org>" imported gpg: Total number processed: 1 gpg: imported: 1
How to Validate a Key
Once a key is imported it should be validated. GnuPG uses a powerful and flexible trust model that does not require you to personally validate each key you import. Some keys may need to be personally validated, however. A key is validated by verifying the key's fingerprint and then signing the key to certify it as a valid key. A key's fingerprint can be quickly viewed with the --fingerprint command-line option, but in order to certify the key you must edit it.
alice% gpg --edit-key email@example.com pub 1024D/9E98BC16 created: 1999-06-04 expires: never trust: -/q sub 1024g/5C8CBD41 created: 1999-06-04 expires: never (1) Blake (Executioner) <firstname.lastname@example.org> Command> fpr pub 1024D/9E98BC16 1999-06-04 Blake (Executioner) <email@example.com> Fingerprint: 268F 448F CCD7 AF34 183E 52D8 9BDE 1A08 9E98 BC16
A key's fingerprint is verified with the key's owner. This may be done in person or over the phone or through any other means as long as you can guarantee that you are communicating with the key's true owner. If the fingerprint you get is the same as the fingerprint the key's owner gets, then you can be sure that you have a correct copy of the key.
After checking the fingerprint, you may sign the key to validate it. Since key verification is a weak point in public-key cryptography, you should be extremely careful and always check a key's fingerprint with the owner before signing the key.
The Web of Trust
How do you verify the authenticity of the key if you don't know the key's owner? It's good to be paranoid in security, but verifying things from here is harder. gpg has the concept of the web of trust, a chain of key signatures that start with someone you trust, who signs someone's key, who signs some other key, until you get to the key you would like to validate. In other words, if you're sufficiently concerned you'll want to check that the repository key is signed by a key that you can trust, with a trust chain that goes back to someone you know personally. If you want to do this, visit an Ubuntu conference or perhaps a local Linux Users Group for a key signing party.
For more, see this blog post about checking the trust path from your personal key to at least one of the keys used to sign the archive/repo key.
Once you have validated and signed the public key, you export that key from your own keyring and feed it to apt-key:
joey@dragon:~>gpg -a --export 2D230C5F | sudo apt-key add - gpg: no ultimately trusted keys found OK
The Warning: "no ultimately trusted keys found" means that gpg was not configured to ultimately trust a specific key. Trust settings are part of OpenPGPs Web-of-Trust
Validation of Release File and Packages
Secure apt now verifies the Release file, which is updated each time any of the packages in the archive change. The Release file itself contains, among other things, md5 checksums of other files in the archive. If it cannot download the Release.gpg, or if the signature is bad, it will complain, and will make note that the Packages files that the Release file points to, and all the packages listed therein, are from an untrusted source.
Here's what that looks like:
W: GPG error: http://ftp.us.debian.org testing Release: The following signatures couldn't be verified because the public key is not available: NO_PUBKEY 010908312D230C5F
If you ignore that warning and try to install a package later, apt will warn again:
WARNING: The following packages cannot be authenticated! libglib-perl libgtk2-perl Install these packages without verification [y/N]?
Note that you can disable these checks by running apt with --allow-unauthenticated