internal KeyStore(UserKeyStore uks, string password, byte[] salt) { // Should only execute when user has a keystore if (uks is UserKeyStore) { byte[] aesKey, rsaBytes; byte[] desIv = uks.DesIv; byte[] aesIv = uks.AesIv; try { aesKey = Crypt.Instance.DeriveKey(password, salt, desIv); rsaBytes = Crypt.Instance.DecryptAes(uks.RsaPriv, aesKey, aesIv); } catch (CryptographicException) { throw new KeyStoreException("KeyStore is in invalid state"); } string rsaPrivate = Encoding.UTF8.GetString(rsaBytes); this.aesIv = uks.AesIv; this.aesKey = aesKey; this.rsaPrivate = rsaPrivate; this.rsaPublic = uks.RsaPub; this.TOTPSecret = uks.TOTPSecret; this.rsaBytes = uks.RsaPriv; this.UserId = uks.UserId; } else { throw new KeyStoreException("KeyStore is in invalid state"); } }
/// <summary> /// CENTRALISED METHOD FOR CREATING USERKEYSTORES /// </summary> internal static UserKeyStore DefaultDbKeyStore(string password, byte[] salt, int userId) { UserKeyStore uks; // Required to derive key from password byte[] desIv = Crypt.Instance.GenerateIv("DES"); // Required to decrypt the RSA key byte[] aesKey = Crypt.Instance.DeriveKey(password, salt, desIv); byte[] aesIv = Crypt.Instance.Generate(16); string rsaString = Crypt.Instance.GenerateRsaParameters(); byte[] rsaStringBytes = Encoding.UTF8.GetBytes(rsaString); byte[] rsaEncrypted = Crypt.Instance.EncryptAes(rsaStringBytes, aesKey, aesIv); string rsaPublic = Crypt.Instance.RemovePrivateKey(rsaString); uks = new UserKeyStore() { AesIv = aesIv, DesIv = desIv, TOTPSecret = null, RsaPub = rsaPublic, RsaPriv = rsaEncrypted, UserId = userId }; return(uks); }
/// <summary> /// Update the user's password /// </summary> /// <param name="oldpass">Old password to validate</param> /// <param name="newpass">Intended password to be changed</param> /// <returns>AuthResult Success if password is changed successfully</returns> internal AuthResult UpdatePassword(string oldpass, string newpass) { using (DataContext db = new DataContext()) { Users u = Users.FindByEmail(this.Email, db); if (u == null) { return(AuthResult.UserNotFound); } AuthResult oldpwres = ValidateLogin(oldpass); if (oldpwres != AuthResult.Success) { return(oldpwres); } db.Entry(u).Reference(usr => usr.UserKeyStore).Load(); // Get the user key store and decrypt their private key UserKeyStore uks = u.UserKeyStore; byte[] aesKey = Crypt.Instance.DeriveKey(oldpass, u.Salt, uks.DesIv); byte[] rsaPrivBytes = Crypt.Instance.DecryptAes(uks.RsaPriv, aesKey, uks.AesIv); // Do the password update u.UpdatePassword(newpass); // Encrypt the private key again byte[] newAesIv = Crypt.Instance.GenerateIv("AES"); uks.AesIv = newAesIv; byte[] newAesKey = Crypt.Instance.DeriveKey(newpass, u.Salt, uks.DesIv); byte[] newRsaPrivEnc = Crypt.Instance.EncryptAes(rsaPrivBytes, newAesKey, newAesIv); uks.RsaPriv = newRsaPrivEnc; db.SaveChanges(); AuthLogger.Instance.PasswordChanged(); return(AuthResult.Success); } }