public UserData registerUser(string username, string password) { // PBKDF2 string pwsalt = ""; string pwhash = ""; // password hash using (var db = new Rfc2898DeriveBytes(password, SALT_SIZE, ITERATIONS)) { pwsalt = Convert.ToBase64String(db.Salt); pwhash = Convert.ToBase64String(db.GetBytes(KEY_SIZE)); } // KEK string keksalt = ""; string kek = ""; // kek generation using (var db = new Rfc2898DeriveBytes(password, SALT_SIZE, ITERATIONS)) { keksalt = Convert.ToBase64String(db.Salt); kek = Convert.ToBase64String(db.GetBytes(KEY_SIZE)); } // RSA string publickey; string privatekey; string privateiv; string encryptedprivatekey; // Generate RSA key pair using (var rsa = new RSACryptoServiceProvider(RSA_SIZE)) { try { privatekey = rsa.ToXmlString(true); publickey = rsa.ToXmlString(false); } finally { // IMPORTANT, avoid storing key in windows store rsa.PersistKeyInCsp = false; } } byte[] privatekeyb = Encoding.UTF8.GetBytes(privatekey); /* logF("register user {0} , password {1}", username, password); log(""); logF("kek {0}", kek); log(""); logF("privatekey {0}", privatekey); log(""); */ using (var cipher = new AesManaged()) { cipher.Mode = CipherMode.CBC; cipher.KeySize = 128; cipher.BlockSize = 128; cipher.Padding = PaddingMode.PKCS7; // cipher.GenerateIV(); privateiv = Convert.ToBase64String(cipher.IV); cipher.Key = Convert.FromBase64String(kek); cipher.IV = Convert.FromBase64String(privateiv); using (ICryptoTransform encryptor = cipher.CreateEncryptor(cipher.Key,cipher.IV)) { using (MemoryStream to = new MemoryStream()) { using (CryptoStream writer = new CryptoStream(to, encryptor, CryptoStreamMode.Write)) { writer.Write(privatekeyb, 0, privatekeyb.Length); writer.FlushFinalBlock(); encryptedprivatekey = Convert.ToBase64String(to.ToArray()); } } } cipher.Clear(); } UserData ud = new UserData() { username = username, passwordSalt = pwsalt, passwordHash = pwhash, KEKSalt = keksalt, privateIV = privateiv, publicKey = publickey, encryptedPrivateKey = encryptedprivatekey }; return ud; }
/* private void writeObject(SslStream sslStream, object obj) { byte[] userDataBytes; MemoryStream ms = new MemoryStream(); BinaryFormatter bf1 = new BinaryFormatter(); bf1.Serialize(ms, obj); userDataBytes = ms.ToArray(); byte[] userDataLen = BitConverter.GetBytes((Int32)userDataBytes.Length); sslStream.Write(userDataLen, 0, 4); sslStream.Write(userDataBytes, 0, userDataBytes.Length); logF("Sent an object of type {0} length {1}:", obj.GetType(), userDataBytes.Length); log(Util.XmlSerializeToString(obj)); } private object readObject(SslStream sslStream) { byte[] readMsgLen = new byte[4]; int dataRead = 0; do { dataRead += sslStream.Read(readMsgLen, 0, 4 - dataRead); } while (dataRead < 4); int dataLen = BitConverter.ToInt32(readMsgLen,0); logF("header: message length {0}", dataLen); if(dataLen == 0) { return null; } byte[] readMsgData = new byte[dataLen]; int len = dataLen; dataRead = 0; do { dataRead += sslStream.Read(readMsgData, dataRead, len - dataRead); } while (dataRead < len); logF("received {0} bytes", len) ; //deserialize MemoryStream ms = new MemoryStream(readMsgData); BinaryFormatter bf1 = new BinaryFormatter(); ms.Position = 0; object rawObj = bf1.Deserialize(ms); log(Util.XmlSerializeToString(rawObj)); return rawObj; }*/ public SecureCalendar registerCalendar(string username, string password, UserData userdata) { SecureCalendar sc = new SecureCalendar() { }; // KEK string FEK = ""; string events = "10:00 Dev team meeting. 20:00 Son birthday party"; // kek generation using (var db = new Rfc2898DeriveBytes(password, SALT_SIZE, ITERATIONS)) { db.Salt = Convert.FromBase64String(userdata.KEKSalt); FEK = Convert.ToBase64String(db.GetBytes(KEY_SIZE)); } // generate KEK using (var cipher = new AesManaged()) { cipher.Mode = CipherMode.CBC; cipher.KeySize = KEY_SIZE * 8; cipher.GenerateKey(); cipher.GenerateIV(); FEK = Convert.ToBase64String(cipher.Key); sc.IV = Convert.ToBase64String(cipher.IV); using (ICryptoTransform encryptor = cipher.CreateEncryptor( cipher.Key, cipher.IV)) { using (MemoryStream to = new MemoryStream()) { using (CryptoStream writer = new CryptoStream(to, encryptor, CryptoStreamMode.Write)) { byte[] x = Encoding.UTF8.GetBytes(Util.XmlSerializeToString(events)); writer.Write(x, 0, x.Length); writer.FlushFinalBlock(); sc.encryptedEvents = Convert.ToBase64String(to.ToArray()); } } } cipher.Clear(); } //Encode FEK with public key RSACryptoServiceProvider rsaPublic = new RSACryptoServiceProvider(); rsaPublic.FromXmlString(userdata.publicKey); byte[] eFEKb = rsaPublic.Encrypt(Convert.FromBase64String(FEK), false); string eFEK = Convert.ToBase64String(eFEKb); sc.keys.Add(new EncryptedFileEncryptionKey() { username = username, eFEK = eFEK }); return sc; }