/TPM-Prototype/src/net/ra23/batman/encyrption/DiffieHellman.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}