- Install JCE Unlimited Strength Policy
git clone https://github.com/bdimmick/cruciform.gitcd cruciform; sbt test package
Cruciform provides functionality through traits that are mixed into the classes and objects that need to perform cryptographic operations.
Trait: com.hexagrammatic.cruciform.KeyGenerators
Symmetric Key Generation
AES [strength(bits)] [withProvider(provider)] keyBlowfish [strength(bits)] [withProvider(provider)] keyDES [strength(bits)] [withProvider(provider)] key
Asymmetric Keypair Generation
DSA [strength(bits)] [withProvider(provider)] keypairRSA [strength(bits)] [withProvider(provider)] keypair
import com.hexagrammatic.cruciform.KeyGenerators
object Example extends KeyGenerators {
val key = AES key
val keypair = RSA strength(1024 bit) keypair
}
Trait: com.hexagrammatic.cruciform.Ciphers
encrypt data <data> using <key> [withAlgorithm(algorithm)] [withProvider(provider)] to <stream>decrypt data <data> using <key> [withAlgorithm(algorithm)] [withProvider(provider)] [withInitVector(iv)] to <stream>sign data <data> using <key> [withAlgorithm(algorithm)] [withProvider(provider)] to <stream>verify signature <data> using <key> [withAlgorithm(algorithm)] [withProvider(provider)] from <data>
Notes:
- In the
encrypt,decrypt, andsignoperations,data <data>and thekey <key>may be switched if desired. Same forsignature <data>andusing <key>inverify. - Instead of
to <stream>,asBytesorasStringmay be used to return raw bytes or a string in the above operations. - The
<data>value may be one of the following:InputStreamSerializableStringArray[Bytes]Array[Char]FileReadable
- The
<stream>value may be one of the following:OutputStreamFile
- Encrypt behaves slightly differently based on the key type provided.
- When a
SecretKey(symmetric key) is provided toencrypt, the return type is a(OutputStream, Option[Array[Byte]])tuple consisting of the stream to which the ciphertext is written and an optional init vector, if one was created for the operation. Similarly,asBytesandasString, which returns a(Array[Byte], Option[Array[Byte]])or a(String, Option[Array[Byte]])respectively. - When a
PublicKey,KeyPair, orCertificateis provided toencrypt, the return type is aOutputStream, withasBytesreturning anArray[Byte]andasStringreturning aString.
- When a
- If
withAlgorithmis omitted, the language will pick the most appropriate one for the key type:- AES uses
AES/CBC/PKCS5Padding - DES uses
DES/CBC/PKCS5Padding - RSA uses
RSA/ECB/PKCS1Padding - Other key types must provide the algorithm
- AES uses
import com.hexagrammatic.cruciform.Ciphers
object example extends Ciphers with KeyGenerators {
val plaintext = "Hello world"
// Symmetric encryption and decryption
val key = AES key
val (encrypted, iv) = encrypt data plaintext using key asBytes
val decrypted = decrypt data encrypted using key withInitVector iv asBytes
// Asymmetric encryption and decryption
val keypair = RSA keypair
val encrypted = encrypt data plaintext using keypair asBytes
val decrypted = decrypt data encrypted using keypair iv asBytes
// Asymmetric sign and verify
val sig = sign data plaintext using keypair asBytes
val verified = verify signature sig using keypair from plaintext
}Trait: com.hexagrammatic.cruciform.Digests
digest data <data> [withAlgorithm(algorithm)] [withProvider(provider)] to <stream>hmac data <data> using <key> [withAlgorithm(algorithm)] [withProvider(provider)] to <stream>
Notes:
- In the
hmacoperation,data <data>and thekey <key>may be switched if desired. - If
withAlgorithmis omitted, SHA-256 will be used for both digest and hmac. - The
<data>value may be one of the following:InputStreamSerializableStringArray[Bytes]Array[Char]FileReadable
- The
<stream>value may be one of the following:OutputStreamFile
- Instead of
to <stream>,asBytesorasStringmay be used to returnArray[Byte]orStringrespectively in the above operations.
import com.hexagrammatic.cruciform.Digests
object Example extends Digests with KeyGenerators {
val str = "Hello World"
val digestSHA = digest data str asBytes
val key = AES key
val hmacSHA = hmac data str using key asBytes
}
val target = new File("target")
val digestor = MessageDigest.getInstance("SHA-256")
val buffer = new Array[Byte](128 * 1024)
val in = new DigestInputStream(new FileInputStream(target), digestor)
while (-1 != in.read(buffer)) {}
val digest = digestor.digestval target = new File("target")
val sha = digest data target withAlgorithm("SHA-256") asBytesSymmetric Key Generation:
val generator = KeyGenerator.getInstance("AES")
generator.init(128)
val key = generator.generateKeyval key = AES strength(128 bit) keyval in = new File("plaintext")
val out = new File("ciphertext")
val cipher = Cipher.getInstance("AES")
cipher.init(key, Cipher.ENCRYPT)
org.apache.commons.io.IOUtils.copy(in, new CipherOutputStream(out, cipher))
in.close()
out.close()val in = new File("plaintext")
val out = new File("ciphertext")
encrypt data in using key to out
in close
out close