diff --git a/reviewboard/accounts/forms/auth.py b/reviewboard/accounts/forms/auth.py
index e1a34f399348e54e6f7bc1b042c2b600bb3fded7..552cbca6bf4e1e52e99cf574f786c1f66da7271f 100644
--- a/reviewboard/accounts/forms/auth.py
+++ b/reviewboard/accounts/forms/auth.py
@@ -112,7 +112,7 @@ class StandardAuthSettingsForm(SiteSettingsForm):
               'will need to go <a href="%(register_url)s">here</A> to '
               'register an account and type in your new keys below.')
             % {
-                'recaptcha_url': 'http://www.recaptcha.net/',
+                'recaptcha_url': 'http://www.google.com/recaptcha',
                 'register_url': 'https://www.google.com/recaptcha/admin'
                                 '#createsite',
             }),
diff --git a/reviewboard/accounts/forms/registration.py b/reviewboard/accounts/forms/registration.py
index 85dc1e0c23cd98c32dd8be76773d32bbcaf0c5fd..022929ff947ba279ef8515aa08a443bca6d484b5 100644
--- a/reviewboard/accounts/forms/registration.py
+++ b/reviewboard/accounts/forms/registration.py
@@ -1,14 +1,11 @@
 from __future__ import unicode_literals
 
 from django import forms
-from django.core.exceptions import ValidationError
-from django.utils.translation import ugettext_lazy as _
 from djblets.auth.forms import RegistrationForm as DjbletsRegistrationForm
-from djblets.siteconfig.models import SiteConfiguration
-from recaptcha.client import captcha
+from djblets.recaptcha.mixins import RecaptchaFormMixin
 
 
-class RegistrationForm(DjbletsRegistrationForm):
+class RegistrationForm(RecaptchaFormMixin, DjbletsRegistrationForm):
     """A registration form with reCAPTCHA support.
 
     This is a version of the Djblets RegistrationForm which knows how to
@@ -19,56 +16,6 @@ class RegistrationForm(DjbletsRegistrationForm):
 
     first_name = forms.CharField(required=False)
     last_name = forms.CharField(required=False)
-    recaptcha_challenge_field = forms.CharField(required=False)
-    recaptcha_response_field = forms.CharField(required=False)
-
-    def __init__(self, *args, **kwargs):
-        """Initialize the form."""
-        super(RegistrationForm, self).__init__(*args, **kwargs)
-        self.captcha_error_query_str = ""
-
-        siteconfig = SiteConfiguration.objects.get_current()
-
-        if siteconfig.get('site_domain_method') == 'https':
-            self.recaptcha_url = 'https://www.google.com/recaptcha/api'
-        else:
-            self.recaptcha_url = 'http://www.google.com/recaptcha/api'
-
-    def clean(self):
-        """Validate all form fields."""
-        siteconfig = SiteConfiguration.objects.get_current()
-
-        if siteconfig.get('auth_registration_show_captcha'):
-            challenge = self.cleaned_data.get('recaptcha_challenge_field',
-                                              None)
-            response = self.cleaned_data.get('recaptcha_response_field', None)
-
-            if challenge and response:
-                captcha_response = \
-                    captcha.submit(
-                        challenge,
-                        response,
-                        siteconfig.get('recaptcha_private_key'),
-                        self.request.META.get('REMOTE_ADDR', None))
-
-                if not captcha_response.is_valid:
-                    self.captcha_error_query_str = '&error=%s' % \
-                        captcha_response.error_code
-
-                    # This isn't actually seen in the Review Board UI,
-                    # as the reCAPTCHA widget itself displays the error
-                    # message. However, this may be useful for testing or
-                    # debugging.
-                    raise ValidationError(
-                        _("The text you entered didn't match what was "
-                          "displayed"))
-            else:
-                self.captcha_error_query_str = '&error=incorrect-captcha-sol'
-
-                raise ValidationError(
-                    _('You need to respond to the captcha'))
-
-        return super(RegistrationForm, self).clean()
 
     def save(self):
         """Save the form."""
diff --git a/reviewboard/admin/siteconfig.py b/reviewboard/admin/siteconfig.py
index 16fee6ee59656bfe629f57290ef418c139560af0..828d1a4704ba34ec1d2d0c7838cf339bb69f8e94 100644
--- a/reviewboard/admin/siteconfig.py
+++ b/reviewboard/admin/siteconfig.py
@@ -39,6 +39,7 @@ from django.conf import settings, global_settings
 from django.core.exceptions import ImproperlyConfigured
 from django.utils import six
 from djblets.log import restart_logging, siteconfig as log_siteconfig
+from djblets.recaptcha import siteconfig as recaptcha_siteconfig
 from djblets.siteconfig.django_settings import (apply_django_settings,
                                                 get_django_defaults,
                                                 get_django_settings_map)
@@ -90,6 +91,7 @@ settings_map = {
 }
 settings_map.update(get_django_settings_map())
 settings_map.update(log_siteconfig.settings_map)
+settings_map.update(recaptcha_siteconfig.settings_map)
 
 # Settings for django-storages
 settings_map.update({
@@ -116,6 +118,7 @@ settings_map.update({
 # All the default values for settings.
 defaults = get_django_defaults()
 defaults.update(log_siteconfig.defaults)
+defaults.update(recaptcha_siteconfig.defaults)
 defaults.update({
     'auth_ldap_anon_bind_uid':             '',
     'auth_ldap_anon_bind_passwd':          '',
diff --git a/reviewboard/settings.py b/reviewboard/settings.py
index 466df5494afefde19d62ad8a5e51e2d7dee19a0f..4f99cfdf857733638dd6a57a153a6a4abb453114 100644
--- a/reviewboard/settings.py
+++ b/reviewboard/settings.py
@@ -156,6 +156,7 @@ RB_BUILTIN_APPS = [
     'djblets.gravatars',
     'djblets.log',
     'djblets.pipeline',
+    'djblets.recaptcha',
     'djblets.siteconfig',
     'djblets.util',
     'haystack',
diff --git a/reviewboard/static/rb/css/common.less b/reviewboard/static/rb/css/common.less
index fd522a047fea280e96a1cbaaf23a7c2abaf70325..e2c9fb222cfafec8b43a035cb394993bb15ff29e 100644
--- a/reviewboard/static/rb/css/common.less
+++ b/reviewboard/static/rb/css/common.less
@@ -363,14 +363,9 @@
   }
 }
 
-#auth_container #register_form {
-  .register-captcha-row {
-    padding-left: 0;
-
-    .register-captcha-container {
-      float: right;
-    }
-  }
+#auth_container .register-captcha-row {
+  float: right;
+  padding-left: 0;
 }
 
 
diff --git a/reviewboard/templates/accounts/register.html b/reviewboard/templates/accounts/register.html
index 4842279df950f3474c2bf3f9636c1701417a78ba..5ed37d062609d4fe7b8780f270e32851f1cea635 100644
--- a/reviewboard/templates/accounts/register.html
+++ b/reviewboard/templates/accounts/register.html
@@ -1,8 +1,15 @@
 {% extends "accounts/base.html" %}
-{% load djblets_deco djblets_extensions i18n %}
+{% load djblets_deco djblets_extensions djblets_recaptcha i18n %}
 
 {% block title %}{% trans "Register account" %}{% endblock %}
 
+{% block scripts %}
+{{block.super}}
+{%  if siteconfig_settings.auth_registration_show_captcha %}
+{% recaptcha_js %}
+{%  endif %}
+{% endblock scripts %}
+
 {% block auth_content %}
 {%  template_hook_point "before-register-form" %}
 
@@ -55,23 +62,7 @@
 
 {% if siteconfig_settings.auth_registration_show_captcha %}
  <div class="auth-form-row register-captcha-row clearfix">
-  <script>
-      var RecaptchaOptions = {
-          theme: 'white'
-      };
-  </script>
-  <div class="register-captcha-container">
-   <script type="text/javascript" src="{{form.recaptcha_url}}/challenge?k={{siteconfig_settings.recaptcha_public_key}}{{form.captcha_error_query_str}}"></script>
-
-   <noscript>
-    <iframe src="{{form.recaptcha_url}}/noscript?k={{siteconfig_settings.recaptcha_public_key}}{{form.captcha_error_query_str}}"
-            height="300" width="500" frameborder="0"></iframe>
-    <br />
-    <textarea name="recaptcha_challenge_field" rows="3" cols="40"></textarea>
-    <input type="hidden" name="recaptcha_response_field"
-           value="manual_challenge" />
-   </noscript>
-  </div>
+  {% recaptcha_form_field form %}
  </div>
 {% endif %}
 
diff --git a/setup.py b/setup.py
index f630f51f182d8ba8e9058f152e77fec0a5865295..fb19f5ae1ff86eb0426311f8cb7a754342bb0d45 100755
--- a/setup.py
+++ b/setup.py
@@ -211,7 +211,6 @@ setup(name=PACKAGE_NAME,
           'python-dateutil==1.5',
           'python-memcached',
           'pytz',
-          'recaptcha-client',
           'Whoosh>=2.6',
       ],
       dependency_links=[
