PageRenderTime 45ms CodeModel.GetById 30ms app.highlight 12ms RepoModel.GetById 1ms app.codeStats 0ms

/TPM-Prototype/src/net/ra23/batman/encyrption/DiffieHellman.scala

https://github.com/xrayn/tpm-scala
Scala | 160 lines | 126 code | 23 blank | 11 comment | 6 complexity | 73ce0baf908407d6f32d734a025f4474 MD5 | raw file
  1/*
  2 * adapted from http://louisbotterill.blogspot.com/2009/01/scala-example-of-diffie-hellman.html
  3 * 
  4 */
  5package net.ra23.batman.encyrption
  6
  7import scala.util.Random
  8import javax.crypto.Cipher
  9import javax.crypto.KeyGenerator
 10import javax.crypto.SecretKey
 11import javax.crypto.spec.SecretKeySpec
 12import org.apache.commons.codec.binary.Base64;
 13import scala.util.matching.Regex;
 14
 15object DiffieHellmanKeyExchange {
 16  /*
 17   * this key is far too weak for production
 18   * either use: http://tools.ietf.org/html/rfc5114#section-2.2
 19   * (key of 3072 Bit is needed, there is none)
 20   * or use Elliptic_curve_cryptography 
 21   * (http://en.wikipedia.org/wiki/Elliptic_curve_cryptography)
 22   */
 23  val p = BigInt("212104724539190889451952152158338349769") //DiffieHellman.randomPrime(128)
 24  val g = 5
 25
 26  val keyCenter = new DiffieHellman(g, p);
 27  var validator = """\d+""".r;
 28  newSecretKey()
 29
 30  def encryptBlowfish(aesKey: String, peerPubKey: Option[String]): Option[String] = {
 31
 32    peerPubKey match {
 33      case None => { None }
 34      case key: Some[String] => {
 35        if (validator.findFirstIn(peerPubKey.get) != None) {
 36          setPeerPubKey(BigInt(peerPubKey.get))
 37          val sharedKey = getSharedKey().toString().getBytes()
 38          val myKeySpec = new SecretKeySpec(sharedKey, "Blowfish");
 39          val cipher = Cipher.getInstance("Blowfish/ECB/PKCS5Padding");
 40          cipher.init(Cipher.ENCRYPT_MODE, myKeySpec);
 41          val ciphertext = cipher.doFinal(aesKey.getBytes())
 42          val cipherout = new Base64().encodeAsString(ciphertext);
 43          Some(cipherout)
 44        } else {
 45          None
 46        }
 47      }
 48    }
 49  }
 50
 51  def decryptBlowfish(aesKey: String, peerPubKey: Option[String]): Option[String] = {
 52
 53    peerPubKey match {
 54      case None => { None }
 55      case key: Some[String] => {
 56        if (validator.findFirstIn(peerPubKey.get) != None) {
 57          setPeerPubKey(BigInt(peerPubKey.get))
 58
 59          setPeerPubKey(BigInt(peerPubKey.get))
 60          val sharedKey = getSharedKey().toString().getBytes()
 61          val myKeySpec = new SecretKeySpec(sharedKey, "Blowfish");
 62          val cipher = Cipher.getInstance("Blowfish/ECB/PKCS5Padding");
 63          cipher.init(Cipher.DECRYPT_MODE, myKeySpec);
 64          val crypted = new Base64().decode(aesKey);
 65          var plaintext = ""
 66          try {
 67            val cipherByte = cipher.doFinal(crypted)
 68            cipherByte.foreach(c => { plaintext = plaintext + c.toChar });
 69            println("PEER PUB KEY IS [" + peerPubKey.get + "]");
 70            println("  BASE64 AES IS [" + aesKey + "]")
 71            println("  PLAINTEXT  IS [" + plaintext + "]")
 72            println("  SHARED KEY IS [" + getSharedKey().toString() + "]")
 73            Some(plaintext)
 74          } catch {
 75            case e: Exception => {
 76              println("PEER PUB KEY IS [" + peerPubKey.get + "]");
 77              println("  BASE64 AES IS [" + aesKey + "]")
 78              println("  PLAINTEXT  IS [" + plaintext + "]")
 79              println("  SHARED KEY IS [" + getSharedKey().toString() + "]")
 80              e.printStackTrace(); None
 81            }
 82          }
 83        } else {
 84          None
 85        }
 86      }
 87    }
 88  }
 89
 90  def getAddedAesKey(aesKey: String, peerPubKey: Option[String]): String = {
 91    setPeerPubKey(BigInt(peerPubKey.get))
 92    val sharedKey = getSharedKey().toString().getBytes()
 93    (BigInt(aesKey) + getSharedKey()).toString()
 94  }
 95  def getAesKeyFromPayload(payload: String, peerPubKey: Option[String]): String = {
 96    setPeerPubKey(BigInt(peerPubKey.get))
 97    val sharedKey = getSharedKey().toByteArray
 98    (BigInt(payload) - getSharedKey()).toString();
 99  }
100  def newSecretKey() = {
101    keyCenter.createSecretKey()
102  }
103  def getPublicKey(): BigInt = {
104    keyCenter.getPublicKey();
105  }
106  def setPeerPubKey(key: BigInt) = {
107    keyCenter.setPeerPublicKey(key)
108  }
109
110  def getSharedKey(): BigInt = {
111    keyCenter.createSharedKey()
112  }
113}
114
115object DiffieHellman {
116
117  def randomPrime(n: Int): BigInt = { // return a random value with n digits
118
119    val rnd = new Random();
120
121    BigInt.probablePrime(n, rnd)
122  }
123}
124
125class DiffieHellman(val g: Int, p: BigInt) {
126
127  var secretKey: BigInt = 0
128  var peerPublicKey: BigInt = 0
129
130  def createSecretKey() {
131    secretKey = random(128)
132    println("secretKey = " + secretKey)
133  }
134
135  def setPeerPublicKey(x: BigInt) {
136    peerPublicKey = x
137  }
138
139  def getPublicKey(): BigInt = {
140    doExpMod(g, secretKey, p)
141  }
142
143  def random(n: Int): BigInt = { // return a random value with n digits
144    val rnd = new Random();
145    BigInt(n, rnd)
146  }
147
148  def createSharedKey(): BigInt = {
149    doExpMod(peerPublicKey, secretKey, p)
150  }
151
152  private def doExpMod(x: BigInt): BigInt = {
153    println("doExpMod g = " + g + ", x = " + x + ", p = " + p)
154    doExpMod(g, x, p)
155  }
156
157  private def doExpMod(g: BigInt, x: BigInt, m: BigInt): BigInt = {
158    g.modPow(x, m)
159  }
160}