SHA1 Algorithm (+ JavaScript Implementation)


SHA1 (SHA here stands for Secure Hashing Algorithm) is a cryptographic algorithm that belongs to a class of algorithms called cryptographic hash functions. Hash functions take the “message” as input, and churn out a fixed sized hash (called a “message digest”) as output. These functions differ from cryptographic encryption functions both in their intended use cases and their properties.

Encryption functions are used to secure data before transmission. The encrypted message, called ciphertext, is decrypted at the receivers end. Hash functions, however, are designed to be one way functions. This means that while it is quick and easy to compute the hash of a message, it is computationally infeasible to “invert” the hash (i.e. get the message from it’s hash). Thus, they aren’t used for data encryption. Instead, they are used for things like encrypting passwords before storing in a database (so that only the hashes, and not the plaintext passwords, need to be compared for authentication), and generating the hashes of files so that a person can verify their integrity. This technique is also used in SSL/TLS certificates.

Computation Details

SHA1 hashes the input text (“message”) into a 20 byte hash value (“message digest”).

A few processing functions, processing constants and variables are used by the SHA-1 algorithm. These are:

SHA-1 requires 80 processing functions:

  1. f(t;B,C,D) = (B AND C) OR ((NOT B) AND D) ( 0 <= t <= 19)
  2. f(t;B,C,D) = B XOR C XOR D (20 <= t <= 39)
  3. f(t;B,C,D) = (B AND C) OR (B AND D) OR (C AND D) (40 <= t <= 59)
  4. f(t;B,C,D) = B XOR C XOR D (60 <= t <= 79)

SHA-1 requires 80 processing constants:

  1. K(t) = 0x5A827999 ( 0 <= t <= 19)
  2. K(t) = 0x6ED9EBA1 (20 <= t <= 39)
  3. K(t) = 0x8F1BBCDC (40 <= t <= 59)
  4. K(t) = 0xCA62C1D6 (60 <= t <= 79)

The following buffer variables are used by SHA-1:

H0 = 0x67452301
H1 = 0xEFCDAB89
H2 = 0x98BADCFE
H3 = 0x10325476
H4 = 0xC3D2E1F0

Preprocessing The Message:

First, the message is preprocessed. The bit “1” is appended to the message, followed by appending zero or more “0” bits so that the total length of the message is congruent to 448 modulo 512.

The length of the input is then appended as the next 64 bits (in 2 32-bit words, the lower order bits are appended first).

The SHA-1 Algorithm:

  1. Divide the message into N blocks of 512 bits each.
  2. For each block K in the list of N blocks, do:
    1. Divide K into 16 words (W(0) to W(15) say)
    2. For t = 16 to 79 do:
      1. W(t) = (W(t-3) XOR W(t-8) XOR W(t-14) XOR W(t-16)) <<< 1
    3. Assign A = H0, B = H1, C = H2, D = H3, E = H4
    4. For t = 0 to 79 do:
      1. Tmp = A <<< 5 + f(t; B, C, D) + E + W(t) + K(t)
      2. E = D; D = C; C = B <<< 30, B = A, A = Tmp
    5. H0 = H0 + A; H1 = H1 + B; H2 = H2 + C; H3 = H3 + D; H4 = H4 + E

Output: The contents of H0, H1, H2, H3 and H4 are returned in sequence as the final hash.

Implement using js-sha1 library

A simple tool that hashes text using the SHA-1 algorithm is a part of the Tool project of the OpenGenus. This section describes how it was built.

The tool was built on top of an existing implementation of SHA1 in JavaScript. The reasons behind this include not reinventing the wheel and the fact that an existing and well established implementation is more likely to be free of bugs and security flaws (which is an important parameter to consider in the context of cryptographic functions).

The js-sha library offers the required implementation of the function by exposing the “sha()” function, which accepts a string as an argument and returns the SHA1 hash.

The library was integrated into the client side tool by means of a CDN.

The tool was built using the template of the “Capitalize” client side tool in order to maintain consistency across tools. The main modifications included removing the convert button and instead allowing real time hashing of the input as it is typed by using keyboard event listeners.

Following is the implementation:

<script src="https://cdnjs.cloudflare.com/ajax/libs/js-sha1/0.6.0/sha1.min.js">
  </script>
  <script type="text/javascript">
  function find_sha1() {
    var text = sha1($('#inputtextarea').val()); 
    $('#outputtextarea').val(text);
  }
  </script>

See pull request at Tools project.