Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
DES and AES encryption in Scala
name := "DES and AES encryption in Scala"
version := "1.0"
scalaVersion := "2.9.1"
libraryDependencies += "commons-codec" % "commons-codec" % "1.6"
package protocol {
import annotation.implicitNotFound
import java.io.{DataOutputStream, ByteArrayOutputStream}
@implicitNotFound(msg = "Could not find a Writes for ${T}")
trait Writes[T] {
def writes(value: T): Array[Byte]
}
class DataOutputStreamWrites[T](writeValue: (DataOutputStream, T) => Unit) extends Writes[T] {
def writes(value: T): Array[Byte] = {
val bos = new ByteArrayOutputStream
val dos = new DataOutputStream(bos)
writeValue(dos, value)
dos.flush()
val byteArray = bos.toByteArray
bos.close()
byteArray
}
}
object defaults {
implicit object WritesString extends Writes[String] {
def writes(value: String) = value.getBytes("UTF-8")
}
implicit object WritesLong extends DataOutputStreamWrites[Long](_.writeLong(_))
implicit object WritesInt extends DataOutputStreamWrites[Int](_.writeInt(_))
implicit object WritesShort extends DataOutputStreamWrites[Short](_.writeShort(_))
}
}
package crypto {
import protocol.Writes
import javax.crypto.spec.SecretKeySpec
import javax.crypto.Cipher
trait Encryption {
def encrypt(dataBytes: Array[Byte], secret: String): Array[Byte]
def decrypt(codeBytes: Array[Byte], secret: String): Array[Byte]
def encrypt[T:Writes](data: T, secret: String): Array[Byte] = encrypt(implicitly[Writes[T]].writes(data), secret)
}
class JavaCryptoEncryption(algorithmName: String) extends Encryption {
def encrypt(bytes: Array[Byte], secret: String): Array[Byte] = {
val secretKey = new SecretKeySpec(secret.getBytes("UTF-8"), algorithmName)
val encipher = Cipher.getInstance(algorithmName + "/ECB/PKCS5Padding")
encipher.init(Cipher.ENCRYPT_MODE, secretKey)
encipher.doFinal(bytes)
}
def decrypt(bytes: Array[Byte], secret: String): Array[Byte] = {
val secretKey = new SecretKeySpec(secret.getBytes("UTF-8"), algorithmName)
val encipher = Cipher.getInstance(algorithmName + "/ECB/PKCS5Padding")
encipher.init(Cipher.DECRYPT_MODE, secretKey)
encipher.doFinal(bytes)
}
}
object DES extends JavaCryptoEncryption("DES")
object AES extends JavaCryptoEncryption("AES")
}
object Main extends App {
import org.apache.commons.codec.binary.Base64
import crypto._
import protocol.defaults._
def encodeBase64(bytes: Array[Byte]) = Base64.encodeBase64String(bytes)
println(encodeBase64(DES.encrypt("hoge", "01234567")))
//=> vyudTtnBJfs=
println(encodeBase64(AES.encrypt("hoge", "0123456789012345")))
//=> QWSouZUMVYMfS86xFyBgtQ==
println(encodeBase64(DES.encrypt(123L, "01234567")))
//=> Cqw2ipxTtvIIu122s3wG1w==
println(encodeBase64(DES.encrypt(123, "01234567")))
//=> BV+LSCSYmUU=
}
@khalid-saifullah

This comment has been minimized.

Copy link

khalid-saifullah commented Mar 27, 2013

Dear KUOKA, really an excellent snippet. I have successfully used both encryption and decryption using your code. Now, I want to use similar approach to encrypt data in PHP so that I can open my code through an API. Problem is, PHP AES encryption is talking about a key and a initial vector (IV). But your code only use one key. Any suggestion?

Thanks in Advance
Khalid

@metaweta

This comment has been minimized.

Copy link

metaweta commented Oct 1, 2013

You're encrypting using ECB mode, which is a big no-no. See http://en.wikipedia.org/wiki/Block_cipher_modes_of_operation#Electronic_codebook_.28ECB.29

@Richard-W

This comment has been minimized.

Copy link

Richard-W commented Dec 24, 2014

@khalid-saifullah: This code snippet uses ECB mode, which is considered insecure for most applications. PHP uses CBC which randomizes the output of the cipher but needs an initialization vector.

I have implemented a similar wrapper (https://github.com/Richard-W/scalacrypt), which uses CBC mode and is therefore compatible with PHP. The first 16 bytes of the output of the AES ciphers in scalacrypt are the IV. You can just slice them of and supply them to the PHP function.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.