add AuthorityKeyIdentifier from_issuer_public_key

Refactored SKI's creation code into a separate function, added
doctest examples
diff --git a/docs/x509/reference.rst b/docs/x509/reference.rst
index dfa91fa..a05be16 100644
--- a/docs/x509/reference.rst
+++ b/docs/x509/reference.rst
@@ -1160,6 +1160,28 @@
 
         The serial number of the issuer's issuer.
 
+    .. classmethod:: from_issuer_public_key(public_key)
+
+        .. versionadded:: 1.0
+
+        Creates a new AuthorityKeyIdentifier instance using the public key
+        provided to generate the appropriate digest. This should be the
+        **issuer public key**. The resulting object will contain a
+        :attr:`~cryptography.x509.AuthorityKeyIdentifier.key_identifier`.
+        The generated digest is the SHA1 hash of the ``subjectPublicKey`` A
+        SN.1 bit string. This is the first recommendation in :rfc:`5280`
+        section 4.2.1.2.
+
+        :param certificate: The issuing :class:`~cryptography.x509.Certificate`.
+
+        .. doctest::
+
+            >>> from cryptography import x509
+            >>> from cryptography.hazmat.backends import default_backend
+            >>> cert = x509.load_pem_x509_certificate(pem_data, default_backend())
+            >>> x509.AuthorityKeyIdentifier.from_issuer_public_key(cert.public_key())
+            <AuthorityKeyIdentifier(key_identifier='X\x01\x84$\x1b\xbc+R\x94J=\xa5\x10r\x14Q\xf5\xaf:\xc9', authority_cert_issuer=None, authority_cert_serial_number=None)>
+
 .. class:: SubjectKeyIdentifier
 
     .. versionadded:: 0.9
@@ -1198,6 +1220,14 @@
             , or
             :class:`~cryptography.hazmat.primitives.asymmetric.ec.EllipticCurvePublicKey`.
 
+        .. doctest::
+
+            >>> from cryptography import x509
+            >>> from cryptography.hazmat.backends import default_backend
+            >>> cert = x509.load_pem_x509_certificate(pem_data, default_backend())
+            >>> x509.SubjectKeyIdentifier.from_public_key(cert.public_key())
+            <SubjectKeyIdentifier(digest='X\x01\x84$\x1b\xbc+R\x94J=\xa5\x10r\x14Q\xf5\xaf:\xc9')>
+
 .. class:: SubjectAlternativeName
 
     .. versionadded:: 0.9
diff --git a/src/cryptography/x509.py b/src/cryptography/x509.py
index 5ed3c09..3f306e3 100644
--- a/src/cryptography/x509.py
+++ b/src/cryptography/x509.py
@@ -32,6 +32,27 @@
     )
 
 
+def _key_identifier_from_public_key(public_key):
+    # This is a very slow way to do this.
+    serialized = public_key.public_bytes(
+        serialization.Encoding.DER,
+        serialization.PublicFormat.SubjectPublicKeyInfo
+    )
+    spki, remaining = decoder.decode(
+        serialized, asn1Spec=_SubjectPublicKeyInfo()
+    )
+    # the univ.BitString object is a tuple of bits. We need bytes and
+    # pyasn1 really doesn't want to give them to us. To get it we'll
+    # build an integer and convert that to bytes.
+    assert not remaining
+    bits = 0
+    for bit in spki.getComponentByName("subjectPublicKey"):
+        bits = bits << 1 | bit
+
+    data = utils.int_to_bytes(bits)
+    return hashlib.sha1(data).digest()
+
+
 _OID_NAMES = {
     "2.5.4.3": "commonName",
     "2.5.4.6": "countryName",
@@ -710,24 +731,7 @@
 
     @classmethod
     def from_public_key(cls, public_key):
-        # This is a very slow way to do this.
-        serialized = public_key.public_bytes(
-            serialization.Encoding.DER,
-            serialization.PublicFormat.SubjectPublicKeyInfo
-        )
-        spki, remaining = decoder.decode(
-            serialized, asn1Spec=_SubjectPublicKeyInfo()
-        )
-        assert not remaining
-        # the univ.BitString object is a tuple of bits. We need bytes and
-        # pyasn1 really doesn't want to give them to us. To get it we'll
-        # build an integer and convert that to bytes.
-        bits = 0
-        for bit in spki.getComponentByName("subjectPublicKey"):
-            bits = bits << 1 | bit
-
-        data = utils.int_to_bytes(bits)
-        return cls(hashlib.sha1(data).digest())
+        return cls(_key_identifier_from_public_key(public_key))
 
     digest = utils.read_only_property("_digest")
 
@@ -1318,6 +1322,15 @@
         self._authority_cert_issuer = authority_cert_issuer
         self._authority_cert_serial_number = authority_cert_serial_number
 
+    @classmethod
+    def from_issuer_public_key(cls, public_key):
+        digest = _key_identifier_from_public_key(public_key)
+        return cls(
+            key_identifier=digest,
+            authority_cert_issuer=None,
+            authority_cert_serial_number=None
+        )
+
     def __repr__(self):
         return (
             "<AuthorityKeyIdentifier(key_identifier={0.key_identifier!r}, "
diff --git a/tests/test_x509_ext.py b/tests/test_x509_ext.py
index 73cdfc5..40231b9 100644
--- a/tests/test_x509_ext.py
+++ b/tests/test_x509_ext.py
@@ -2112,6 +2112,25 @@
         ]
         assert ext.value.authority_cert_serial_number == 3
 
+    def test_from_certificate(self, backend):
+        issuer_cert = _load_cert(
+            os.path.join("x509", "rapidssl_sha256_ca_g3.pem"),
+            x509.load_pem_x509_certificate,
+            backend
+        )
+        cert = _load_cert(
+            os.path.join("x509", "cryptography.io.pem"),
+            x509.load_pem_x509_certificate,
+            backend
+        )
+        ext = cert.extensions.get_extension_for_oid(
+            x509.OID_AUTHORITY_KEY_IDENTIFIER
+        )
+        aki = x509.AuthorityKeyIdentifier.from_issuer_public_key(
+            issuer_cert.public_key()
+        )
+        assert ext.value == aki
+
 
 class TestNameConstraints(object):
     def test_ipaddress_wrong_type(self):