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 SecureRandomId
s 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.