public byte[] HybridDecrypt(Stream inputStream, User user) { using (var streamReader = new MemoryStream()) { inputStream.CopyTo(streamReader); var result = streamReader.ToArray(); var secretKeyEnc = new byte[128]; var ivEnc = new byte[128]; Array.Copy(result, 0, secretKeyEnc, 0, 128); Array.Copy(result, 128, ivEnc, 0, 128); var contentLength = result.Length - 256; var content = new byte[contentLength]; Array.Copy(result, 256, content, 0, contentLength); var secretKey = AsymmetricDecrypt(secretKeyEnc, user); var iv = AsymmetricDecrypt(ivEnc, user); var symmetricKeys = new SymmetricParameters { SecretKey = secretKey, IV = iv }; var stream = new MemoryStream(content); return(SymmetricDecryptFile(stream, symmetricKeys)); } }
private static SymmetricParameters GenerateSymmetricParameters(User user) { if (user == null) { throw new Exception("User cannot be null"); } // having a random IV is crucial var guid = Guid.NewGuid(); var username = user.Username; var password = user.Password; var salt = guid + username + password; var saltBytes = Encoding.UTF32.GetBytes(salt); using (var rijndael = Rijndael.Create()) using (var rfc = new Rfc2898DeriveBytes(password, saltBytes)) { var symetricParams = new SymmetricParameters { SecretKey = rfc.GetBytes(rijndael.KeySize / 8), IV = rfc.GetBytes(rijndael.BlockSize / 8) }; return(symetricParams); } }
public ActionResult Create([Bind(Include = "Id,Title")] Article article, HttpPostedFileBase file) { if (ModelState.IsValid) { try { EncryptionUtility utility = new EncryptionUtility(); SymmetricParameters parameters = utility.GenerateSymmetricParameters("123qwe", "ijbygcrz"); string userId = User.Identity.GetUserId(); // Public and private keys are generated during user registration, stored in UserKey table string publicKey = db.UserKeys.SingleOrDefault(k => k.UserId == userId).PublicKey; string privateKey = db.UserKeys.SingleOrDefault(k => k.UserId == userId).PrivateKey; //Convert file into an array of bytes, results saved in memory MemoryStream ms = new MemoryStream(); file.InputStream.Position = 0; file.InputStream.CopyTo(ms); ms.Position = 0; //Signing Process string signature = utility.GenerateSignature(ms.ToArray(), privateKey); // Encryption Process string encryptedSK = utility.Encrypt(parameters.SecretKey, publicKey); string encryptedIV = utility.Encrypt(parameters.IV, publicKey); string encryptedFile = utility.Encrypt(ms.ToArray(), parameters); // Storage Process string filePath = Server.MapPath(@"\Files"); //File save location string fileName = Guid.NewGuid().ToString(); //Generate unique file name string absoluteFilePath = filePath + @"\" + fileName; //Build file data, Secret key and IV in file header utility.WriteToFile(absoluteFilePath, utility.FileMerge(encryptedSK, encryptedIV, encryptedFile)); //Database Process article.UserId = User.Identity.GetUserId(); article.DateCreated = DateTime.Now; article.StateId = 1; article.Signature = signature; article.FileName = fileName; db.Articles.Add(article); db.SaveChanges(); ViewBag.Message = "Upload & Encryption Successful"; return(RedirectToAction("Index")); } catch { return(RedirectToAction("Missing")); } } return(View()); }
private static byte[] SymmetricDecryptFile(Stream cipher, SymmetricParameters symmetricParameters) { using (var rijndael = Rijndael.Create()) using (var memoryStream = new MemoryStream()) using (var cryptoStream = new CryptoStream(memoryStream, rijndael.CreateDecryptor(symmetricParameters.SecretKey, symmetricParameters.IV), CryptoStreamMode.Write)) { cipher.CopyTo(cryptoStream); cryptoStream.FlushFinalBlock(); memoryStream.Position = 0; return(memoryStream.ToArray()); } }
private static byte[] SymmetricEncryptFile(Stream inputStream, User user, out SymmetricParameters symmetricParameters) { if (user == null) { throw new Exception("User cannot be null"); } symmetricParameters = GenerateSymmetricParameters(user); using (var rijndael = Rijndael.Create()) using (var memoryStream = new MemoryStream()) using (var cryptoStream = new CryptoStream(memoryStream, rijndael.CreateEncryptor(symmetricParameters.SecretKey, symmetricParameters.IV), CryptoStreamMode.Write)) { inputStream.CopyTo(cryptoStream); cryptoStream.FlushFinalBlock(); memoryStream.Position = 0; return(memoryStream.ToArray()); } }
//[Bind(Include = "Id,UserId,ReviewId,Title,Body,DateCreated,StateId")] Article article public ActionResult Edit([Bind(Include = "Id,UserId,ReviewId,DateCreated,StateId,FileName,Title")] Article article, HttpPostedFileBase file) { if (ModelState.IsValid) { try { if (article.StateId == 1 || article.StateId == 3) // Unlocked states { EncryptionUtility utility = new EncryptionUtility(); SymmetricParameters parameters = utility.GenerateSymmetricParameters("123qwe", "ijbygcrz"); string userId = User.Identity.GetUserId(); // Public and private keys are generated during user registration, stored in UserKey table string PublicKey = db.UserKeys.SingleOrDefault(k => k.UserId == userId).PublicKey; string PrivateKey = db.UserKeys.SingleOrDefault(k => k.UserId == userId).PrivateKey; //Convert file into an array of bytes, results saved in memory MemoryStream ms = new MemoryStream(); file.InputStream.Position = 0; file.InputStream.CopyTo(ms); ms.Position = 0; //Signing Process string signature = utility.GenerateSignature(ms.ToArray(), PrivateKey); // Encryption Process string encryptedSK = utility.Encrypt(parameters.SecretKey, PublicKey); string encryptedIV = utility.Encrypt(parameters.IV, PublicKey); string encryptedFile = utility.Encrypt(ms.ToArray(), parameters); // Storage Process string filePath = Server.MapPath(@"\Files"); //File save location string absoluteFilePath = filePath + @"\" + article.FileName; // If same name of file present then delete that file first if (System.IO.File.Exists(absoluteFilePath)) { System.IO.File.Delete(absoluteFilePath); } //Build file data, Secret key and IV in file header utility.WriteToFile(absoluteFilePath, utility.FileMerge(encryptedSK, encryptedIV, encryptedFile)); // Database Process if (article.Review != null) { article.Review.Accepted = false; } article.StateId = 1; // Revert back to pending article.DateLastEdited = DateTime.Now; article.Signature = signature; db.Entry(article).State = EntityState.Modified; db.SaveChanges(); ViewBag.Message = "Upload & Encryption Successful"; return(RedirectToAction("Index")); } else { ViewBag.Message = "Only Pending or Finished articles can be updated."; } } catch { return(RedirectToAction("Missing")); } } return(View(article)); }
public ActionResult Download(string fileName) { bool isPublished = false; if (db.Articles.SingleOrDefault(a => a.FileName == fileName).StateId == 4) { isPublished = true; } bool advancedUser = false; if (User.IsInRole("Author") || User.IsInRole("MediaManager")) { advancedUser = true; } if (advancedUser == false && isPublished == false) { return(RedirectToAction("Missing")); } else { try { EncryptionUtility utility = new EncryptionUtility(); SymmetricParameters parameters = new SymmetricParameters(); string userId = db.Articles.SingleOrDefault(a => a.FileName == fileName).UserId; // Public and private keys are generated during user registration, stored in UserKey table string publicKey = db.UserKeys.SingleOrDefault(k => k.UserId == userId).PublicKey; string privateKey = db.UserKeys.SingleOrDefault(k => k.UserId == userId).PrivateKey; string signature = db.Articles.SingleOrDefault(a => a.FileName == fileName).Signature; // Retrieval Process string filePath = Server.MapPath(@"\Files" + @"\" + fileName); string encryptedFile = utility.ReadFromFile(filePath); // Decryption Process string[] splitString = encryptedFile.Split(new string[] { "#CONTENT#" }, StringSplitOptions.None); string[] keyiv = splitString[0].Split(new string[] { "$KEY$" }, StringSplitOptions.None); string SK = keyiv[0]; string IV = keyiv[1]; string encryptedContent = splitString[1]; parameters.SecretKey = utility.Decrypt(SK, privateKey); parameters.IV = utility.Decrypt(IV, privateKey); //Decrypt file using Secret key and IV byte[] decryptedFile = utility.Decrypt(encryptedContent, parameters); bool verify = utility.VerifySignature(decryptedFile, publicKey, signature); ViewBag.isValid = verify.ToString(); return(File(decryptedFile, System.Net.Mime.MediaTypeNames.Application.Octet, "Article")); } catch { return(RedirectToAction("Missing")); } } }