TSec-Common
In cryptography, loads of operations happen on bytes and strings, thus, tsec naturally includes some helpers
for this.
importing tsec.common._ brings in:
String syntax
import org.apache.commons.codec.binary.{Base64 => AB64}
def utf8Bytes: Array[Byte] = s.getBytes(StandardCharsets.UTF_8)
def asciiBytes: Array[Byte] = s.getBytes(StandardCharsets.US_ASCII)
def base64Bytes: Array[Byte] = Base64.getDecoder.decode(s)
def base64UrlBytes: Array[Byte] = AB64.decodeBase64(s)
def hexBytes[F[_]](implicit F: Sync[F]): F[Array[Byte]] = F.delay(Hex.decodeHex(s))
def hexBytesUnsafe: Array[Byte] = Hex.decodeHex(s)
def toStringRepr[A](implicit stringEV: StringEV[A]): A = stringEV.fromString(s)
scala> import tsec.common._
import tsec.common._
scala> "hi".utf8Bytes //Get the utf-8 bytes of a string
res0: Array[Byte] = Array(104, 105)
scala> "FF0952".hexBytesUnsafe //Note: This can throw!
res1: Array[Byte] = Array(-1, 9, 82)
Note: Hex encoding provided by apache commons io
Bytes syntax
def toUtf8String = new String(array, StandardCharsets.UTF_8)
def toAsciiString = new String(array, StandardCharsets.US_ASCII)
def toB64UrlString: String = AB64.encodeBase64URLSafeString(array)
def toB64String: String = Base64.getEncoder.encodeToString(array)
def toHexString: String = Hex.encodeHexString(array)
def toRepr[A](implicit byteEV: ByteEV[A]): A = byteEV.fromArray(array)
scala> "hi".utf8Bytes.toHexString
res2: String = 6869
scala> "hello".asciiBytes.toB64UrlString
res3: String = aGVsbG8
Secure Random Ids
tsec provides a SecureRandomId which is simply a string random bytes generated by java’s SecureRandom, then hex encoded. The
SecureRandom implementation is managed for proper security and reseeding (see the ManagedRandom section).
The type itself is a newtype using cats.evidence.Is
To generate SecureRandomIds of more than 32 bits, you can simply set the length in a custom SecureRandomIdGenerator,
with the signature
case class SecureRandomIdGenerator(sizeInBytes: Int = 32) extends ManagedRandom {
def generate: SecureRandomId
}
ManagedRandom
Proper SecureRandom management requires occasional reseeding. Extending ManagedRandom in your class will
effectively provide a nextBytes method which is identical in function to SecureRandom’s nextBytes, but
will reseed periodically (though sensibly, not too often), managing
concurrency with a LongAdder. Though note: nextBytes is a side effecting function that mutates the array,
this is not managed in a functional style to keep an API identical to java’s SecureRandom, but it would not be
hard to implement the effect management, if you so desire it.
SecureRandomId, and many other secure random constructs in tsec are implemented using ManagedRandom to
manage proper reseeding.