Hashing

Note:

This has been beaten to death everywhere, but please do not use these for Password Hashing. We provide Password Hashers to use for this purpose under the password hashers section.

Usage

For TSec, we support MD5, SHA1, SHA256 and SHA512 hashing of byte arrays, as well as hashing of byte streams (fs2 does this as well, but we simply provide the helper via the type. As a matter of fact, our implementation is identical to the fs2 implementation for the JCA, but different for libsodium)

scala>   /** Imports */
     |   import cats.Id
import cats.Id

scala>   import cats.effect.{IO, Sync}
import cats.effect.{IO, Sync}

scala>   import fs2._
import fs2._

scala>   import tsec.common._
import tsec.common._

scala>   import tsec.hashing.jca._ //For this example, we will use our byteutil helpers
import tsec.hashing.jca._

scala>   /**For direct byte pickling, use: */
     |   "hiHello".utf8Bytes.hash[SHA1]
res2: tsec.hashing.CryptoHash[tsec.hashing.jca.SHA1] = Array(-53, -3, -25, 113, -46, -127, 18, 88, -70, -9, -97, 61, -119, -93, 103, -81, -124, -64, 86, 16)

scala>   "hiHello".utf8Bytes.hash[SHA256]
res3: tsec.hashing.CryptoHash[tsec.hashing.jca.SHA256] = Array(3, 72, 84, -16, 62, -55, -11, -100, 32, -51, 6, 39, 95, 33, -97, -91, 52, -114, -115, -94, 56, 98, 77, -104, -104, -102, 94, -47, 116, -44, 104, 99)

scala>   "hiHello".utf8Bytes.hash[SHA512]
res4: tsec.hashing.CryptoHash[tsec.hashing.jca.SHA512] = Array(36, 4, 93, 17, -69, 24, -80, -52, -63, -59, 5, -48, -7, -108, -99, -118, -44, 31, -54, -63, 73, -49, -99, 29, -66, -70, 102, -44, 62, -50, 93, 58, 18, 7, 50, 125, -13, -40, 95, 6, -71, -14, -33, 102, -41, 62, 47, -4, -29, -86, 77, -53, 27, 60, -97, -97, 54, 19, -97, -16, -36, -109, -84, -68)

scala>   "hiHello".utf8Bytes.hash[MD5]
res5: tsec.hashing.CryptoHash[tsec.hashing.jca.MD5] = Array(-64, 73, -73, -119, 66, -112, 114, -95, 76, -113, 113, 5, 93, 19, 39, -122)

scala>   /** Alternatively, use the algorithms directly
     |     * Note: For the JCA, while you _can_ interpret
     |     * into `IO` if you ever need to work in it, hashing
     |     * is essentially pure. Thus, interpreting into `Id` is not unsafe
     |     * in this case
     |     */
     |   SHA1.hash[Id]("hiHello".utf8Bytes)
res7: cats.Id[tsec.hashing.CryptoHash[tsec.hashing.jca.SHA1]] = Array(-53, -3, -25, 113, -46, -127, 18, 88, -70, -9, -97, 61, -119, -93, 103, -81, -124, -64, 86, 16)

scala>   SHA256.hash[Id]("hiHello".utf8Bytes)
res8: cats.Id[tsec.hashing.CryptoHash[tsec.hashing.jca.SHA256]] = Array(3, 72, 84, -16, 62, -55, -11, -100, 32, -51, 6, 39, 95, 33, -97, -91, 52, -114, -115, -94, 56, 98, 77, -104, -104, -102, 94, -47, 116, -44, 104, 99)

scala>   /** Some Monad with a sync bound: **/
     |   SHA512.hash[IO]("hiHello".utf8Bytes)
res10: cats.effect.IO[tsec.hashing.CryptoHash[tsec.hashing.jca.SHA512]] = IO([B@1a18b66)

scala>   def hashPipeExample[F[_]: Sync](str: Stream[F, Byte]): Stream[F, Byte] = {
     |     str.through(SHA512.hashPipe[F])
     |   }
hashPipeExample: [F[_]](str: fs2.Stream[F,Byte])(implicit evidence$1: cats.effect.Sync[F])fs2.Stream[F,Byte]