javax.crypto.Cipher Scala Examples

The following examples show how to use javax.crypto.Cipher. You can vote up the ones you like or vote down the ones you don't like, and go to the original project or source file by following the links above each example.
Example 1
Source File: Enigma.scala    From matcher   with MIT License 6 votes vote down vote up
package com.wavesplatform.dex.crypto

import java.nio.charset.StandardCharsets
import java.security.NoSuchAlgorithmException
import java.security.spec.InvalidKeySpecException

import javax.crypto.spec.{PBEKeySpec, SecretKeySpec}
import javax.crypto.{Cipher, SecretKeyFactory}

import scala.util.control.NonFatal

object Enigma {

  private[this] val KeySalt           = "0495c728-1614-41f6-8ac3-966c22b4a62d".getBytes(StandardCharsets.UTF_8)
  private[this] val AES               = "AES"
  private[this] val Algorithm         = AES + "/ECB/PKCS5Padding"
  private[this] val HashingIterations = 999999
  private[this] val KeySizeBits       = 128

  def hashPassword(password: Array[Char],
                   salt: Array[Byte],
                   iterations: Int = HashingIterations,
                   keyLength: Int = KeySizeBits,
                   hashingAlgorithm: String = "PBKDF2WithHmacSHA512"): Array[Byte] =
    try {
      val keyFactory = SecretKeyFactory.getInstance(hashingAlgorithm)
      val keySpec    = new PBEKeySpec(password, salt, iterations, keyLength)
      val key        = keyFactory.generateSecret(keySpec)
      key.getEncoded
    } catch {
      case e @ (_: NoSuchAlgorithmException | _: InvalidKeySpecException) => throw new RuntimeException("Password hashing error", e)
    }

  def prepareDefaultKey(password: String): SecretKeySpec = new SecretKeySpec(hashPassword(password.toCharArray, KeySalt), AES)

  def encrypt(key: SecretKeySpec, bytes: Array[Byte]): Array[Byte] =
    try {
      val cipher = Cipher.getInstance(Algorithm)
      cipher.init(Cipher.ENCRYPT_MODE, key)
      cipher.doFinal(bytes)
    } catch {
      case NonFatal(e) => throw new RuntimeException("Encrypt error", e)
    }

  def decrypt(key: SecretKeySpec, encryptedBytes: Array[Byte]): Array[Byte] =
    try {
      val cipher: Cipher = Cipher.getInstance(Algorithm)
      cipher.init(Cipher.DECRYPT_MODE, key)
      cipher.doFinal(encryptedBytes)
    } catch {
      case NonFatal(e) => throw new RuntimeException("Decrypt error", e)
    }
} 
Example 2
Source File: RSAUtils.scala    From Linkis   with Apache License 2.0 5 votes vote down vote up
package com.webank.wedatasphere.linkis.common.utils

import java.security.{KeyPair, KeyPairGenerator, PrivateKey, PublicKey}
import javax.crypto.Cipher

import org.apache.commons.codec.binary.Hex
import org.apache.commons.net.util.Base64


object RSAUtils {
  private implicit val keyPair = genKeyPair(1024)
  def genKeyPair(keyLength: Int): KeyPair = {
    val keyPair = KeyPairGenerator.getInstance("RSA")
    keyPair.initialize(keyLength)
    keyPair.generateKeyPair()
  }
  def getDefaultPublicKey(): String = {
    new String(Base64.encodeBase64(keyPair.getPublic.getEncoded))
  }
  def encrypt(data: Array[Byte], publicKey: PublicKey): Array[Byte] = {
    val cipher = Cipher.getInstance("RSA")
    cipher.init(Cipher.ENCRYPT_MODE, publicKey)
    cipher.doFinal(data)
  }
  def encrypt(data: Array[Byte]): Array[Byte] = encrypt(data, keyPair.getPublic)
  def decrypt(data: String, privateKey: PrivateKey): Array[Byte] = {
    val dataBytes = Hex.decodeHex(data.toCharArray)
    decrypt(dataBytes, privateKey)
  }
  def decrypt(data: String): Array[Byte] = decrypt(data, keyPair.getPrivate)
  def decrypt(data: Array[Byte], privateKey: PrivateKey): Array[Byte] = {
    val cipher = Cipher.getInstance("RSA")
    cipher.init(Cipher.DECRYPT_MODE, privateKey)
    cipher.doFinal(data)
  }
  def decrypt(data: Array[Byte]): Array[Byte] = decrypt(data, keyPair.getPrivate)
} 
Example 3
Source File: CipherBench.scala    From tsec   with MIT License 5 votes vote down vote up
package tsec

import java.util.concurrent.TimeUnit
import javax.crypto
import javax.crypto.Cipher

import cats.effect.IO
import org.openjdk.jmh.annotations._
import tsec.cipher.symmetric._
import tsec.cipher.symmetric.bouncy._
import tsec.cipher.symmetric.jca.{SecretKey, AES256GCM => JAESGCM}
import tsec.cipher.symmetric.libsodium.{AES256GCM, CryptoSecretBox, SodiumKey, XChacha20AEAD}
import tsec.common._
import tsec.libsodium._

@State(Scope.Thread)
@BenchmarkMode(Array(Mode.Throughput))
@OutputTimeUnit(TimeUnit.MILLISECONDS)
class CipherBench {
  import CipherBench._

  
  @Benchmark
  def testTSecJCA(): CipherText[JAESGCM] =
    JAESGCM
      .encrypt[IO](longPlaintext, AESGCMKey, Iv[JAESGCM](gcmIv))
      .unsafeRunSync()

  @Benchmark
  def testLibSodiumAES(): CipherText[AES256GCM] =
    AES256GCM
      .encrypt[IO](longPlaintext, SodiumKey[AES256GCM](AESKeyRaw), Iv[AES256GCM](gcmIv))
      .unsafeRunSync()

  @Benchmark
  def testLibSodiumXChacha20(): CipherText[XChacha20AEAD] =
    XChacha20AEAD
      .encrypt[IO](longPlaintext, SodiumKey[XChacha20AEAD](XChaChaKey), Iv[XChacha20AEAD](XChaChaIv))
      .unsafeRunSync()

  @Benchmark
  def testBouncyXChacha20(): CipherText[XChaCha20Poly1305] =
    XChaCha20Poly1305
      .encrypt[IO](longPlaintext, BouncySecretKey[XChaCha20Poly1305](XChaChaKey), Iv[XChaCha20Poly1305](XChaChaIv))
      .unsafeRunSync()

  @Benchmark
  def testLibSodiumXSalsa20(): CipherText[CryptoSecretBox] =
    CryptoSecretBox
      .encrypt[IO](longPlaintext, SodiumKey[CryptoSecretBox](XChaChaKey), Iv[CryptoSecretBox](XChaChaIv))
      .unsafeRunSync()

  @Benchmark
  def testBouncyXSalsa20(): CipherText[XSalsa20Poly1305] =
    XSalsa20Poly1305
      .encrypt[IO](longPlaintext, BouncySecretKey[XSalsa20Poly1305](XChaChaKey), Iv[XSalsa20Poly1305](XChaChaIv))
      .unsafeRunSync()
}

object CipherBench {
  lazy val longPlaintext: PlainText = PlainText(Array.fill[Char](5000)(99).mkString.utf8Bytes)

  val XChaChaIv  = "07000000404142434445464748494a4b0000000000000000".hexBytesUnsafe
  val XChaChaKey = "808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9f".hexBytesUnsafe
  val fixedPTRaw = "Ladies and Gentlemen of the class of '99: If I could offer you only one " +
    "tip for the future, sunscreen would be it."
  val fixedPT = PlainText(fixedPTRaw.utf8Bytes)

  val AESKeyRaw = "15d2d85402d913c9342967232c09d29ce5345e54ecc964963256a5d7f5328e4d".hexBytesUnsafe
  val AESGCMKey = JAESGCM.unsafeBuildKey(AESKeyRaw)
  val gcmIv     = "a84da0b22dc35ca5e5507326".hexBytesUnsafe

} 
Example 4
Source File: Crypto.scala    From dr-cla   with BSD 3-Clause "New" or "Revised" License 5 votes vote down vote up
package utils

import java.util.Base64

import javax.crypto.{Cipher, KeyGenerator}
import javax.inject.Inject
import play.api.Configuration

class Crypto @Inject() (configuration: Configuration) {

  private val secretKey = {
    val cryptoSecret = configuration.get[String]("play.http.secret.key")
    val keyGenerator = KeyGenerator.getInstance("AES")
    keyGenerator.init(128)
    keyGenerator.generateKey()
  }

  def encryptAES(plainText: String): String = {
    val plainTextBytes = plainText.getBytes
    val cipher = Cipher.getInstance("AES")
    cipher.init(Cipher.ENCRYPT_MODE, secretKey)
    val encryptedButes = cipher.doFinal(plainTextBytes)
    Base64.getEncoder.encodeToString(encryptedButes)
  }

  def decryptAES(encryptedText: String): String = {
    val encryptedTextBytes = Base64.getDecoder.decode(encryptedText)
    val cipher = Cipher.getInstance("AES")
    cipher.init(Cipher.DECRYPT_MODE, secretKey)
    val decryptedBytes = cipher.doFinal(encryptedTextBytes)
    new String(decryptedBytes)
  }

} 
Example 5
Source File: EncryptorActor.scala    From changestream   with MIT License 5 votes vote down vote up
package changestream.actors

import java.nio.charset.Charset
import java.util.Base64
import javax.crypto.Cipher
import javax.crypto.spec.SecretKeySpec

import akka.actor.Actor
import com.typesafe.config.{Config, ConfigFactory}
import kamon.Kamon
import org.slf4j.LoggerFactory
import spray.json._

object EncryptorActor {
  case class Plaintext(message: JsObject)
  case class Ciphertext(message: JsObject)
}

class EncryptorActor (
                        config: Config = ConfigFactory.load().getConfig("changestream.encryptor")
                      ) extends Actor {
  import EncryptorActor._

  protected val log = LoggerFactory.getLogger(getClass)
  protected val timingMetric = Kamon.timer("changestream.crypto_time")


  private val charset = Charset.forName("UTF-8")
  private val decoder = Base64.getDecoder
  private val encoder = Base64.getEncoder

  private val cipher = config.getString("cipher")
  private val decodedKey = decoder.decode(config.getString("key"))
  private val originalKey = new SecretKeySpec(decodedKey, 0, decodedKey.length, cipher)
  private val encryptEngine = Cipher.getInstance(cipher)
  private val decryptEngine = Cipher.getInstance(cipher)

  private val encryptFields = config.getString("encrypt-fields").toLowerCase().split(',').map(_.trim)

  override def preStart() = {
    encryptEngine.init(Cipher.ENCRYPT_MODE, originalKey)
    decryptEngine.init(Cipher.DECRYPT_MODE, originalKey)
  }

  def receive = {
    case Plaintext(message) =>
      val timer = timingMetric.refine("mode" -> "encrypt").start()
      val result = encryptFields(message)
      timer.stop()

      sender() ! result

    case Ciphertext(message) =>
      val timer = timingMetric.refine("mode" -> "decrypt").start()
      val result = decryptFields(message)
      timer.stop()

      sender() ! result
  }

  private def encryptFields(message: JsObject, jsonPath: String = ""): JsObject = {
    JsObject(
      message.fields.map({
        case (k:String, plaintextValue:JsValue) if encryptFields.contains(getNextJsonPath(jsonPath, k)) =>
          val plaintextBytes = plaintextValue.compactPrint.getBytes(charset)
          val cipherText = encryptEngine.doFinal(plaintextBytes)
          val v = encoder.encodeToString(cipherText)
          k -> JsString(v)
        case (k:String, jsObj: JsObject) =>
          k -> encryptFields(jsObj, getNextJsonPath(jsonPath, k))
        case (k:String, v: JsValue) =>
          k -> v
      })
    )
  }

  private def decryptFields(message: JsObject, jsonPath: String = ""): JsObject = {
    JsObject(
      message.fields.map({
        case (k:String, JsString(ciphertextValue)) if encryptFields.contains(getNextJsonPath(jsonPath, k)) =>
          val ciphertextBytes = decoder.decode(ciphertextValue)
          val plaintextBytes = decryptEngine.doFinal(ciphertextBytes)
          val v = new String(plaintextBytes, charset).parseJson
          k -> v
        case (k:String, jsObj: JsObject) =>
          k -> decryptFields(jsObj, getNextJsonPath(jsonPath, k))
        case (k:String, v: JsValue) =>
          k -> v
      })
    )
  }

  private def getNextJsonPath(jsonPath: String, nextPath: String): String = {
    Seq(jsonPath, nextPath).filter(_.nonEmpty).mkString(".")
  }
} 
Example 6
Source File: Crypto.scala    From akka-http-session   with Apache License 2.0 5 votes vote down vote up
package com.softwaremill.session

import java.security.MessageDigest
import java.util

import com.softwaremill.session.SessionUtil._
import javax.crypto.spec.SecretKeySpec
import javax.crypto.{Cipher, Mac}

object Crypto {
  def sign_HmacSHA1_hex(message: String, secret: String): String = {
    val key = secret.getBytes("UTF-8")
    val mac = Mac.getInstance("HmacSHA1")
    mac.init(new SecretKeySpec(key, "HmacSHA1"))
    toHexString(mac.doFinal(message.getBytes("utf-8")))
  }

  def sign_HmacSHA256_base64_v0_5_2(message: String, secret: String): String = {
    val key = secret.getBytes("UTF-8")
    val mac = Mac.getInstance("HmacSHA256")
    mac.init(new SecretKeySpec(key, "HmacSHA256"))
    SessionUtil.toBase64_v0_5_2(mac.doFinal(message.getBytes("utf-8")))
  }

  def encrypt_AES(value: String, secret: String): String = {
    val raw = util.Arrays.copyOf(secret.getBytes("utf-8"), 16)
    val skeySpec = new SecretKeySpec(raw, "AES")
    val cipher = Cipher.getInstance("AES")
    cipher.init(Cipher.ENCRYPT_MODE, skeySpec)
    toHexString(cipher.doFinal(value.getBytes("utf-8")))
  }

  def decrypt_AES(value: String, secret: String): String = {
    val raw = util.Arrays.copyOf(secret.getBytes("utf-8"), 16)
    val skeySpec = new SecretKeySpec(raw, "AES")
    val cipher = Cipher.getInstance("AES")
    cipher.init(Cipher.DECRYPT_MODE, skeySpec)
    new String(cipher.doFinal(hexStringToByte(value)))
  }

  def hash_SHA256(value: String): String = {
    val digest = MessageDigest.getInstance("SHA-256")
    toHexString(digest.digest(value.getBytes("UTF-8")))
  }
} 
Example 7
Source File: data.scala    From redis4cats   with Apache License 2.0 5 votes vote down vote up
package dev.profunktor.redis4cats

import cats.effect.Sync
import cats.syntax.functor._
import dev.profunktor.redis4cats.JavaConversions._
import io.lettuce.core.{ ReadFrom => JReadFrom }
import io.lettuce.core.codec.{ ByteArrayCodec, CipherCodec, CompressionCodec, RedisCodec => JRedisCodec, StringCodec }
import io.lettuce.core.{ KeyScanCursor => JKeyScanCursor }
import javax.crypto.Cipher
import javax.crypto.spec.SecretKeySpec

object data {

  final case class RedisChannel[K](underlying: K) extends AnyVal

  final case class RedisCodec[K, V](underlying: JRedisCodec[K, V]) extends AnyVal
  final case class NodeId(value: String) extends AnyVal

  final case class KeyScanCursor[K](underlying: JKeyScanCursor[K]) extends AnyVal {
    def keys: List[K]  = underlying.getKeys.asScala.toList
    def cursor: String = underlying.getCursor
  }

  object RedisCodec {
    val Ascii: RedisCodec[String, String]           = RedisCodec(StringCodec.ASCII)
    val Utf8: RedisCodec[String, String]            = RedisCodec(StringCodec.UTF8)
    val Bytes: RedisCodec[Array[Byte], Array[Byte]] = RedisCodec(ByteArrayCodec.INSTANCE)

    
    def decryptSupplier[F[_]: Sync](key: SecretKeySpec): F[CipherCodec.CipherSupplier] =
      cipherSupplier[F](key, Cipher.DECRYPT_MODE)

    private def cipherSupplier[F[_]: Sync](key: SecretKeySpec, mode: Int): F[CipherCodec.CipherSupplier] = {
      val mkCipher =
        F.delay {
          val cipher: Cipher = Cipher.getInstance("AES/CBC/PKCS5Padding")
          cipher.init(mode, key)
          cipher
        }

      mkCipher.map { cipher =>
        new CipherCodec.CipherSupplier {
          override def get(kd: CipherCodec.KeyDescriptor): Cipher = cipher
        }
      }
    }

  }

  object ReadFrom {
    val Master           = JReadFrom.MASTER
    val MasterPreferred  = JReadFrom.MASTER_PREFERRED
    val Nearest          = JReadFrom.NEAREST
    val Replica          = JReadFrom.REPLICA
    val ReplicaPreferred = JReadFrom.REPLICA_PREFERRED
  }

} 
Example 8
Source File: CipherUtil.scala    From spark-highcharts   with Apache License 2.0 5 votes vote down vote up
package com.knockdata.spark.utils

import java.security.MessageDigest
import javax.crypto.Cipher
import javax.crypto.spec.{IvParameterSpec, SecretKeySpec}

import sun.misc.{BASE64Decoder, BASE64Encoder}

object CipherUtil {
  val cipherName = "AES/CBC/PKCS5Padding"

  val ivspec = new IvParameterSpec(Array[Byte](0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0))

  def getKey(key: String): Array[Byte] = {
    val raw = MessageDigest.getInstance("MD5").digest(key.getBytes)
    raw
  }

  def encrypt(key: String, password: String): String = {
    val spec = new SecretKeySpec(getKey(key), "AES")
    val cipher = Cipher.getInstance(cipherName)
    cipher.init(Cipher.ENCRYPT_MODE, spec, ivspec)

    val encrypted = cipher.doFinal(password.getBytes("UTF8"))

    new BASE64Encoder().encode(encrypted)
  }

  def decrypt(key: String, encryptedPassword: String): String = {
    val spec = new SecretKeySpec(getKey(key), "AES")
    val cipher = Cipher.getInstance(cipherName)
    cipher.init(Cipher.DECRYPT_MODE, spec, ivspec)

    val encrypted = new BASE64Decoder().decodeBuffer(encryptedPassword)

    val decrypted = cipher.doFinal(encrypted)
    new String(decrypted, "UTF8")
  }
} 
Example 9
Source File: D3ESCBC.scala    From OUTDATED_ledger-wallet-android   with MIT License 5 votes vote down vote up
package co.ledger.wallet.core.crypto

import javax.crypto.Cipher
import javax.crypto.spec.{SecretKeySpec, IvParameterSpec}

class D3ESCBC(secret: Array[Byte], IV: Option[Array[Byte]] = None) {
  Crypto.ensureSpongyIsInserted()

  if (IV.isDefined && IV.get.length != 8) {
    throw new IllegalArgumentException("Initialization Vector must be a 8 bytes array")
  }
  private[this] val iv = new IvParameterSpec(IV.getOrElse(Array[Byte](0, 0, 0, 0, 0, 0, 0, 0)))
  private[this] val cipher = Cipher.getInstance("DESede/CBC/NoPadding", "BC")
  private[this] val secretKey = new SecretKeySpec(secret, "DESede")

  def encrypt(byte: Array[Byte]): Array[Byte] = {
    Crypto.ensureSpongyIsInserted()
    cipher.init(Cipher.ENCRYPT_MODE, secretKey, iv)
    cipher.doFinal(byte)
  }

  def decrypt(byte: Array[Byte]): Array[Byte] = {
    Crypto.ensureSpongyIsInserted()
    cipher.init(Cipher.DECRYPT_MODE, secretKey, iv)
    cipher.doFinal(byte)
  }

} 
Example 10
Source File: Crypto.scala    From akka-http-extensions   with Mozilla Public License 2.0 5 votes vote down vote up
package akka.http.extensions.security

import java.security.MessageDigest
import javax.crypto.Cipher
import javax.crypto.spec.{IvParameterSpec, SecretKeySpec}

import org.apache.commons.codec.binary.Base64

object CryptoConfig {

  implicit def fromString(secret:String): CryptoConfig = CryptoConfig(secret)
}

case class CryptoConfig( secret: String, transformation: String = "AES/CTR/NoPadding")

class CryptoException(val message: String = null, val throwable: Throwable = null)
  extends RuntimeException(message, throwable)

trait Encryption {

  def algorithm:String

  def encrypt(value: String, config:CryptoConfig): String

  def decrypt(value: String, config:CryptoConfig): String
}

object AES extends Encryption {

  val algorithm = "AES"

  protected def secretKeyWithSha256(privateKey: String) = {
    val messageDigest = MessageDigest.getInstance("SHA-256")
    messageDigest.update(privateKey.getBytes("utf-8"))
    // max allowed length in bits / (8 bits to a byte)
    val maxAllowedKeyLength = Cipher.getMaxAllowedKeyLength(algorithm) / 8
    val raw = messageDigest.digest().slice(0, maxAllowedKeyLength)
    new SecretKeySpec(raw, algorithm)
  }


  def encrypt(value: String, config:CryptoConfig): String = {
    val skeySpec = secretKeyWithSha256(config.secret)
    val cipher = Cipher.getInstance(config.transformation)
    cipher.init(Cipher.ENCRYPT_MODE, skeySpec)
    val encryptedValue = cipher.doFinal(value.getBytes("utf-8"))
    Option(cipher.getIV) match {
      case Some(iv) => s"2-${Base64.encodeBase64String(iv ++ encryptedValue)}"
      case None => s"1-${Base64.encodeBase64String(encryptedValue)}"
    }
  }



  def decrypt(value: String, config:CryptoConfig): String =  value.indexOf("-") match
  {
    case sepIndex if sepIndex<0=> throw new CryptoException("Outdated AES version")
    case sepIndex=>
      val data = value.substring(sepIndex + 1, value.length())
      val version = value.substring(0, sepIndex)
      version match {
        case "1" => decryptAES1(data, config)
        case "2" => decryptAES2(data, config)
        case _ =>  throw new CryptoException("Unknown version")
        }
  }


  
  private def decryptAES2(value: String, config:CryptoConfig): String = {
    val cipher = Cipher.getInstance(config.transformation)
    val blockSize = cipher.getBlockSize
    val data = Base64.decodeBase64(value)
    val iv = data.slice(0, blockSize)
    val payload = data.slice(blockSize, data.size)
    val skeySpec = secretKeyWithSha256(config.secret)
    cipher.init(Cipher.DECRYPT_MODE, skeySpec, new IvParameterSpec(iv))
    new String(cipher.doFinal(payload), "utf-8")
  }

} 
Example 11
Source File: Crypto.scala    From gospeak   with Apache License 2.0 5 votes vote down vote up
package gospeak.libs.scala

import java.nio.ByteBuffer
import java.security.{Key, MessageDigest, SecureRandom}
import java.util.Base64

import javax.crypto.spec.IvParameterSpec
import javax.crypto.{Cipher, KeyGenerator}

import scala.util.Try

object Crypto {
  private val charEnc = "UTF-8"
  private val aesKeyLength = 128
  private val aesTransformationString = "AES/CFB/NoPadding"

  def base64Encode(message: String): String =
    base64Encode(message.getBytes)

  def base64Encode(message: Array[Byte]): String =
    new String(Base64.getEncoder.encode(message), charEnc)

  def base64Decode(base64: String): Try[String] =
    base64DecodeBytes(base64).map(new String(_, charEnc))

  def base64DecodeBytes(base64: String): Try[Array[Byte]] =
    Try(Base64.getDecoder.decode(base64.getBytes(charEnc)))

  def md5(message: String): String =
    MessageDigest.getInstance("MD5").digest(message.getBytes).map("%02x".format(_)).mkString

  def sha1(message: String): String =
    MessageDigest.getInstance("SHA1").digest(message.getBytes).map("%02x".format(_)).mkString

  def secureRandom(): Try[Double] = {
    Try(SecureRandom.getInstance("SHA1PRNG")).map { sr =>
      val seedByteCount = 10
      val seed = sr.generateSeed(seedByteCount)
      sr.setSeed(seed)
      sr.nextDouble()
    }
  }

  final case class AesSecretKey(value: String) extends Key {
    override def getAlgorithm: String = "AES"

    override def getFormat: String = "RAW"

    override def getEncoded: Array[Byte] = base64DecodeBytes(value).get

    override def toString: String = "AesSecretKey(*****)"
  }

  final case class AesEncrypted(cipher: String)

  def aesGenerateKey(): Try[AesSecretKey] = for {
    // Generate an AES key of the desired length (in bits) using an AES KeyGenerator.
    keyGen <- Try(KeyGenerator.getInstance("AES"))
    _ <- Try(keyGen.init(aesKeyLength))
    secretKey <- Try(keyGen.generateKey)
  } yield AesSecretKey(base64Encode(secretKey.getEncoded))

  // adapted from https://www.owasp.org/index.php/Using_the_Java_Cryptographic_Extensions
  def aesEncrypt(message: String, secretKey: AesSecretKey): Try[AesEncrypted] = {
    for {
      // Get a Cipher instance of the desired algorithm, mode, and padding.
      aesCipherForEncryption <- Try(Cipher.getInstance(aesTransformationString))
      // Generate an initialization vector for our message of the same size as the Cipher's blocksize.
      iv <- Try(aesCipherForEncryption.getBlockSize).map(new Array[Byte](_))
      prng <- Try(new SecureRandom())
      _ = prng.nextBytes(iv)
      // Initialize the Cipher instance for encryption using the key and initialization vector.
      p <- Try(new IvParameterSpec(iv))
      _ <- Try(aesCipherForEncryption.init(Cipher.ENCRYPT_MODE, secretKey, p))
      // Use the Cipher to encrypt the message (after encoding it to a byte[] using the named Charset), and then append the encrypted data to the IV and Base64-encode the result.
      m <- Try(message.getBytes(charEnc))
      encrypted <- Try(aesCipherForEncryption.doFinal(m))
      cipherData = ByteBuffer.allocate(iv.length + encrypted.length)
      _ = cipherData.put(iv)
      _ = cipherData.put(encrypted)
    } yield AesEncrypted(base64Encode(cipherData.array))
  }

  def aesDecrypt(message: AesEncrypted, secretKey: AesSecretKey): Try[String] = {
    for {
      // Get a new Cipher instance of the same algorithm, mode, and padding used for encryption.
      aesCipherForDecryption <- Try(Cipher.getInstance(aesTransformationString))
      // Base64-decode and split the data into the IV and the encrypted data, and then initialize the cipher for decryption with the same key used for encryption (symmetric), the IV, and the encrypted data.
      cipherData <- base64DecodeBytes(message.cipher).map(ByteBuffer.wrap)
      iv = new Array[Byte](aesCipherForDecryption.getBlockSize)
      _ <- Try(cipherData.get(iv))
      encrypted = new Array[Byte](cipherData.remaining)
      _ <- Try(cipherData.get(encrypted))
      _ <- Try(aesCipherForDecryption.init(Cipher.DECRYPT_MODE, secretKey, new IvParameterSpec(iv)))
      // Use the Cipher to decrypt the data, convert it to a String using the named Charset, and display the message.
      decrypted <- Try(aesCipherForDecryption.doFinal(encrypted))
    } yield new String(decrypted, charEnc)
  }
} 
Example 12
Source File: RSAUtils.scala    From asura   with MIT License 5 votes vote down vote up
package asura.common.util

import java.security._
import java.security.interfaces.{RSAPrivateKey, RSAPublicKey}
import java.security.spec.{PKCS8EncodedKeySpec, X509EncodedKeySpec}
import java.util

import javax.crypto.Cipher

object RSAUtils {

  private val KEY_ALGORITHM = "RSA"
  private val KEY_SIZE = 1024

  private val PUBLIC_KEY = "RSAPublicKey"
  private val PRIVATE_KEY = "RSAPrivateKey"

  @throws[Exception]
  def initKey(): util.Map[String, AnyRef] = {
    val keyPairGenerator = KeyPairGenerator.getInstance(KEY_ALGORITHM)
    keyPairGenerator.initialize(KEY_SIZE)
    val keyPair = keyPairGenerator.generateKeyPair
    val publicKey = keyPair.getPublic.asInstanceOf[RSAPublicKey]
    val privateKey = keyPair.getPrivate.asInstanceOf[RSAPrivateKey]
    val keyMap = new util.HashMap[String, AnyRef]
    keyMap.put(PUBLIC_KEY, publicKey)
    keyMap.put(PRIVATE_KEY, privateKey)
    keyMap
  }


  @throws[Exception]
  def encryptByPrivateKey(data: Array[Byte], key: Array[Byte]): Array[Byte] = {
    val pkcs8KeySpec = new PKCS8EncodedKeySpec(key)
    val keyFactory = KeyFactory.getInstance(KEY_ALGORITHM)
    val privateKey = keyFactory.generatePrivate(pkcs8KeySpec)
    val cipher = Cipher.getInstance(keyFactory.getAlgorithm)
    cipher.init(Cipher.ENCRYPT_MODE, privateKey)
    cipher.doFinal(data)
  }

  @throws[Exception]
  def encryptByPublicKey(data: Array[Byte], key: Array[Byte]): Array[Byte] = {
    val keyFactory = KeyFactory.getInstance(KEY_ALGORITHM)
    val x509KeySpec = new X509EncodedKeySpec(key)
    val pubKey = keyFactory.generatePublic(x509KeySpec)
    val cipher = Cipher.getInstance(keyFactory.getAlgorithm)
    cipher.init(Cipher.ENCRYPT_MODE, pubKey)
    cipher.doFinal(data)
  }

  @throws[Exception]
  def decryptByPrivateKey(data: Array[Byte], key: Array[Byte]): Array[Byte] = {
    val pkcs8KeySpec = new PKCS8EncodedKeySpec(key)
    val keyFactory = KeyFactory.getInstance(KEY_ALGORITHM)
    val privateKey = keyFactory.generatePrivate(pkcs8KeySpec)
    val cipher = Cipher.getInstance(keyFactory.getAlgorithm)
    cipher.init(Cipher.DECRYPT_MODE, privateKey)
    cipher.doFinal(data)
  }

  @throws[Exception]
  def decryptByPublicKey(data: Array[Byte], key: Array[Byte]): Array[Byte] = {
    val keyFactory = KeyFactory.getInstance(KEY_ALGORITHM)
    val x509KeySpec = new X509EncodedKeySpec(key)
    val pubKey = keyFactory.generatePublic(x509KeySpec)
    val cipher = Cipher.getInstance(keyFactory.getAlgorithm)
    cipher.init(Cipher.DECRYPT_MODE, pubKey)
    cipher.doFinal(data)
  }

  def getPrivateKey(keyMap: util.Map[String, AnyRef]): Array[Byte] = {
    val key = keyMap.get(PRIVATE_KEY).asInstanceOf[Key]
    key.getEncoded
  }

  @throws[Exception]
  def getPublicKey(keyMap: util.Map[String, AnyRef]): Array[Byte] = {
    val key = keyMap.get(PUBLIC_KEY).asInstanceOf[Key]
    key.getEncoded
  }
} 
Example 13
Source File: HasEncryption.scala    From recogito2   with Apache License 2.0 5 votes vote down vote up
package services.user

import javax.crypto.Cipher
import javax.crypto.spec.SecretKeySpec
import org.apache.commons.codec.binary.Base64
import java.security.MessageDigest
import java.util.Arrays
import controllers.HasConfig

trait HasEncryption { self: HasConfig =>

  private val CIPHER = "AES/ECB/PKCS5Padding"

  private lazy val keySpec = self.config.getOptional[String]("recogito.email.key").flatMap { key =>
    if (key.isEmpty) {
      None
    } else {
      val md = MessageDigest.getInstance("SHA-1")
      val keyDigest = md.digest(key.getBytes)
      Some(new SecretKeySpec(Arrays.copyOf(keyDigest, 16), "AES"))
    }
  }

  def encrypt(plaintext: String) = keySpec match {
    case Some(spec) => {
      val cipher = Cipher.getInstance(CIPHER)
      cipher.init(Cipher.ENCRYPT_MODE, spec)
      Base64.encodeBase64String(cipher.doFinal(plaintext.getBytes("UTF-8")))
    }

    case None => plaintext
  }

  def decrypt(encrypted: String) = keySpec match {
    case Some(spec) => {
      val cipher = Cipher.getInstance(CIPHER)
      cipher.init(Cipher.DECRYPT_MODE, spec)
      new String(cipher.doFinal(Base64.decodeBase64(encrypted)))
    }

    case None => encrypted
  }

} 
Example 14
Source File: JsonFileStorage.scala    From Waves   with MIT License 5 votes vote down vote up
package com.wavesplatform.utils

import java.io.{File, PrintWriter}

import javax.crypto.Cipher
import javax.crypto.spec.SecretKeySpec
import play.api.libs.json.{Json, Reads, Writes}
import java.util.Base64

import scala.io.Source
import scala.util.control.NonFatal

object JsonFileStorage {
  private[this] val KeySalt           = "0495c728-1614-41f6-8ac3-966c22b4a62d"
  private[this] val AES               = "AES"
  private[this] val Algorithm         = AES + "/ECB/PKCS5Padding"
  private[this] val HashingAlgorithm  = "PBKDF2WithHmacSHA512"
  private[this] val HashingIterations = 999999
  private[this] val KeySizeBits       = 128

  def prepareKey(key: String): SecretKeySpec = {
    import java.security.NoSuchAlgorithmException
    import java.security.spec.InvalidKeySpecException

    import javax.crypto.SecretKeyFactory
    import javax.crypto.spec.PBEKeySpec

    def hashPassword(password: Array[Char], salt: Array[Byte], iterations: Int, keyLength: Int): Array[Byte] =
      try {
        val keyFactory = SecretKeyFactory.getInstance(HashingAlgorithm)
        val keySpec    = new PBEKeySpec(password, salt, iterations, keyLength)
        val key        = keyFactory.generateSecret(keySpec)
        key.getEncoded
      } catch {
        case e @ (_: NoSuchAlgorithmException | _: InvalidKeySpecException) =>
          throw new RuntimeException("Password hashing error", e)
      }

    new SecretKeySpec(hashPassword(key.toCharArray, KeySalt.utf8Bytes, HashingIterations, KeySizeBits), AES)
  }

  def save[T](value: T, path: String, key: Option[SecretKeySpec])(implicit w: Writes[T]): Unit = {
    val folder = new File(path).getParentFile
    if (!folder.exists()) folder.mkdirs()

    val file = new PrintWriter(path)
    try {
      val json = Json.toJson(value).toString()
      val data = key.fold(json)(k => encrypt(k, json))
      file.write(data)
    } finally file.close()
  }

  def save[T](value: T, path: String)(implicit w: Writes[T]): Unit =
    save(value, path, None)

  def load[T](path: String, key: Option[SecretKeySpec] = None)(implicit r: Reads[T]): T = {
    val file = Source.fromFile(path)
    try {
      val dataStr = file.mkString
      Json.parse(key.fold(dataStr)(k => decrypt(k, dataStr))).as[T]
    } finally file.close()
  }

  def load[T](path: String)(implicit r: Reads[T]): T =
    load(path, Option.empty[SecretKeySpec])(r)

  private[this] def encrypt(key: SecretKeySpec, value: String): String = {
    try {
      val cipher: Cipher = Cipher.getInstance(Algorithm)
      cipher.init(Cipher.ENCRYPT_MODE, key)
      new String(Base64.getEncoder.encode(cipher.doFinal(value.utf8Bytes)))
    } catch {
      case NonFatal(e) =>
        throw new RuntimeException("File storage encrypt error", e)
    }
  }

  private[this] def decrypt(key: SecretKeySpec, encryptedValue: String): String = {
    try {
      val cipher: Cipher = Cipher.getInstance(Algorithm)
      cipher.init(Cipher.DECRYPT_MODE, key)
      new String(cipher.doFinal(Base64.getDecoder.decode(encryptedValue)))
    } catch {
      case NonFatal(e) =>
        throw new RuntimeException("File storage decrypt error", e)
    }
  }
} 
Example 15
Source File: crypto.scala    From pfps-shopping-cart   with Apache License 2.0 5 votes vote down vote up
package shop.algebras

import cats.effect.Sync
import cats.implicits._
import javax.crypto.spec.{ PBEKeySpec, SecretKeySpec }
import javax.crypto.{ Cipher, SecretKeyFactory }
import shop.config.data.PasswordSalt
import shop.domain.auth._

trait Crypto {
  def encrypt(value: Password): EncryptedPassword
  def decrypt(value: EncryptedPassword): Password
}

object LiveCrypto {
  def make[F[_]: Sync](secret: PasswordSalt): F[Crypto] =
    Sync[F]
      .delay {
        val salt     = secret.value.value.value.getBytes("UTF-8")
        val keySpec  = new PBEKeySpec("password".toCharArray(), salt, 65536, 256)
        val factory  = SecretKeyFactory.getInstance("PBKDF2WithHmacSHA1")
        val bytes    = factory.generateSecret(keySpec).getEncoded
        val sKeySpec = new SecretKeySpec(bytes, "AES")
        val eCipher  = EncryptCipher(Cipher.getInstance("AES"))
        eCipher.value.init(Cipher.ENCRYPT_MODE, sKeySpec)
        val dCipher = DecryptCipher(Cipher.getInstance("AES"))
        dCipher.value.init(Cipher.DECRYPT_MODE, sKeySpec)
        (eCipher, dCipher)
      }
      .map {
        case (ec, dc) =>
          new LiveCrypto(ec, dc)
      }
}

final class LiveCrypto private (
    eCipher: EncryptCipher,
    dCipher: DecryptCipher
) extends Crypto {

  // Workaround for PostgreSQL ERROR: invalid byte sequence for encoding "UTF8": 0x00
  private val Key = "=DownInAHole="

  def encrypt(password: Password): EncryptedPassword = {
    val bytes      = password.value.getBytes("UTF-8")
    val result     = new String(eCipher.value.doFinal(bytes), "UTF-8")
    val removeNull = result.replaceAll("\\u0000", Key)
    EncryptedPassword(removeNull)
  }

  def decrypt(password: EncryptedPassword): Password = {
    val bytes      = password.value.getBytes("UTF-8")
    val result     = new String(dCipher.value.doFinal(bytes), "UTF-8")
    val insertNull = result.replaceAll(Key, "\\u0000")
    Password(insertNull)
  }

} 
Example 16
Source File: auth.scala    From pfps-shopping-cart   with Apache License 2.0 5 votes vote down vote up
package shop.domain

import eu.timepit.refined.types.string.NonEmptyString
import io.circe._
import io.estatico.newtype.macros.newtype
import java.util.UUID
import javax.crypto.Cipher
import scala.util.control.NoStackTrace

object auth {

  @newtype case class UserId(value: UUID)
  @newtype case class UserName(value: String)
  @newtype case class Password(value: String)

  @newtype case class EncryptedPassword(value: String)

  @newtype case class EncryptCipher(value: Cipher)
  @newtype case class DecryptCipher(value: Cipher)

  // --------- user registration -----------

  @newtype case class UserNameParam(value: NonEmptyString) {
    def toDomain: UserName = UserName(value.value.toLowerCase)
  }

  @newtype case class PasswordParam(value: NonEmptyString) {
    def toDomain: Password = Password(value.value)
  }

  case class CreateUser(
      username: UserNameParam,
      password: PasswordParam
  )

  case class UserNameInUse(username: UserName) extends NoStackTrace
  case class InvalidUserOrPassword(username: UserName) extends NoStackTrace
  case object UnsupportedOperation extends NoStackTrace

  case object TokenNotFound extends NoStackTrace

  // --------- user login -----------

  case class LoginUser(
      username: UserNameParam,
      password: PasswordParam
  )

  // --------- admin auth -----------

  @newtype case class ClaimContent(uuid: UUID)

  object ClaimContent {
    implicit val jsonDecoder: Decoder[ClaimContent] =
      Decoder.forProduct1("uuid")(ClaimContent.apply)
  }

}