- Install JCE Unlimited Strength Policy
git clone https://github.com/bdimmick/cruciform.git
cd 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)] key
Blowfish [strength(bits)] [withProvider(provider)] key
DES [strength(bits)] [withProvider(provider)] key
Asymmetric Keypair Generation
DSA [strength(bits)] [withProvider(provider)] keypair
RSA [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
, andsign
operations,data <data>
and thekey <key>
may be switched if desired. Same forsignature <data>
andusing <key>
inverify
. - Instead of
to <stream>
,asBytes
orasString
may be used to return raw bytes or a string in the above operations. - The
<data>
value may be one of the following:InputStream
Serializable
String
Array[Bytes]
Array[Char]
File
Readable
- The
<stream>
value may be one of the following:OutputStream
File
- 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,asBytes
andasString
, which returns a(Array[Byte], Option[Array[Byte]])
or a(String, Option[Array[Byte]])
respectively. - When a
PublicKey
,KeyPair
, orCertificate
is provided toencrypt
, the return type is aOutputStream
, withasBytes
returning anArray[Byte]
andasString
returning aString
.
- When a
- If
withAlgorithm
is 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
hmac
operation,data <data>
and thekey <key>
may be switched if desired. - If
withAlgorithm
is omitted, SHA-256 will be used for both digest and hmac. - The
<data>
value may be one of the following:InputStream
Serializable
String
Array[Bytes]
Array[Char]
File
Readable
- The
<stream>
value may be one of the following:OutputStream
File
- Instead of
to <stream>
,asBytes
orasString
may be used to returnArray[Byte]
orString
respectively 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.digest
val target = new File("target")
val sha = digest data target withAlgorithm("SHA-256") asBytes
Symmetric Key Generation:
val generator = KeyGenerator.getInstance("AES")
generator.init(128)
val key = generator.generateKey
val key = AES strength(128 bit) key
val 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