diff --git a/docs/development/test-vectors.rst b/docs/development/test-vectors.rst
index 3a820004c384bd9b89cca4efb4d128e7b37368c9_ZG9jcy9kZXZlbG9wbWVudC90ZXN0LXZlY3RvcnMucnN0..23d01ba79fc6415cc3deb10f496fff646c16486e_ZG9jcy9kZXZlbG9wbWVudC90ZXN0LXZlY3RvcnMucnN0 100644
--- a/docs/development/test-vectors.rst
+++ b/docs/development/test-vectors.rst
@@ -78,6 +78,8 @@
 * ``asymmetric/PEM_Serialization/rsa_public_key.pem`` and
   ``asymmetric/DER_Serialization/rsa_public_key.der``- Contains an RSA 2048
   bit public generated using OpenSSL from ``rsa_private_key.pem``.
+* ``asymmetric/PEM_Serialization/dsa_4096.pem`` - Contains a 4096-bit DSA
+  private key generated using OpenSSL.
 * ``asymmetric/PEM_Serialization/dsaparam.pem`` - Contains 2048-bit DSA
   parameters generated using OpenSSL; contains no keys.
 * ``asymmetric/PEM_Serialization/dsa_private_key.pem`` - Contains a DSA 2048
diff --git a/docs/hazmat/primitives/asymmetric/dsa.rst b/docs/hazmat/primitives/asymmetric/dsa.rst
index 3a820004c384bd9b89cca4efb4d128e7b37368c9_ZG9jcy9oYXptYXQvcHJpbWl0aXZlcy9hc3ltbWV0cmljL2RzYS5yc3Q=..23d01ba79fc6415cc3deb10f496fff646c16486e_ZG9jcy9oYXptYXQvcHJpbWl0aXZlcy9hc3ltbWV0cmljL2RzYS5yc3Q= 100644
--- a/docs/hazmat/primitives/asymmetric/dsa.rst
+++ b/docs/hazmat/primitives/asymmetric/dsa.rst
@@ -5,6 +5,13 @@
 
 .. module:: cryptography.hazmat.primitives.asymmetric.dsa
 
+.. note::
+
+    DSA is a **legacy algorithm** and should generally be avoided in favor of
+    choices like
+    :doc:`EdDSA using curve25519</hazmat/primitives/asymmetric/ed25519>` or
+    :doc:`ECDSA</hazmat/primitives/asymmetric/ec>`.
+
 `DSA`_ is a `public-key`_ algorithm for signing messages.
 
 Generation
@@ -14,7 +21,13 @@
 
     .. versionadded:: 0.5
 
+    .. versionchanged:: 3.0
+
+        Added support for 4096-bit keys for some legacy applications that
+        continue to use DSA despite the wider cryptographic community's
+        `ongoing protestations`_.
+
     Generate a DSA private key from the given key size. This function will
     generate a new set of parameters and key in one step.
 
     :param int key_size: The length of the modulus in :term:`bits`. It should
@@ -17,12 +30,9 @@
     Generate a DSA private key from the given key size. This function will
     generate a new set of parameters and key in one step.
 
     :param int key_size: The length of the modulus in :term:`bits`. It should
-        be either 1024, 2048 or 3072. For keys generated in 2015 this should
-        be `at least 2048`_ (See page 41).  Note that some applications
-        (such as SSH) have not yet gained support for larger key sizes
-        specified in FIPS 186-3 and are still restricted to only the
-        1024-bit keys specified in FIPS 186-2.
+        be either 1024, 2048, 3072, or 4096. For keys generated in 2015 this
+        should be `at least 2048`_ (See page 41).
 
     :param backend: An instance of
         :class:`~cryptography.hazmat.backends.interfaces.DSABackend`.
@@ -38,6 +48,12 @@
 
     .. versionadded:: 0.5
 
+    .. versionchanged:: 3.0
+
+        Added support for 4096-bit keys for some legacy applications that
+        continue to use DSA despite the wider cryptographic community's
+        `ongoing protestations`_.
+
     Generate DSA parameters using the provided ``backend``.
 
     :param int key_size: The length of :attr:`~DSAParameterNumbers.q`. It
@@ -41,11 +57,8 @@
     Generate DSA parameters using the provided ``backend``.
 
     :param int key_size: The length of :attr:`~DSAParameterNumbers.q`. It
-        should be either 1024, 2048 or 3072. For keys generated in 2015 this
-        should be `at least 2048`_ (See page 41).  Note that some applications
-        (such as SSH) have not yet gained support for larger key sizes
-        specified in FIPS 186-3 and are still restricted to only the
-        1024-bit keys specified in FIPS 186-2.
+        should be either 1024, 2048, 3072, or 4096. For keys generated in 2015
+        this should be `at least 2048`_ (See page 41).
 
     :param backend: An instance of
         :class:`~cryptography.hazmat.backends.interfaces.DSABackend`.
@@ -446,3 +459,4 @@
 .. _`public-key`: https://en.wikipedia.org/wiki/Public-key_cryptography
 .. _`FIPS 186-4`: https://csrc.nist.gov/publications/detail/fips/186/4/final
 .. _`at least 2048`: https://www.cosic.esat.kuleuven.be/ecrypt/ecrypt2/documents/D.SPA.20.pdf
+.. _`ongoing protestations`: https://buttondown.email/cryptography-dispatches/archive/cryptography-dispatches-dsa-is-past-its-prime/
diff --git a/src/cryptography/hazmat/backends/openssl/backend.py b/src/cryptography/hazmat/backends/openssl/backend.py
index 3a820004c384bd9b89cca4efb4d128e7b37368c9_c3JjL2NyeXB0b2dyYXBoeS9oYXptYXQvYmFja2VuZHMvb3BlbnNzbC9iYWNrZW5kLnB5..23d01ba79fc6415cc3deb10f496fff646c16486e_c3JjL2NyeXB0b2dyYXBoeS9oYXptYXQvYmFja2VuZHMvb3BlbnNzbC9iYWNrZW5kLnB5 100644
--- a/src/cryptography/hazmat/backends/openssl/backend.py
+++ b/src/cryptography/hazmat/backends/openssl/backend.py
@@ -626,8 +626,10 @@
             return False
 
     def generate_dsa_parameters(self, key_size):
-        if key_size not in (1024, 2048, 3072):
-            raise ValueError("Key size must be 1024 or 2048 or 3072 bits.")
+        if key_size not in (1024, 2048, 3072, 4096):
+            raise ValueError(
+                "Key size must be 1024, 2048, 3072, or 4096 bits."
+            )
 
         ctx = self._lib.DSA_new()
         self.openssl_assert(ctx != self._ffi.NULL)
diff --git a/src/cryptography/hazmat/primitives/asymmetric/dsa.py b/src/cryptography/hazmat/primitives/asymmetric/dsa.py
index 3a820004c384bd9b89cca4efb4d128e7b37368c9_c3JjL2NyeXB0b2dyYXBoeS9oYXptYXQvcHJpbWl0aXZlcy9hc3ltbWV0cmljL2RzYS5weQ==..23d01ba79fc6415cc3deb10f496fff646c16486e_c3JjL2NyeXB0b2dyYXBoeS9oYXptYXQvcHJpbWl0aXZlcy9hc3ltbWV0cmljL2RzYS5weQ== 100644
--- a/src/cryptography/hazmat/primitives/asymmetric/dsa.py
+++ b/src/cryptography/hazmat/primitives/asymmetric/dsa.py
@@ -128,8 +128,10 @@
 
 
 def _check_dsa_parameters(parameters):
-    if parameters.p.bit_length() not in [1024, 2048, 3072]:
-        raise ValueError("p must be exactly 1024, 2048, or 3072 bits long")
+    if parameters.p.bit_length() not in [1024, 2048, 3072, 4096]:
+        raise ValueError(
+            "p must be exactly 1024, 2048, 3072, or 4096 bits long"
+        )
     if parameters.q.bit_length() not in [160, 224, 256]:
         raise ValueError("q must be exactly 160, 224, or 256 bits long")
 
diff --git a/tests/hazmat/primitives/test_dsa.py b/tests/hazmat/primitives/test_dsa.py
index 3a820004c384bd9b89cca4efb4d128e7b37368c9_dGVzdHMvaGF6bWF0L3ByaW1pdGl2ZXMvdGVzdF9kc2EucHk=..23d01ba79fc6415cc3deb10f496fff646c16486e_dGVzdHMvaGF6bWF0L3ByaW1pdGl2ZXMvdGVzdF9kc2EucHk= 100644
--- a/tests/hazmat/primitives/test_dsa.py
+++ b/tests/hazmat/primitives/test_dsa.py
@@ -349,6 +349,28 @@
                 y=y
             ).public_key(backend)
 
+    def test_large_p(self, backend):
+        key = load_vectors_from_file(
+            os.path.join("asymmetric", "PEM_Serialization", "dsa_4096.pem"),
+            lambda pemfile: serialization.load_pem_private_key(
+                pemfile.read(), None, backend
+            ), mode="rb"
+        )
+        pn = key.private_numbers()
+        assert pn.public_numbers.parameter_numbers.p.bit_length() == 4096
+        # Turn it back into a key to confirm that values this large pass
+        # verification
+        dsa.DSAPrivateNumbers(
+            public_numbers=dsa.DSAPublicNumbers(
+                parameter_numbers=dsa.DSAParameterNumbers(
+                    p=pn.public_numbers.parameter_numbers.p,
+                    q=pn.public_numbers.parameter_numbers.q,
+                    g=pn.public_numbers.parameter_numbers.g,
+                ),
+                y=pn.public_numbers.y
+            ), x=pn.x
+        ).private_key(backend)
+
 
 @pytest.mark.requires_backend_interface(interface=DSABackend)
 class TestDSAVerification(object):
diff --git a/vectors/cryptography_vectors/asymmetric/PEM_Serialization/dsa_4096.pem b/vectors/cryptography_vectors/asymmetric/PEM_Serialization/dsa_4096.pem
new file mode 100644
index 0000000000000000000000000000000000000000..23d01ba79fc6415cc3deb10f496fff646c16486e_dmVjdG9ycy9jcnlwdG9ncmFwaHlfdmVjdG9ycy9hc3ltbWV0cmljL1BFTV9TZXJpYWxpemF0aW9uL2RzYV80MDk2LnBlbQ==
--- /dev/null
+++ b/vectors/cryptography_vectors/asymmetric/PEM_Serialization/dsa_4096.pem
@@ -0,0 +1,36 @@
+-----BEGIN DSA PRIVATE KEY-----
+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
+-----END DSA PRIVATE KEY-----