{"id":31,"date":"2015-03-20T16:52:00","date_gmt":"2015-03-20T06:52:00","guid":{"rendered":""},"modified":"2018-05-22T20:51:01","modified_gmt":"2018-05-22T10:51:01","slug":"help-for-digest-checking","status":"publish","type":"post","link":"https:\/\/pbw.id.au\/blog\/2015\/03\/help-for-digest-checking\/","title":{"rendered":"Help for digest checking"},"content":{"rendered":"<p><i>Updated 2018-02-14<\/i><\/p>\n<p>It&#8217;s pretty important to check the digests of software you download. \u00a0When a downloaded file is accompanied by a signature file, for example a <i>gnupg .asc<\/i> file, you can verify the signature with various tools. \u00a0Often though, a download site will include the MD5 or SHA1 digest hash of the file, which allows a quick check on the file&#8217;s integrity. \u00a0OS X has an <i>\/sbin\/md5<\/i> command, and includes the <i>openssl<\/i> distribution. \u00a0Within <i>openssl<\/i>, the <i>digest<\/i> subcommand allows for the generation of digests for an array of digest algorithms, including MD5 and SHA1. \u00a0So it&#8217;s simple enough to generate the appropriate digest for that file you just downloaded.<\/p>\n<p>Comparing them is a bit tedious, though. \u00a0If you&#8217;re like me, you skim across the two digests \u2013 the one you generated and the one that the authors published \u2013 and look for eye-catching patterns near the beginning, middle and end. \u00a0That works pretty well in practice, but its hardly rigorous.<\/p>\n<p><!--more-->So I wrote myself a little script that generates a hash, and checks it against a hash value given as an argument. \u00a0Here&#8217;s the help output.<br \/>\n<code>\u00a0$ sha1 --help<br \/>\nUsage: sha1 &amp;lt;filename&amp;gt; [test-value]<br \/>\nwhere &amp;lt;filename&amp;gt; is required and test-value is<br \/>\nan optional hex digest value to test against.<br \/>\nExits with<br \/>\n1 if the number of arguments is wrong;<br \/>\n2 if the digest comparison fails;<br \/>\n3 if an unsupported algorithm is requested.<\/code><\/p>\n<p>or: sha1 &#8211;digests<br \/>\nwhich will echo the supported algorithms.<\/p>\n<p>or: sha1 &#8211;setup<br \/>\nwhich tries to ensure that hard links are set up for all digest algorithms.<br \/>\nExits with 4 if NOT all links are available after execution.<\/p>\n<p>Note that the user running this option must have write permission in the<br \/>\ndirectory containing the invoked program. Soft links are followed<br \/>\nto determine the actual directory containing the program.<br \/>\nAlternatively, you may manually set up your own softlinks in any directory.<\/p>\n<p>or: sha1 -&amp;lt;anything&amp;gt;<br \/>\nPrint this help text.<\/p>\n<p>Some of the executables may already exist on your system.\u00a0On OS X, for example,<br \/>\nthe executable \/sbin\/md5 is present. Which one is found depends on your PATH.<br \/>\n$<\/p>\n<h2>Installing the script<\/h2>\n<p>Download the script from\u00a0<a href=\"http:\/\/pbw.id.au\/code\/sha1\">here<\/a>. \u00a0The SHA1 digest of the script is<br \/>\n<code>1ef20a26423edc31dea2488b4e7b4671cd43f5de<\/code><br \/>\nThis assumes that your downloader is happy with UTF-8 or ASCII and the existing Unix line endings (LF). If it changes them, all bets are off.<\/p>\n<p>Select a location on your PATH. \u00a0I installed in <i>~\/bin<\/i>, but you may want to put it in <i>\/usr\/local\/bin<\/i> or some such system directory. \u00a0To do that you will have to use sudo or some equivalent. \u00a0Make sure the file is executable. \u00a0In my case, I would do this:<br \/>\n<code>$ mv ~\/Downloads\/sha1 ~\/bin\/sha1<br \/>\n$ chmod +x ~\/bin\/sha1<\/code><\/p>\n<h3>Set up links<\/h3>\n<p>The <i>&#8211;setup<\/i> option will try to set up hard links for each of the supported digest algorithms (a subset of the algorithms supported in <i>openssl digest<\/i>). \u00a0If you required <i>sudo<\/i> to install the script initially, you will also have to run the <i>&#8211;setup<\/i> as <i>sudo<\/i>. Your output will look something like this.<br \/>\n<code>$ sha1 --setup<br \/>\nExecutable \/Users\/pbw\/bin\/sha1 already exists.<br \/>\nExecutable \/Users\/pbw\/bin\/md5 created.<br \/>\nExecutable \/Users\/pbw\/bin\/sha256 created.<br \/>\nExecutable \/Users\/pbw\/bin\/sha384 created.<br \/>\nExecutable \/Users\/pbw\/bin\/sha512 created.<br \/>\nExecutable \/Users\/pbw\/bin\/dss1 created.<br \/>\n$<\/code><br \/>\nNow that it&#8217;s installed you can check a digest like so. \u00a0I&#8217;ll go to the Downloads folder and check (too late now, of course) the initial download.<br \/>\n<code>$ sha1 sha1 59254e751d0ce827770a73aae573f5294a1e1ac9<br \/>\nsha1 OK<br \/>\n59254e751d0ce827770a73aae573f5294a1e1ac9 EQUALS<br \/>\n59254e751d0ce827770a73aae573f5294a1e1ac9<br \/>\n$<\/code><br \/>\nLet&#8217;s see what happens if you change the comparison text.<br \/>\n<code>$ sha1 sha1 59254e751d0ce827770a73aae573f5294a1e1acA<br \/>\nsha1 FAIL<br \/>\n59254e751d0ce827770a73aae573f5294a1e1ac9 NOT EQUAL TO<br \/>\n59254e751d0ce827770a73aae573f5294a1e1aca<br \/>\n$<\/code><\/p>\n<p>The script returns <i>true<\/i> (0) for a successful comparison and <i>false<\/i> (in this case, 2) for a failure.<\/p>\n<p>That&#8217;s it folks!<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Updated 2018-02-14 It&#8217;s pretty important to check the digests of software you download. \u00a0When a downloaded file is accompanied by a signature file, for example a gnupg .asc file, you can verify the signature with various tools. \u00a0Often though, a download site will include the MD5 or SHA1 digest hash of the file, which allows &hellip; <a href=\"https:\/\/pbw.id.au\/blog\/2015\/03\/help-for-digest-checking\/\" class=\"more-link\">Continue reading<span class=\"screen-reader-text\"> &#8220;Help for digest checking&#8221;<\/span><\/a><\/p>\n","protected":false},"author":2,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"jetpack_post_was_ever_published":false,"_jetpack_newsletter_access":"","_jetpack_dont_email_post_to_subs":false,"_jetpack_newsletter_tier_id":0,"_jetpack_memberships_contains_paywalled_content":false,"_jetpack_memberships_contains_paid_content":false,"footnotes":"","jetpack_publicize_message":"","jetpack_publicize_feature_enabled":true,"jetpack_social_post_already_shared":false,"jetpack_social_options":{"image_generator_settings":{"template":"highway","default_image_id":0,"font":"","enabled":false},"version":2}},"categories":[19],"tags":[],"class_list":["post-31","post","type-post","status-publish","format-standard","hentry","category-code"],"jetpack_publicize_connections":[],"jetpack_featured_media_url":"","jetpack_sharing_enabled":true,"jetpack_shortlink":"https:\/\/wp.me\/p8SCfl-v","jetpack-related-posts":[{"id":30,"url":"https:\/\/pbw.id.au\/blog\/2015\/05\/tikadiff-graphical-diff-for-text-from-binary-files\/","url_meta":{"origin":31,"position":0},"title":"tikadiff: graphical diff for text from &#8220;binary&#8221; files","author":"pbw","date":"Sat 9th May '15","format":false,"excerpt":"Code The code is from the Downloads area of my Atlassian Bitbucket repository; see the README online. Version Control Systems (VCSs) VCSs like mercurial, git and bazaar (to mention only a few) are great for keeping track of changes to source files, but their utility doesn't stop there. \u00a0If you're\u2026","rel":"","context":"In &quot;Code&quot;","block_context":{"text":"Code","link":"https:\/\/pbw.id.au\/blog\/category\/code\/"},"img":{"alt_text":"","src":"","width":0,"height":0},"classes":[]},{"id":37,"url":"https:\/\/pbw.id.au\/blog\/2013\/05\/ant-edit-property-values\/","url_meta":{"origin":31,"position":1},"title":"Ant: edit property values","author":"pbw","date":"Thu 9th May '13","format":false,"excerpt":"One of the frustrations of using ant\u00a0was the difficulty of deriving one property value performing some sort of editing operation on an existing property value. The mapper task does a lot of grunt work for file names, but not for property values as such. A common requirement is to map\u2026","rel":"","context":"In &quot;Code&quot;","block_context":{"text":"Code","link":"https:\/\/pbw.id.au\/blog\/category\/code\/"},"img":{"alt_text":"","src":"","width":0,"height":0},"classes":[]},{"id":36,"url":"https:\/\/pbw.id.au\/blog\/2013\/05\/ant-process-elements-in-a-list\/","url_meta":{"origin":31,"position":2},"title":"Ant: process elements in a list","author":"pbw","date":"Sun 19th May '13","format":false,"excerpt":"I was looking for a way to process a list of items in an ant build file, similar to what you would do in Java with a construct like: for ( Element element : elements ) { \/\/ do stuff with element } The approach of XSLT, using recursive calls\u2026","rel":"","context":"In &quot;Code&quot;","block_context":{"text":"Code","link":"https:\/\/pbw.id.au\/blog\/category\/code\/"},"img":{"alt_text":"","src":"","width":0,"height":0},"classes":[]},{"id":38,"url":"https:\/\/pbw.id.au\/blog\/2013\/05\/using-environment-plist-with-mountain-lion\/","url_meta":{"origin":31,"position":3},"title":"Using environment.plist with Mountain Lion","author":"pbw","date":"Sat 4th May '13","format":false,"excerpt":"UPDATE This post is now obsolete. For the preferred method in both Mountain Lion and Mavericks, see\u00a0 Setting environment variables in OS X Mountain Lion and Mavericks. With Mountain Lion (OS X 10.8), the environment settings from ~\/.MacOSX\/environment.plist are not taken into account when the background system environment is set\u2026","rel":"","context":"In &quot;Observations&quot;","block_context":{"text":"Observations","link":"https:\/\/pbw.id.au\/blog\/category\/personal\/observations\/"},"img":{"alt_text":"","src":"","width":0,"height":0},"classes":[]},{"id":34,"url":"https:\/\/pbw.id.au\/blog\/2013\/11\/setting-environment-variables-in-os-x-yosemite-and-mavericks\/","url_meta":{"origin":31,"position":4},"title":"Setting environment variables in  MacOS Big Sur","author":"pbw","date":"Thu 7th Nov '13","format":false,"excerpt":"This method uses launchctl to manage environment variables for programs invoked directly from Finder. \u00a0See the launchctl man page, especially the section LEGACY SUBCOMMANDS. \u00a0It's not entirely accurate, but that's not unusual. \u00a0The critical subcommands are getenv, setenv, and unsetenv. The man page indicates that the export subcommand is available;\u2026","rel":"","context":"In &quot;Code&quot;","block_context":{"text":"Code","link":"https:\/\/pbw.id.au\/blog\/category\/code\/"},"img":{"alt_text":"","src":"","width":0,"height":0},"classes":[]},{"id":39,"url":"https:\/\/pbw.id.au\/blog\/2013\/05\/setting-environment-variables-in-os-x-lion\/","url_meta":{"origin":31,"position":5},"title":"Setting Environment Variables in OS X Lion","author":"pbw","date":"Fri 3rd May '13","format":false,"excerpt":"If you want to set environment variables in OS X in such a way as to be recognised in applications run from Finder, it is not enough to set the env var in .profile. \u00a0You must also ensure that the variables are set in the file ~\/.MacOSX\/environment.plist. Setting values in\u2026","rel":"","context":"In &quot;Code&quot;","block_context":{"text":"Code","link":"https:\/\/pbw.id.au\/blog\/category\/code\/"},"img":{"alt_text":"","src":"","width":0,"height":0},"classes":[]}],"_links":{"self":[{"href":"https:\/\/pbw.id.au\/blog\/wp-json\/wp\/v2\/posts\/31","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/pbw.id.au\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/pbw.id.au\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/pbw.id.au\/blog\/wp-json\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"https:\/\/pbw.id.au\/blog\/wp-json\/wp\/v2\/comments?post=31"}],"version-history":[{"count":27,"href":"https:\/\/pbw.id.au\/blog\/wp-json\/wp\/v2\/posts\/31\/revisions"}],"predecessor-version":[{"id":564,"href":"https:\/\/pbw.id.au\/blog\/wp-json\/wp\/v2\/posts\/31\/revisions\/564"}],"wp:attachment":[{"href":"https:\/\/pbw.id.au\/blog\/wp-json\/wp\/v2\/media?parent=31"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/pbw.id.au\/blog\/wp-json\/wp\/v2\/categories?post=31"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/pbw.id.au\/blog\/wp-json\/wp\/v2\/tags?post=31"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}