diff --git a/CHANGELOG.rst b/CHANGELOG.rst
index 4735f42..779f442 100644
--- a/CHANGELOG.rst
+++ b/CHANGELOG.rst
@@ -26,7 +26,7 @@ Deprecations:
 Changes:
 ^^^^^^^^
 
-*none*
+- You can now load encrypted PKCS#8 PEM key as ``pem.Key``.
 
 
 ----
diff --git a/CONTRIBUTING.rst b/CONTRIBUTING.rst
index dcabac2..57802b5 100644
--- a/CONTRIBUTING.rst
+++ b/CONTRIBUTING.rst
@@ -18,6 +18,8 @@ Workflow
   Whether you prefer to rebase on master or merge master into your branch, do whatever is more comfortable for you.
 - *Always* add tests and docs for your code.
   This is a hard rule; patches with missing tests or documentation can't be merged.
+- Consider updating CHANGELOG.rst to reflect the changes as observed by people
+  using this library.
 - Make sure your changes pass our CI_.
   You won't get any feedback until it's green unless you ask for it.
 - Once you've addressed review feedback, make sure to bump the pull request with a short note, so we know you're done.
diff --git a/setup.cfg b/setup.cfg
index b0a9418..8aac42a 100644
--- a/setup.cfg
+++ b/setup.cfg
@@ -24,4 +24,4 @@ multi_line_output=3
 not_skip=__init__.py
 
 known_first_party=pem
-known_third_party=OpenSSL,certifi,pem,pretend,pytest,setuptools,sphinx_rtd_theme,twisted
+known_third_party=OpenSSL,certifi,pem,pretend,pytest,setuptools,sphinx_rtd_theme,twisted,typing
diff --git a/src/pem/_core.py b/src/pem/_core.py
index 0acdce6..b3998d3 100644
--- a/src/pem/_core.py
+++ b/src/pem/_core.py
@@ -141,6 +141,7 @@ class DHParameters(AbstractPEMObject):
 _PEM_TO_CLASS = {
     b"CERTIFICATE": Certificate,
     b"PRIVATE KEY": Key,
+    b"ENCRYPTED PRIVATE KEY": Key,
     b"RSA PRIVATE KEY": RSAPrivateKey,
     b"DH PARAMETERS": DHParameters,
     b"NEW CERTIFICATE REQUEST": CertificateRequest,

diff --git a/tests/data.py b/tests/data.py
index 81f9b0f..5c82cc2 100644
--- a/tests/data.py
+++ b/tests/data.py
@@ -54,6 +54,75 @@ kjBF/mzooA==
 -----END RSA PRIVATE KEY-----
 """
 
+# KEY_PEM_PKCS8_* and KEY_PEM_PKCS5_* contain the same private key, but in
+# different formats.
+
+# PKCS#5 RSA unencrypted.
+# Generated with:
+# openssl genrsa -out private.pem 512
+KEY_PEM_PKCS5_UNENCRYPTED = b"""-----BEGIN RSA PRIVATE KEY-----
+MIIBOwIBAAJBAKX6cRhPHvdyoftEHGiRje3tTLRDnddg01AvgsJJcCFoIjwdgfa9
+aKFdzCcgD/htjvfRZl24M7E89sMUBMNHk8ECAwEAAQJABcBi8OO1AAAh6tIWZe09
+TNRfRxPcwVzilbG/xznCP/YMf72E8hsZazu+HGMKITg9dFeJOyjXZ4e8sD/pL/I6
+0QIhANzULu4JjJxpoTK8NnF/CemF7neLROA18NDB/mao5ZZtAiEAwGnYobinxuHS
+UQh8cT3w7aLsVlarZmCtoapxjW+ObiUCIQCcAltVV/G63vU/PrDH5hQ+opwiYIW8
+UN9c3HC6XkA00QIhAJ8YpfwKgAfNfyZrmuHTspv7Q+mb3jtXoxnyodOtsxpVAiBC
+a4FDqkr+bDwV4SwaGdG/AC40fR3P8hhOADAhtFDwlw==
+-----END RSA PRIVATE KEY-----
+"""
+
+# PKCS#5 RSA encrypted with `test` as password.
+# Generated with:
+# openssl genrsa -des3 -out private.pem 512
+KEY_PEM_PKCS5_ENCRYPTED = b"""-----BEGIN RSA PRIVATE KEY-----
+Proc-Type: 4,ENCRYPTED
+DEK-Info: DES-EDE3-CBC,8A72BD2DC1C9092F
+
+6LgvCNeXdcuTayEOKhQo2N4IveCP0S3t8xJCeihW9yizLeQFzSjqSfKtmRyImjfg
+fMl8IMDFozR+xVE9uWaIo98wKWpjyu6cytYyjL/8SP3jswBoSP5P9OekUSLifPWM
+ghUEu6tGissqSs/8i2wzLIdho3DdUnUMPZIprENmK6HrYmdRtJT3qMgkFTCtCS9Q
+r9oPm7xKPsfKBhaUHK51JcsPkPjrny8Dl56W0IYf/dfvRPwSr5yFQFLk6Nbgnx0N
+32aT3ZMRCEvOTxhX1cO3f5JqYLxFAGKBFwvsulTisJ6rGYOEDSMBDwZc3sqLvt5g
+h0vKRPqSkylQ0W5shNg0bwbxySiRxJPBL8kWDAbJVfauArabLPuNkUNwmYhIjy7j
+lY0oYw2xeJ9hTUly/Zg3+DI8oYYY3z7WaxPHXEoicCE=
+-----END RSA PRIVATE KEY-----
+"""
+
+# PKCS#8 RSA encrypted with `test` as password.
+# Generated with pkc5 as intermediate file:
+# openssl genrsa -des3 -out private.pem 512
+# openssl pkcs8 -topk8 -in private.pem
+KEY_PEM_PKCS8_ENCRYPTED = b"""-----BEGIN ENCRYPTED PRIVATE KEY-----
+MIIBvTBXBgkqhkiG9w0BBQ0wSjApBgkqhkiG9w0BBQwwHAQIyqwWErm7rlcCAggA
+MAwGCCqGSIb3DQIJBQAwHQYJYIZIAWUDBAEqBBAkVu+KRbmcfWIGKzgnjjBMBIIB
+YI3aRS0ebuzb1Tq26/HAq8pplPu+96dM1SnRNXwH0ijmP3fLBjEDH4hB/X9H8arT
+xWSfKQ80+FKI07DsLQKmO+cuB12MAWPSoCNBRtLwGUiwYvlMcBp6XR4NQQ+YG/Nw
+OgZ1InH2w7uSnDPdxV9dZculYWzJE82IohnFVZokO2nYSEfIqr1xVQZht6lfzpx2
+aRje42fpYfgkEm13w4oJKIlekzA9M4CeYku7Q4l9GDSHRmoeypMSHPI8RFV9pxub
+ME3AMXGcRioJ0Ic/cpmwqFaJbTVRPsqFVEsMCz1T/CQ4oLjPTWg+zkxfsPIyGj7L
+K3yLZmTA6IxSu+wuO/bsbqiM3x718AW6U0FHXd4zk+llu3mUfhTiMYPvN/cedv/M
+wsT85CHM6reIBopGMqeZD965tNEcWPGMEvXXnG71dxxgrfHFv7l/o8+moVRNIQCh
+EArlaXgT3MlI1jb9HoNvVNg=
+-----END ENCRYPTED PRIVATE KEY-----
+"""
+
+# RSA unencrypted
+# Generated with pkc5 as intermediate file:
+# openssl genrsa -des3 -out private.pem 512
+# openssl pkcs8 -topk8 -in private.pem -nocrypt
+KEY_PEM_PKCS8_UNENCRYPTED = b"""-----BEGIN PRIVATE KEY-----
+MIIBVQIBADANBgkqhkiG9w0BAQEFAASCAT8wggE7AgEAAkEApfpxGE8e93Kh+0Qc
+aJGN7e1MtEOd12DTUC+CwklwIWgiPB2B9r1ooV3MJyAP+G2O99FmXbgzsTz2wxQE
+w0eTwQIDAQABAkAFwGLw47UAACHq0hZl7T1M1F9HE9zBXOKVsb/HOcI/9gx/vYTy
+GxlrO74cYwohOD10V4k7KNdnh7ywP+kv8jrRAiEA3NQu7gmMnGmhMrw2cX8J6YXu
+d4tE4DXw0MH+Zqjllm0CIQDAadihuKfG4dJRCHxxPfDtouxWVqtmYK2hqnGNb45u
+JQIhAJwCW1VX8bre9T8+sMfmFD6inCJghbxQ31zccLpeQDTRAiEAnxil/AqAB81/
+Jmua4dOym/tD6ZveO1ejGfKh062zGlUCIEJrgUOqSv5sPBXhLBoZ0b8ALjR9Hc/y
+GE4AMCG0UPCX
+-----END PRIVATE KEY-----
+"""
+
+
 DH_PEM = b"""-----BEGIN DH PARAMETERS-----
 MIICCAKCAgEAj9/hwPNNKlQEANXqFBXViNy9nVpYlqIIHaLhoKdwAFzgYM+9hNSz
 FM/k+K5FS5dXrM63Zh9NgTI1M+ZRHJAxM2hhsG8AA333PN+c3exTRGwjQhU16XJg
diff --git a/tests/test_core.py b/tests/test_core.py
index 6e4349f..a9d5f17 100644
--- a/tests/test_core.py
+++ b/tests/test_core.py
@@ -6,6 +6,8 @@ from itertools import combinations
 
 import certifi
 
+from OpenSSL import crypto
+
 import pem
 
 from pem._compat import text_type
@@ -16,7 +18,10 @@ from .data import (
     CERT_PEMS_NO_NEW_LINE,
     CRL_PEMS,
     DH_PEM,
-    KEY_PEM,
+    KEY_PEM_PKCS5_ENCRYPTED,
+    KEY_PEM_PKCS5_UNENCRYPTED,
+    KEY_PEM_PKCS8_ENCRYPTED,
+    KEY_PEM_PKCS8_UNENCRYPTED,
 )
 
 
@@ -339,15 +344,76 @@ class TestPEMObjects(object):
 
 
 class TestParse(object):
-    def test_key(self):
+    """
+    Tests for parsing input with one or multiple PEM objects.
+    """
+
+    def test_key_pkcs5_unencrypted(self):
         """
-        Parses a PEM string with a key into an RSAPrivateKey.
+        It can load an unencrypted PKCS#5 RSA key as PEM string
+        as an RSAPrivateKey.
         """
-        rv = pem.parse(KEY_PEM)
+        rv = pem.parse(KEY_PEM_PKCS5_UNENCRYPTED)
         key, = rv
 
         assert isinstance(key, pem.RSAPrivateKey)
-        assert KEY_PEM == key.as_bytes()
+        assert KEY_PEM_PKCS5_UNENCRYPTED == key.as_bytes()
+
+        crypto_key = crypto.load_privatekey(
+            crypto.FILETYPE_PEM, key.as_bytes()
+        )
+        assert crypto.TYPE_RSA, crypto_key.type()
+        assert 512, crypto_key.bits()
+
+    def test_key_pkcs5_encrypted(self):
+        """
+        It can load an encrypted PKCS#5 RSA key as PEM string
+        as an RSAPrivateKey.
+        """
+        rv = pem.parse(KEY_PEM_PKCS5_ENCRYPTED)
+        key, = rv
+
+        assert isinstance(key, pem.RSAPrivateKey)
+        assert KEY_PEM_PKCS5_ENCRYPTED == key.as_bytes()
+
+        crypto_key = crypto.load_privatekey(
+            crypto.FILETYPE_PEM, key.as_bytes(), b"test"
+        )
+        assert crypto.TYPE_RSA, crypto_key.type()
+        assert 512, crypto_key.bits()
+
+    def test_key_pkcs8_unencrypted(self):
+        """
+        It can load an unencrypted PKCS#8 RSA key as PEM string
+        as an RSAPrivateKey.
+        """
+        rv = pem.parse(KEY_PEM_PKCS8_UNENCRYPTED)
+        key, = rv
+
+        assert isinstance(key, pem.Key)
+        assert KEY_PEM_PKCS8_UNENCRYPTED == key.as_bytes()
+
+        crypto_key = crypto.load_privatekey(
+            crypto.FILETYPE_PEM, key.as_bytes()
+        )
+        assert crypto.TYPE_RSA, crypto_key.type()
+        assert 512, crypto_key.bits()
+
+    def test_key_pkcs8_encrypted(self):
+        """
+        It can load an encrypted PKCS#8 RSA key as PEM string
+        as an RSAPrivateKey.
+        """
+        rv = pem.parse(KEY_PEM_PKCS8_ENCRYPTED)
+        key, = rv
+
+        assert isinstance(key, pem.Key)
+        assert KEY_PEM_PKCS8_ENCRYPTED == key.as_bytes()
+
+        crypto_key = crypto.load_privatekey(
+            crypto.FILETYPE_PEM, key.as_bytes(), b"test"
+        )
+        assert crypto.TYPE_RSA, crypto_key
 
     def test_certificates(self):
         """
@@ -423,7 +489,7 @@ class TestParse(object):
         """
         \n and \r\n are treated equal.
         """
-        lf_pem = KEY_PEM.replace(b"\n", b"\r\n")
+        lf_pem = KEY_PEM_PKCS5_UNENCRYPTED.replace(b"\n", b"\r\n")
         rv, = pem.parse(lf_pem)
 
         assert rv.as_bytes() == lf_pem

Add support for PCKS#8 encrypted `BEGIN ENCRYPTED PRIVATE KEY`
It looks like for now only `RSA PRIVATE KEY` is supported.

OpenSSL docs https://www.openssl.org/docs/man1.0.2/apps/openssl-pkcs8.html

A comparison

https://github.com/kjur/jsrsasign/wiki/Tutorial-for-PKCS5-and-PKCS8-PEM-private-key-formats-differences

--------

I will try to add a patch, but for now I have created this issue for reference
tests/test_core.py::TestParse::test_key_pkcs8_encrypted
tests/test_core.py::TestPEMObjects::test_cert_has_correct_repr tests/test_core.py::TestPEMObjects::test_cert_has_correct_str tests/test_core.py::TestPEMObjects::test_cert_req_has_correct_repr tests/test_core.py::TestPEMObjects::test_sha1_hexdigest tests/test_core.py::TestPEMObjects::test_as_text tests/test_core.py::TestPEMObjects::test_cert_req_has_correct_str tests/test_core.py::TestPEMObjects::test_key_has_correct_repr tests/test_core.py::TestPEMObjects::test_key_has_correct_str tests/test_core.py::TestPEMObjects::test_rsa_key_has_correct_repr tests/test_core.py::TestPEMObjects::test_rsa_key_has_correct_str tests/test_core.py::TestPEMObjects::test_dh_params_has_correct_repr tests/test_core.py::TestPEMObjects::test_dh_params_has_correct_str tests/test_core.py::TestPEMObjects::test_crl_has_correct_repr tests/test_core.py::TestPEMObjects::test_crl_has_correct_str tests/test_core.py::TestPEMObjects::test_certificate_unicode tests/test_core.py::TestPEMObjects::test_certificate_request_unicode tests/test_core.py::TestPEMObjects::test_key_unicode tests/test_core.py::TestPEMObjects::test_rsa_key_unicode tests/test_core.py::TestPEMObjects::test_dhparams_unicode_deprecated tests/test_core.py::TestPEMObjects::test_crl_unicode tests/test_core.py::TestPEMObjects::test_certs_equal tests/test_core.py::TestPEMObjects::test_cert_reqs_equal tests/test_core.py::TestPEMObjects::test_keys_equal tests/test_core.py::TestPEMObjects::test_rsa_keys_equal tests/test_core.py::TestPEMObjects::test_dh_params_equal tests/test_core.py::TestPEMObjects::test_crl_equal tests/test_core.py::TestPEMObjects::test_cert_contents_unequal tests/test_core.py::TestPEMObjects::test_cert_req_contents_unequal tests/test_core.py::TestPEMObjects::test_crl_unequal tests/test_core.py::TestPEMObjects::test_different_objects_unequal tests/test_core.py::TestPEMObjects::test_incompatible_types tests/test_core.py::TestParse::test_key_pkcs5_unencrypted tests/test_core.py::TestParse::test_key_pkcs5_encrypted tests/test_core.py::TestParse::test_key_pkcs8_unencrypted tests/test_core.py::TestParse::test_certificates tests/test_core.py::TestParse::test_certificate_no_new_line tests/test_core.py::TestParse::test_certificates_no_new_line tests/test_core.py::TestParse::test_dh tests/test_core.py::TestParse::test_crl tests/test_core.py::TestParse::test_file tests/test_core.py::TestParse::test_loads_certifi tests/test_core.py::TestParse::test_allows_lf