Skip to content

Instantly share code, notes, and snippets.

@jaytaylor
Created November 10, 2011 17:16
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save jaytaylor/1355462 to your computer and use it in GitHub Desktop.
Save jaytaylor/1355462 to your computer and use it in GitHub Desktop.
Scala Port of Java Encryption Utility class originally found at http://bytebar.blogspot.com/2008/08/aes-encryption-in-java.html
import javax.crypto.{Cipher, SecretKeyFactory, SecretKey}
import javax.crypto.spec.{PBEKeySpec, SecretKeySpec}
import java.lang.{Long => JLong}
import java.security.MessageDigest
import java.security.spec.KeySpec
import java.util.Arrays
/**
* @author Jay Taylor <jay@klout.com>
* @date 2011-11-09
*
* @description I found the Java version at
* http://bytebar.blogspot.com/2008/08/aes-encryption-in-java.html. I'm pretty
* sure it was based off of
* http://java.sun.com/developer/technicalArticles/Security/AES/AES_v1.html.
*/
object CryptUtil {
/**
* Turns array of bytes into string
*
* @param buf
* Array of bytes to convert to hex string
* @return Generated hex string
*/
def asHexStr(buf: Array[Byte]): String = {
val strbuf: StringBuffer = new StringBuffer(buf.length * 2)
for (i <- 0 until buf.length) {
if ((buf(i).asInstanceOf[Int] & 0xff) < 0x10) {
strbuf.append("0")
}
strbuf.append(JLong.toString(buf(i).asInstanceOf[Int] & 0xff, 16))
}
strbuf.toString
}
def getSecretKeySpec(
passphrase: String,
algorithm: String,
kgenbit: Int
): SecretKeySpec = {
val salt: Array[Byte] = Array(
0xA9.asInstanceOf[Byte],
0x87.asInstanceOf[Byte],
0xC8.asInstanceOf[Byte],
0x32.asInstanceOf[Byte],
0x56.asInstanceOf[Byte],
0xA5.asInstanceOf[Byte],
0xE3.asInstanceOf[Byte],
0xB2.asInstanceOf[Byte]
)
val iterationCount = 1024
val keySpec: KeySpec = new PBEKeySpec(
passphrase.toCharArray,
salt,
iterationCount
)
val secretKey: SecretKey = SecretKeyFactory.getInstance(
"PBEWithMD5AndDES"
).generateSecret(keySpec)
val md: MessageDigest = MessageDigest.getInstance("MD5")
md.update(secretKey.getEncoded)
md.update(salt)
for (i <- 1 until iterationCount) {
md.update(md.digest())
}
val keyBytes: Array[Byte] = md.digest
val skeyspec: SecretKeySpec = new SecretKeySpec(keyBytes, algorithm)
skeyspec
}
/**
* Encrypt a byte array given the secret key spec
* @param message
* @param skeyspec
* @return
* @throws Exception
*/
def encrypt(
message: Array[Byte],
secret: String,
scheme: String = "AES",
bits: Int = 192
): Array[Byte] = {
val skeySpec: SecretKeySpec = getSecretKeySpec(secret, scheme, bits)
val cipher: Cipher = Cipher.getInstance(skeySpec.getAlgorithm)
cipher.init(Cipher.ENCRYPT_MODE, skeySpec)
val encrypted: Array[Byte] = cipher.doFinal(message)
encrypted
}
/**
* Decrypt a byte array given the same secret key spec used to encrypt the
* message.
*
* @param message
* @param skeyspec
* @return
* @throws Exception
*/
def decrypt(
message: Array[Byte],
secret: String,
scheme: String = "AES",
bits: Int = 192
): Array[Byte] = {
val skeySpec: SecretKeySpec = getSecretKeySpec(secret, scheme, bits)
val cipher: Cipher = Cipher.getInstance(skeySpec.getAlgorithm)
cipher.init(Cipher.DECRYPT_MODE, skeySpec)
val decrypted: Array[Byte] = cipher.doFinal(message)
decrypted
}
/**
* Main method, shows how to use the CryptUtil class
* @param args
* @throws Exception
*/
def main(args: Array[String]): Unit = {
var message: String = "This is just an example"
System.out.println("(HEX) Original : " + asHexStr(message.getBytes))
var encrypted: Array[Byte] = encrypt(message.getBytes, "mypassword", "AES", 128)
System.out.println("(HEX) Encrypted : " + asHexStr(encrypted))
var decrypted: Array[Byte] = decrypt(encrypted, "mypassword", "AES", 128)
System.out.println("(HEX) Decrypted : " + asHexStr(decrypted))
if (Arrays.equals(decrypted, message.getBytes)) {
System.out.println("THE ONE AND THE SAME")
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment