hashcash - hashcash anti-spam / denial of service counter-measure tool
hashcash [ options ] [ -b bits ] [ resource ]>
hashcash -c [ options ] -b bits -r resource [ token ]
hashcash -s [ options ] [ -b bits ]
hashcash -p now [ -j resource ] [ -k ] [ -t time ] [ -u ]
hashcash -w [ options ] [ token ]
hashcash -n [ options ] [ token ]
hashcash -l [ options ] -e period [ token ]
Hashcash is a denial-of-service counter measure tool. It's main current use is to help hashcash users avoid losing email due to content based and blacklist based anti-spam systems.
The hashcash tool allows you to create hashcash tokens to attach to emails you send, and to verify hashcash tokens attached to emails you receive. Email senders attach hashcash tokens with the X-Hashcash: header. Vendors and authors of anti-spam tools are encouraged to exempt mail sent with hashcash from their blacklists and content based filtering rules.
A hashcash token constitutes a proof-of-work which takes a parameterizable amount of work to compute for the sender. The recipient can verify received tokens efficiently. This package also includes a sha1 implementation which behaves somewhat like md5sum, but with SHA1.
The hashcash proof-of-work function is to compute partial hash collisions (the SHA1 hash function is used). By choosing the number of bits of collision, the work required to compute a collision can be made arbitrarily expensive -- from fractions of a second to minutes or hours. The verification is efficient requiring the same small cost whatever the collision size.
For more detailed discussion of other applications hashcash has been used for see http://www.hashcash.org/
In this man page a resource name is the name of the service or address the token is created for. In the case of email, the resource name is the recipient's email address in the form user@domain.com.
If neither the -c or -s option are given, it is assumed that you want to mint a token.
The resource name (recipient's email address) to mint the token against can be passed as an argument, or if omitted is read from stdin. If stdin is a tty the user is prompted, if stdin is a pipe the resource name is just silently read. The desired collision size can be specified with the -b option. If no collision size is specified, the default is 20 bits. As a convenience, if stdin is a tty and no collision size is given with the -b flag, the user is prompted for a collision size.
The -c flag must be given to check tokens. The token to check can
be given as an argument to hashcash
. If no token is given the
token is read from stdin. If stdin is a tty the user will be
prompted, if stdin is a pipe the token is just silently read. A
resource name (the recipient's email address) can be given with the
-r option. If a resource name is given the resource name is
compared to the resource name in the token, if they do not match, the
token is rejected.
Note: if no resource name is given the token is anyway checked to see if it is otherwise valid, but it could be minted for a different resource, which would allow tokens to be reused across different resources, so hashcash will return unchecked exit code on exit.
Tokens are by default considered to be valid forever. The validity period can be changed using the -e flag.
If the token has expired or has a date in the future the token is rejected and the program exits immediately.
If a required collision size is given with the -b flag, the tokens value is computed and compared, if the token has insufficent value it is rejected, and the program exits immediately. If the -b flag is not given, the token could be of any size, so hashcash will return unchecked exit code on exit.
If the token is double spent the token is rejected. Double spending protection is discussed in more detail below in Double Spending Protection. If double spending protection is not enabled, the token could be double spent, so hashcash will return unchecked exit code (exit code 2) on exit.
The -w flag can be used to request that the number of bits of the collision are counted and displayed; exit code unchecked (exit code 2) is returned on exit. The -n flag can be used to request that the resource name in the token is parsed out and displayed; exit code unchecked (exit code 2) is returned on exit. The -l flag can be used to request the number of seconds until expiry of the token is output; exit code unchecked (exit code 2) is returned on exit.
The program will only return exit codes valid or invalid if the -c flag is used, and all of the options -b bits, -d, -r resource are used. These are the minimum set of options necessary to fully check the validty of a token. If these criteria are not met, the program will return exit code unchecked (exit code 2) on exit. (See also the -y flag.)
If the -d flag is used with the -c flag a database of spent tokens is kept.
By default tokens expire after 28 days, without expiry the database would grow indefinately. You can specify an alternate expiry period with the -e flag. The recommended (and default) expiry period for email is 28 days. After the expiry period amount of time, the token is anyway considered expired and may be purged from the database to save space. (See Purging Periodically vs on Next Access for how to purge tokens.)
For efficiency reasons a token is verified before it is checked in the database; if it is otherwise invalid no database activity will occur.
Note: The decision about how long the token should be considered valid is up to the verifier. If it is too short it is possible for some applications that the token will expire before arriving at the recipient (eg with email.) The suggested value of 28 days should be safe for normal email delivery delays. The choice is a trade-off between database size and risk of expiry prior to arrival, and depends on the application.
Note: Different tokens in the same database can have different validity periods, so for example tokens for different resources with different validity periods can be stored in the same database, or the recipient may change the validity period for future tokens without affecting the validity of old tokens.
To purge old tokens periodically while checking tokens use the -p period option to purge no sooner than the given time period since the last purge. Purging can be used with the -k option to purge unexpired tokens also, and with the -r resource flag to purge only tokens for the given resource.
There are circumstances where it may be inconvenient to purge tokens
on the next access, for example if there is a large double spend
database which takes some time to purge, and the response time of the
hashcash checker is important. To avoid this problem, purging can be
done separately using just the -p now option to request just the
purge operation. On unix for example you could call hashcash -p
now
in a cron job once per day, or on demand when disk was running
low.
The -s flag requests measurement of how many collisions can be tested per second. No token is minted, or verified.
If the -b flag is used with this option, instead an estimate of how many seconds it would take to mint a token of the given size in bits is computed.
All informational output is printed on stderr. Minted tokens, and results of token verification and timing are printed on stdout. The quiet flag -q suppresses all informational output. The -v flag requests more informational output. The requested output, which is the only information that is output in quiet mode (when -q is specified) is printed on standard output. If stdout is a pipe, or when quiet mode is in effect the output is printed without description (ie just bits, just seconds, just resource).
hashcash
.
When checking tokens, the resource name (your own email address) can be given with the -r option. If the resource name is given it is checked against the resource name in the token, and if they do not match the token is rejected. Note if the resource name is not given, tokens for other resources would be accepted, and therefore hashcash returns exit code unchecked (exit code 2) on exit.
If used with the -d option, the spent token and it's expiry period is recorded in the database. See the -p option for description of how to purge tokens from the database.
The following -e usage to give an implicit time resolution while minting is deprecated, use explicit -z option instead. (-z overrides -e if both are given. -e still works for backwards compatibility. If neither are given the default is 6 chars (time format: YYMMDD)).
While minting tokens, the -e flag can have an effect on the resolution of time created in the token. Without the -e option, the default resolution is days (time format: YYMMDD). Alternate formats based on range of expiry period are as follows:
Note the rounding down is based on UTC time, not local time. This can lead to initially suprising results when rounding down to eg days in time zones other than GMT (UTC = GMT). It may be clearer to understand if you use the -u option.
Note the rounding down is based on UTC time, not local time. This can lead to initially suprising results when rounding down to eg days in time zones other than GMT (UTC = GMT). It may be clearer to understand if you use the -u option.
The default units for grace period are seconds. A single character suffix can be used to specify alternate units (m = minutes, h = hours, d = days, M = months, y = Y = years, and s = seconds).
If used in combination with -j resource only the tokens minted for the given resource are purged.
If used in combination with -k all tokens even un-expired tokens are purged. Can be used in combination with -t time to expire as if the current time were the given time.
When checking, if no token is given as an argument, scans stdin for a line starting with the string 'X-Hashcash:', and uses the rest of the matching line as the token. Only the lines up to and ending at the first blank line are scanned. A blank line is the separator used to separate the headers from the body of a mail message or USENET article. This is meant to make it convenient to pipe a mail message or USENET article to hashcash on stdin.
Time is expressed in local time by default. Use with -u flag to give time in UTC (GMT).
You can also give time relative to the current time by prefixing the argument with + or -. The default units for relative time are seconds. A single character suffix can be used to specify alternate units (m = minutes, h = hours, d = days, M = months, y = Y = years, and s = seconds).
Note: when time is expressed in local time, if there is daylight savings in your timezone, there are one or two ambiguous hours per year at the time of change from daylight savings time to normal time.
Note: the calculation includes the grace period, so can be up to 2 times grace period longer than you might otherwise expect (clock fast but system has to presume it could be slow). If you want to exclude the grace period add -g0 to set grace period to 0 for the calculation.
hashcash -s
hashcash -s -b 32
hashcash
hashcash foo
hashcash foo -b 10
hashcash -a -3d
hashcash -w 0:020814:foo:4333957e84db47f6
hashcash -q -b 10 foo | hashcash -w
hashcash -n 0:020814:foo:21c8cf3099cbf467
hashcash -l -e 30y 0:020814:foo:21c8cf3099cbf467
hashcash -c 0:020814:foo:21c8cf3099cbf467
hashcash -c -b24 0:020814:foo:21c8cf3099cbf467
hashcash -c -b24 -r foo 0:020814:foo:21c8cf3099cbf467
The examples given in Verifying Tokens can be modified to keep a double spend database so that the same token will not be accepted twice. Note a token will only be checked in and added to the database if it is otherwise valid and fully checked (a required number of bits of collision has been specified and a resource has been specified).
hashcash -cd -b 10 -r foo 0:020814:foo:21c8cf3099cbf467
hashcash -cd -b 10 -r foo 0:020814:foo:21c8cf3099cbf467
To prevent the double spend database growing indefinately, the recipient can request that tokens be no older than a specified period. After expiry old tokens can dropped from the double spend database as they will no longer be needed -- expired tokens can be rejected based purely on their old date, so the space taken by expired tokens in the double spend database can be saved without risk of accepting an expired though otherwise valid token.
The first field of the token is the UTC time since 1st January 1970. The default time format is YYMMDD, time rounded down to the nearest day. The default validity period is 28 days.
You can provide an alternative validity period with the -e option.
hashcash -cd -b 10 -e 2d -r foo 0:020811:foo:21dd87d4c9f5aae1
We gave option -e 2d so the tokens expiry date is 2 days after creation, which is now in the past.
Note: if the creation time is expressed in the token in days, the precise creation date is the begining of the specified day in UTC time (similarly for alternate units the creation time is rounded down to the begining of the unit it is expressed in). For units in days, for example, this may mean depending on your time zone that the token appears to be considered invalid in under the specified expiry period in days relative to your relative view of what day it is, as the calculation is based on current time in UTC, and the creation time of the token is expressed in UTC time.
hashcash -cd -b 10 -r foo 0:020811:foo:21dd87d4c9f5aae1
If the -c, -d options are used together, each time a token is checked, if it is valid and all of the mandatory aspects of the token are verified (collision bits check, resource name check) then the token and it's expiry period is written to the database file. The default expiry period if an expiry period is not given explicitly with the -e option is forever (ie tokens do not expire).
First mint and then add a token:
hashcash -b 10 foo -e 1m > token
hashcash -cd -e 1m -b 10 -r foo < token
hashcash -p now
hashcash -cd -e 1m -b 10 -r foo < token
With the default database (the sdb format) the database contents are human readable, so you can view their contents by cating them to the terminal:
cat hashcash.db
As a convenience you can purge at the same time as checking tokens by using the -p option with the -c option.
hashcash -b 10 foo > token
=item hashcash -cd -p now -e 1 -b 10 -r foo < token
hashcash
to purge no more
frequently than that time period since the previous purge.
For example:
hashcash -cd -p 1d -e 1 -b 10 -r foo < token
hashcash
to purge any expired tokens no more than once per
day.
hashcash -p 1M -j foo
hashcash
to purge only expired tokens matching resource foo
once per month.
hashcash -p now -k
hashcash
to purge all tokens (expired and unexpired) now.
where
hashcash
returns success (exit code 0) after successfully minting a
token, after fully checking a token and finding it valid, and after a
timing test.
If when checking a token it is found to be invalid (due to being
malformed, being expired, having insufficient value, having a date in
the future, or being double spent), hashcash
returns failure (exit
code 1).
If insufficient options are given to fully check a token, or if using the -n, -l, or -w options, if the token is otherwise valid return unchecked (exit code 2). If the -y flag is given and hashcash would normally return unchecked, exit code success is returned instead.
If any exception occurs (file read failure for database checking or corrupted database contents) an exit status of 3 is returned.
Written by Adam Back <adam@cypherspace.org>
sha1(1), http://www.hashcash.org/