Sunday, November 4, 2012

Improving The Site Security - Checking .asc files with PGP (GPG)


This example shows step by step how to check security issues about a downloaded file applying concepts exposed on Apache's tutorial .


If you just want to test integrity, a simpler alternative is using MD5 or SHA, but checking both, integrity and signature, offers a better security solution.
This makes sense when downloading security libraries to a secure service or web service.


How can you assure that your site is secure if its libraries are not checked at all?
Just because you use SSH and all the stuff about, how can you be sure that the libraries were not tampered and they are exactly what you expect to be?
So, it's necessary to expend some time to make sure and construct security from the basis.

If downloading a Apache file, you'll probably has already seen on the download page, the following:

It is essential that you verify the integrity of the downloaded files using the PGP or MD5 signatures.
The PGP signatures can be verified using PGP or GPG.
First download the KEYS as well as the asc signature file for the relevant distribution.
Make sure you get these files from the main distribution site, rather than from a mirror. Then verify the signatures using

% pgpk -a KEYS
% pgpv downloaded_file.asc
or
% pgp -ka KEYS
% pgp downloaded_file.asc
or
% gpg --import KEYS
% gpg --verify downloaded_file.asc




On the procedure above, you import the keys (KEYS) in order to be able to verify the downloaded files and check the files' integrity.
 
Nevertheless, suppose that you don't have the keys from KEYS file, or yet if you'd like to check further, considering the message returned by the --verify option:
gpg: WARNING: This key is not certified with a trusted signature!
gpg:          There is no indication that the signature belongs to the owner.



Below, it's shown an example of a procedure based on "web of trust".
Although long at first sight, many steps done once will not be repeated twice. The data collected is maintained and the next steps become faster and easier.
First time is a first time... well, you just know how it works!


This example uses GnuPG, but the concepts are the same, so feel free to work with your favorite environment and tool.

From the documentation we have:
gpg is the OpenPGP part of the GNU Privacy Guard (GnuPG). 
It is a tool to provide digital encryption and signing services  using  the  OpenPGP      standard.
...
The gpg command is the standalone version of gpg.  
For desktop use you should consider using gpg2.

The example uses two files downloaded from wss4j project which represents a possible and real use case when a developer is creating secure solutions.

The version downloaded by this time were:

wss4j-bin-1.6.7.zip (the binary)
wss4j-bin-1.6.7.zip.asc  (and its respective .asc file)


1. First, put the both target files under the same folder.

2. Disvover the ID, typing the command (GnuPG must be installed):
 gpg wss4j-bin-1.6.7.zip.asc
 or
 gpg --verify wss4j-bin-1.6.7.zip.asc

The output:
gpg: Signature made Wed 25 Jul 2012 11:25:57 AM BRT using RSA key ID 0AD53983
gpg: Can't check signature: public key not found

3. Getting the public key from a trusted source, a public well known and reliable keyserver:
 gpg --keyserver pgpkeys.mit.edu --recv-key 0AD53983

4. After importing, repeat the 3rd step.
Now it shall recognize the signature against the target file:
 gpg wss4j-bin-1.6.7.zip.asc
 or
 gpg --verify wss4j-bin-1.6.7.zip.asc

Output:
gpg: Signature made Wed 25 Jul 2012 11:25:57 AM BRT using RSA key ID 0AD53983
gpg: Good signature from "Colm O hEigeartaigh <coheigea@apache.org>"
gpg: WARNING: This key is not certified with a trusted signature!
gpg:          There is no indication that the signature belongs to the owner.
Primary key fingerprint: DB45 ECD1 9B97 514F 7271  05AE 67BF 80B1 0AD5 3983

Notice that the last 8 digits from the fingerprint shall be equal to the key ID.


5. Getting the fingerprint to validade the public key:
 gpg --fingerprint 0AD53983

Output:
pub   2048R/0AD53983 2011-02-10
Key fingerprint = DB45 ECD1 9B97 514F 7271  05AE 67BF 80B1 0AD5 3983
uid                  Colm O hEigeartaigh <coheigea@apache.org>
sub   2048R/1C6209E9 2011-02-10



6. Checking if the public key really exists.

Above (3rd step), we got the public key from MIT.

So, checking using another trusted source to confirm, we search by "coheigea" at RedIris .

The result returned:


The ID 0AD53983 was also found on another reliable public keyserver.
Remember that a keyring or keyserver may be tampered also, but exactly the two ones at the same time... it's something quite remote.





7. Who is coheigea@apache.org?

We can not call him on the phone or cell.
Imagine, zillions of people doing that... No way!
So, that's when networking comes in.


Our first attempt, following the Apache's documentation is to point to the Apache's web of trust at
 http://people.apache.org/~henkp/trust/apache.html


He was not found there and probably is not up to date or something else, but after a fast search on web, he was found on twitter  and belongs to the Apache community.



8. Does somebody else know and endorse Colm O hEigeartaigh?

Let's verify, issuing:
 gpg wss4j-bin-1.6.7.zip.asc
 or
 gpg --verify wss4j-bin-1.6.7.zip.asc

Output:
gpg: Signature made Wed 25 Jul 2012 11:25:57 AM BRT using RSA key ID 0AD53983
gpg: Good signature from "Colm O hEigeartaigh "
gpg: WARNING: This key is not certified with a trusted signature!
gpg:          There is no indication that the signature belongs to the owner.
Primary key fingerprint: DB45 ECD1 9B97 514F 7271  05AE 67BF 80B1 0AD5 3983

It's signed by itself.
To discover more details about that signature, do:
 gpg --list-sigs 0AD53983

Output:
pub   2048R/0AD53983 2011-02-10
uid                  Colm O hEigeartaigh
sig          DEDEAB92 2012-02-06  [User ID not found]
sig 3        0AD53983 2011-02-10  Colm O hEigeartaigh
sub   2048R/1C6209E9 2011-02-10
sig          0AD53983 2011-02-10  Colm O hEigeartaigh

On the output (yellow), we see that it is signed by 0AD53983.
Who is 0AD53983?

To answer, we do:
 gpg --keyserver pgpkeys.mit.edu --recv-key DEDEAB92

Output:
gpg: requesting key DEDEAB92 from hkp server pgpkeys.mit.edu
gpg: key DEDEAB92: public key "Sergey Beryozkin (Release Management) " imported
gpg: 3 marginal(s) needed, 1 complete(s) needed, PGP trust model
gpg: depth: 0  valid:   3  signed:   0  trust: 0-, 0q, 0n, 0m, 0f, 3u
gpg: next trustdb check due at 2012-12-02
gpg: Total number processed: 1
gpg:               imported: 1


9. Who is sberyozkin@gmail.com?                                                                        
Again, the same problem, we can not get a direct contact, but we can check the informations to discover if they match and are coherent.

Searching for "sberyozkin" we find many sources including his twitter, noticing that he also works on Apache's community and etc.


As we see, details match...

So, this is web of trust, not directly endorsed but endorsed indirectly by networking using social media and other sources.

Conclusion:                                                                                                           
His ID is found on two public trusted sources, and he's a well known and active member of Apache's community working on the respective subject and also endorsed by somebody else "on the field".

Enough, done.

If the target were not well known, certainly it would be necessary to extend the networking survey, to grab enough information to create a context that could give us some kind of security.


Important Considerations


1. Alternatives and Additional Tips

Many sites have a section on the download page that shows how to test integrity and offer a key list of developers.

Very handy because you enrich your keyring faster.
More practical, instead of importing one by one when you need, as done above by example.

As referred on the beginning, Apache offers the keys on the download pages, for instance go to apache geronimo (the application server).

You find there a reference to a KEYS file containing such keys.


2. Good practices

From Apache's tutorial, we get:

...
Attackers can easily create new keys similar to yours with identical user IDs and comments.
Such a public key may be introduced to your keyring when you download keys from a public keyserver or as part of an import.

...
Trusting that an import contains only the owner's public key is not recommended.
The import may contain additional public keys (either intentionally or not).
So, when using an import, always verify the key ID of interest from another source.

...
                                                                                   

In practice, in most of the cases, it is not possible to get in touch with the owner.
So, consider some good and important additional security practices:

1. Keep control of the keyring's number of registries.
Check before and after the import.

2. After an import, always check it, otherwise your keyring will loose confidence.

3. Create a backup after an import operation and periodically.
Check http://www.apache.org/dev/openpgp.html#backup-private


To count the number of registries of your keyring you can use a script like this :

#!/bin/sh
# last update: 11/08/2012 11:34:53 AM
# name: gpgcounter
#
# target: returns the number of registries on a GnuPG keyring.
#
#IMPORTANT NOTE:
#On the GnuPG's man page, there is a note:
#  Avoid  using the output of this command in scripts or other programs
#  as it is likely to change as GnuPG  changes.
#
# So, you shall test the script with your version before using it.
#
# syntax:
#
#   gpgcounter
# set here the GnuPG version used for creation or test
GPGVER="1.4.9"

pubs=$(gpg --list-keys | grep '^pub' | uniq -c | awk '{sum += $1} END {print sum}')
uids=$(gpg --list-keys | grep '^uid' | uniq -c | awk '{sum += $1} END {print sum}')
subs=$(gpg --list-keys | grep '^sub' | uniq -c | awk '{sum += $1} END {print sum}')
gpgver=$( gpg --version | grep ^gpg | awk '{print $3}')

if ! [ "$gpgver" = "$GPGVER" ] ; then
    echo ""
    echo "**************************************************************************"
    echo "[WARN]: this script was tested with gpg v.$GPGVER."
    echo "  The current GnuPG version (v.$gpgver) differs from v.$GPGVER  (See: gpg --version)"
    echo "     Check the following command in order to confirm its validity:"
    echo "       gpg --list-keys"
    echo "  It shall return an output formatted like the following example:    "
    echo "       pub   4096R/2E63F262 2012-07-13"
    echo "       uid          John Xiao (CODE SIGHING KEY) "
    echo "       sub   4096R/64F9AF14 2012-07-13"
    echo ""
    echo " If the output format is different from the example, the script must be altered to reflect the new changes."
    echo ""
else
    echo "[INFO]: gpgcounter totals (pub, uid, sub): $pubs, $uids, $subs at $(date +%y%m%d_%H%M%S) by $USER for gpg v.$GPGVER"
fi  


If *nix environment, create the file gpgcounter.sh copying the content above, then do:
chmod 755 gpgcounter.sh
./gpgcounter.sh

The little script will return something like this:
 [INFO]: gpgcounter totals (pub, uid, sub): 6, 7, 5 at 121106_174037 by alsdias  for gpg v.1.4.9                                   

Save the information to an encrypted control file somewhere else.
If your keyring is tampered, certainly you'll have a better chance to discover it.

NOTE:                                                                                                  

On the GnuPG's man page, there is a note:
   Avoid  using the output of this command in scripts or other programs 
   as it is likely to change as GnuPG  changes.

So, the script also tests your current version.
If the current version differs, it returns a warning.
It also has a note for which version it was created, echoing it into the statistics returned.
That way, the script checks and alerts the user about the version that it was created or tested for.



Conclusion                                                                                                              


Security comes from the basis.
Import is a key point.
Think about it.


Additional sources:
Apache's tutorial
apache geronimo download site containing instructions

3 comments:

  1. It also has a note for which version it was created, echoing it into the statistics returned.

    ReplyDelete
  2. If your keyring is tampered, certainly you'll have a better chance to discover it.

    ReplyDelete
  3. It also has a note for which version it was created, echoing it into the statistics returned.

    ReplyDelete

eclipse: java: SLF4J: Failed to load class "org.slf4j.impl.StaticLoggerBinder" or Exception in thread "main" java.lang.NoClassDefFoundError: org/slf4j/impl/StaticLoggerBinder

  >PROBLEM Using Eclipse, you try to run a simple logging test using "org.slf4j.Logger" like the sample below: package Test; im...