Skip to content

Instantly share code, notes, and snippets.

@andrewconner
Last active December 16, 2015 22:59
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save andrewconner/5510961 to your computer and use it in GitHub Desktop.
Save andrewconner/5510961 to your computer and use it in GitHub Desktop.
UserVoice SSO Token Generator in Scala
import org.apache.commons.codec.net.URLCodec
import org.apache.commons.codec.binary.Base64
import javax.crypto.spec.SecretKeySpec
import javax.crypto.spec.IvParameterSpec
import org.apache.commons.codec.digest.DigestUtils
import java.io.InputStream
import java.io.OutputStream
import javax.crypto.Cipher
import javax.crypto.CipherOutputStream
import java.io.ByteArrayOutputStream
import java.io.ByteArrayInputStream
object UserVoiceTokenGenerator {
private final val USERVOICE_SUBDOMAIN = "<insert UserVoice subdomain>"
private final val SSO_KEY = "<insert UserVoice SSO key>"
private final val INIT_VECTOR = "OpenSSL for Ruby".getBytes()
private val hash = DigestUtils.sha(SSO_KEY + USERVOICE_SUBDOMAIN).toSeq
private val secretKeySpec = new SecretKeySpec(hash.take(16).toArray, "AES")
private val ivSpec = new IvParameterSpec(INIT_VECTOR)
private val urlCodec = new URLCodec("ASCII")
private val base64 = new Base64()
private def encrypt(in: InputStream): ByteArrayOutputStream = {
val cipher = Cipher.getInstance("AES/CBC/PKCS5Padding")
cipher.init(Cipher.ENCRYPT_MODE, secretKeySpec, ivSpec)
val buf = new Array[Byte](1024)
val byteStream = new ByteArrayOutputStream()
val out = new CipherOutputStream(byteStream, cipher)
try {
Iterator.continually(in.read(buf)).takeWhile(_ >= 0) foreach { numRead =>
out.write(buf, 0, numRead)
}
} catch {
case ex: Throwable =>
// integrate your application logging
ex.printStackTrace()
} finally {
out.close()
}
byteStream
}
def create(json: String): String = {
val jsonBytes = json.getBytes()
val data = INIT_VECTOR.zip(jsonBytes).take(16).map({ case (i, d) => (i ^ d).byteValue }) ++ jsonBytes.drop(INIT_VECTOR.length)
val out = encrypt(new ByteArrayInputStream(data));
new String(urlCodec.encode(base64.encode(out.toByteArray)))
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment