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