diff --git a/SciPost_v1/settings/base.py b/SciPost_v1/settings/base.py
index 3a236b58512d1010200fe03a6e643579614ad7cc..4083889191653f3b3464621e2b8374370f43dd47 100644
--- a/SciPost_v1/settings/base.py
+++ b/SciPost_v1/settings/base.py
@@ -246,3 +246,31 @@ CROSSREF_LOGIN_PASSWORD = ''
 RECAPTCHA_PUBLIC_KEY = '6LeIxAcTAAAAAJcZVRqyHh71UMIEGNQ_MXjiZKhI'
 RECAPTCHA_PRIVATE_KEY = '6LeIxAcTAAAAAGG-vFI1TnRWxMZNFuojJ4WifJWe'
 NOCAPTCHA = True
+
+
+# PASSWORDS
+
+PASSWORD_HASHERS = [
+    'django.contrib.auth.hashers.Argon2PasswordHasher',
+    'django.contrib.auth.hashers.PBKDF2PasswordHasher',
+    'django.contrib.auth.hashers.PBKDF2SHA1PasswordHasher',
+    'django.contrib.auth.hashers.BCryptSHA256PasswordHasher',
+    'django.contrib.auth.hashers.BCryptPasswordHasher',
+]
+AUTH_PASSWORD_VALIDATORS = [
+    {
+        'NAME': 'django.contrib.auth.password_validation.UserAttributeSimilarityValidator',
+    },
+    {
+        'NAME': 'django.contrib.auth.password_validation.MinimumLengthValidator',
+        'OPTIONS': {
+            'min_length': 8,
+        }
+    },
+    {
+        'NAME': 'django.contrib.auth.password_validation.CommonPasswordValidator',
+    },
+    {
+        'NAME': 'django.contrib.auth.password_validation.NumericPasswordValidator',
+    },
+]
diff --git a/requirements.txt b/requirements.txt
index 8a82ef7057d72bccf77dc2a8d9aeec140e2861bf..fe99a6a6fd57b124ee6a3bc066c10aa7087b4092 100644
--- a/requirements.txt
+++ b/requirements.txt
@@ -1,4 +1,5 @@
 alabaster==0.7.9
+argon2-cffi==16.3.0
 Babel==2.3.4
 Django==1.10.3
 django_ajax_selects==1.5.2
diff --git a/scipost/forms.py b/scipost/forms.py
index 8fde48c4e6778911e6bf9b1939a704a763de99b1..21c68fe51c5aa3a94289857a942539a620b7757d 100644
--- a/scipost/forms.py
+++ b/scipost/forms.py
@@ -1,6 +1,8 @@
 from django import forms
 from django.contrib.auth import authenticate
 from django.contrib.auth.models import User, Group
+from django.contrib.auth.password_validation import validate_password
+from django.core.exceptions import ValidationError
 from django.core.urlresolvers import reverse_lazy
 from django.utils.http import is_safe_url
 
@@ -16,7 +18,7 @@ from .models import Contributor, DraftInvitation, RegistrationInvitation,\
                     UnavailabilityPeriod, PrecookedEmail
 
 from journals.models import Publication
-from mailing_lists.models import MailchimpList, MailchimpSubscription
+# from mailing_lists.models import MailchimpList, MailchimpSubscription
 
 
 REGISTRATION_REFUSAL_CHOICES = (
@@ -60,13 +62,28 @@ class RegistrationForm(forms.Form):
         required=False)
     username = forms.CharField(label='* Username', max_length=100)
     password = forms.CharField(label='* Password', widget=forms.PasswordInput())
-    password_verif = forms.CharField(label='* Verify password', widget=forms.PasswordInput())
+    password_verif = forms.CharField(label='* Verify password', widget=forms.PasswordInput(),
+                                     help_text='Your password must contain at least 8 characters')
     captcha = ReCaptchaField(attrs={'theme': 'clean'}, label='*Please verify to continue:')
 
+    def clean_password(self):
+        password = self.cleaned_data.get('password', '')
+        user = User(
+            username=self.cleaned_data.get('username', ''),
+            first_name=self.cleaned_data.get('first_name', ''),
+            last_name=self.cleaned_data.get('last_name', ''),
+            email=self.cleaned_data.get('email', '')
+        )
+        try:
+            validate_password(password, user)
+        except ValidationError as error_message:
+            self.add_error('password', error_message)
+        return password
+
     def clean_password_verif(self):
-        if self.cleaned_data['password'] != self.cleaned_data['password_verif']:
-            self.add_error('password', 'Your passwords must match')
-            self.add_error('password_verif', 'Your passwords must match')
+        if self.cleaned_data.get('password', '') != self.cleaned_data.get('password_verif', ''):
+            self.add_error('password_verif', 'Your password entries must match')
+        return self.cleaned_data.get('password_verif', '')
 
     def clean_username(self):
         if User.objects.filter(username=self.cleaned_data['username']).exists():
@@ -245,6 +262,40 @@ class PasswordChangeForm(forms.Form):
     password_new = forms.CharField(label='New password', widget=forms.PasswordInput())
     password_verif = forms.CharField(label='Reenter new password', widget=forms.PasswordInput())
 
+    def __init__(self, *args, **kwargs):
+        self.current_user = kwargs.pop('current_user', None)
+        super().__init__(*args, **kwargs)
+
+    def clean_password_prev(self):
+        '''Check if old password is correct.'''
+        password_prev = self.cleaned_data['password_prev']
+        if not self.current_user.check_password(password_prev):
+            self.add_error('password_prev',
+                           'The currently existing password you entered is incorrect')
+        return password_prev
+
+    def clean_password_new(self):
+        '''Validate the newly chosen password using the validators as per the settingsfile.'''
+        password = self.cleaned_data['password_new']
+        try:
+            validate_password(password, self.current_user)
+        except ValidationError as error_message:
+            self.add_error('password_new', error_message)
+        return password
+
+    def clean_password_verif(self):
+        '''Check if the new password's match to ensure the user entered new password correctly.'''
+        password_verif = self.cleaned_data.get('password_verif', '')
+        if self.cleaned_data['password_new'] != password_verif:
+            self.add_error('password_verif', 'Your new password entries must match')
+        return password_verif
+
+    def save_new_password(self):
+        '''Save new password is form is valid.'''
+        if not self.errors:
+            self.current_user.set_password(self.cleaned_data['password_new'])
+            self.current_user.save()
+
 
 AUTHORSHIP_CLAIM_CHOICES = (
     ('-', '-'),
diff --git a/scipost/templates/scipost/change_password.html b/scipost/templates/scipost/change_password.html
index c0e94de5a9504fcd7bc707c9e250539acf6bfbab..ffac2c40459b6a3d8c61fa8ddc8f8d6f517494aa 100644
--- a/scipost/templates/scipost/change_password.html
+++ b/scipost/templates/scipost/change_password.html
@@ -6,26 +6,16 @@
 
 {% block content %}
 
-{% if ack %}
-    <div class="row">
-        <div class="col-12">
-            <h1>Your SciPost password has been successfully changed</h1>
-        </div>
-    </div>
-{% else %}
-    <div class="row">
-        <div class="col-lg-8 offset-lg-2">
-            <h1 class="highlight">Change your SciPost password</h1>
-            {% if errormessage %}
-              <p class="text-danger">{{ errormessage }}</p>
-            {% endif %}
-            <form action="{% url 'scipost:change_password' %}" method="post">
-                {% csrf_token %}
-                {{form|bootstrap}}
-                <input type="submit" class="btn btn-secondary" value="Change" />
-            </form>
-        </div>
+<div class="row">
+    <div class="col-lg-8 offset-lg-2">
+        <h1 class="highlight">Change your SciPost password</h1>
+
+        <form action="{% url 'scipost:change_password' %}" method="post">
+            {% csrf_token %}
+            {{form|bootstrap}}
+            <input type="submit" class="btn btn-secondary" value="Change" />
+        </form>
     </div>
-{% endif %}
+</div>
 
 {% endblock content %}
diff --git a/scipost/templates/scipost/reset_password.html b/scipost/templates/scipost/reset_password.html
index 429ed46c71c7a1f728fdb45bd427a4b18bc62ffd..e8169dba2c0608cf7b3b4d23b8c83c65d12f15f8 100644
--- a/scipost/templates/scipost/reset_password.html
+++ b/scipost/templates/scipost/reset_password.html
@@ -2,20 +2,20 @@
 
 {% block pagetitle %}: Reset Password{% endblock pagetitle %}
 
-{% block bodysup %}
-
 {% load bootstrap %}
 
-<div class="container">
-    <div class="row">
-        <div class="col-md-4">
-  <h3>Reset password request form</h3>
-  <form method="post">
-    {% csrf_token %}
-    {{ form|bootstrap }}
-    <input class="btn btn-primary" type="submit" value="Submit" />
-  </form>
+{% block content %}
+
+
+<div class="row">
+    <div class="col-md-4 offset-md-4">
+          <h3>Reset password request form</h3>
+          <form method="post">
+            {% csrf_token %}
+            {{ form|bootstrap }}
+            <input class="btn btn-primary" type="submit" value="Submit" />
+          </form>
         </div>
-    </div>
 </div>
-{% endblock bodysup %}
+
+{% endblock %}
diff --git a/scipost/templates/scipost/reset_password_complete.html b/scipost/templates/scipost/reset_password_complete.html
index f675ab9967a7677319b1e252b57c52086aef1a33..dd226a8df6f40d4867d08a24b794f52fc3889a0a 100644
--- a/scipost/templates/scipost/reset_password_complete.html
+++ b/scipost/templates/scipost/reset_password_complete.html
@@ -3,5 +3,5 @@
 {% block pagetitle %}: Reset password complete{% endblock pagetitle %}
 
 {% block bodysup %}
-<p>You have successfully reset your password.</p>
+    <p>You have successfully reset your password.</p>
 {% endblock bodysup %}
diff --git a/scipost/templates/scipost/reset_password_confirm.html b/scipost/templates/scipost/reset_password_confirm.html
index e302efffc0b6085d18bfd325611f20a61554f470..60afebc99f0f143ac49d577665f4475f7e3a6cb2 100644
--- a/scipost/templates/scipost/reset_password_confirm.html
+++ b/scipost/templates/scipost/reset_password_confirm.html
@@ -2,16 +2,22 @@
 
 {% block pagetitle %}: Reset password confirm{% endblock pagetitle %}
 
-{% block bodysup %}
-<section>
+{% load bootstrap %}
+
+{% block content %}
+
+<div class="row">
+    <div class="col-md-6 offset-md-3">
     {% if validlink %}
         <form method="post">
             {% csrf_token %}
-            {{ form.as_p }}
-            <button type="submit">Submit</button>
+            {{ form|bootstrap }}
+            <input class="btn btn-secondary" type="submit" value="Submit">
         </form>
     {% else %}
         <p>This reset link is no longer valid!</p>
     {% endif %}
-</section>
-{% endblock bodysup %}
+    </div>
+</div>
+
+{% endblock content %}
diff --git a/scipost/views.py b/scipost/views.py
index c113d3b9f496c6007a23855ec3f571200d329668..d603e50197e61cdef8f67dfad460d6dc378915e1 100644
--- a/scipost/views.py
+++ b/scipost/views.py
@@ -3,7 +3,7 @@ import re
 from django.utils import timezone
 from django.shortcuts import get_object_or_404, render
 from django.contrib import messages
-from django.contrib.auth import login, logout
+from django.contrib.auth import login, logout, update_session_auth_hash
 from django.contrib.auth.decorators import login_required
 from django.contrib.auth.models import Group
 from django.contrib.auth.views import password_reset, password_reset_confirm
@@ -914,23 +914,14 @@ def personal_page(request):
 
 @login_required
 def change_password(request):
-    form = PasswordChangeForm(request.POST or None)
-    ack = False
+    form = PasswordChangeForm(request.POST or None, current_user=request.user)
     if form.is_valid():
-        if not request.user.check_password(form.cleaned_data['password_prev']):
-            return render(
-                request, 'scipost/change_password.html',
-                {'form': form,
-                 'errormessage': 'The currently existing password you entered is incorrect'})
-        if form.cleaned_data['password_new'] != form.cleaned_data['password_verif']:
-            return render(request, 'scipost/change_password.html', {
-                          'form': form,
-                          'errormessage': 'Your new password entries must match'})
-        request.user.set_password(form.cleaned_data['password_new'])
-        request.user.save()
-        ack = True
-
-    return render(request, 'scipost/change_password.html', {'ack': ack, 'form': form})
+        form.save_new_password()
+        # Update user's session hash to stay logged in.
+        update_session_auth_hash(request, request.user)
+        messages.success(request, 'Your SciPost password has been successfully changed')
+        return redirect(reverse('scipost:personal_page'))
+    return render(request, 'scipost/change_password.html', {'form': form})
 
 
 def reset_password_confirm(request, uidb64=None, token=None):