def public_pem(self):
"""
Returns the public key PEM. This is a base64 format with delimiters.
This function returns None if the public pem information could
not be acquired.
"""
if not isinstance(self.public_key, RSAPublicKey):
if not isinstance(self.private_key, RSAPrivateKey):
return None
self.public_key = self.private_key.public_key()
return self.public_key.public_bytes(
encoding=serialization.Encoding.PEM,
format=serialization.PublicFormat.SubjectPublicKeyInfo,
)
python类RSAPrivateKey()的实例源码
def fields_to_partial_json(self):
# pylint: disable=protected-access
if isinstance(self.key._wrapped, rsa.RSAPublicKey):
numbers = self.key.public_numbers()
params = {
'n': numbers.n,
'e': numbers.e,
}
else: # rsa.RSAPrivateKey
private = self.key.private_numbers()
public = self.key.public_key().public_numbers()
params = {
'n': public.n,
'e': public.e,
'd': private.d,
'p': private.p,
'q': private.q,
'dp': private.dmp1,
'dq': private.dmq1,
'qi': private.iqmp,
}
return dict((key, self._encode_param(value))
for key, value in six.iteritems(params))
def from_cryptography_key(cls, crypto_key):
"""
Construct based on a ``cryptography`` *crypto_key*.
:param crypto_key: A ``cryptography`` key.
:type crypto_key: One of ``cryptography``'s `key interfaces`_.
:rtype: PKey
.. versionadded:: 16.1.0
"""
pkey = cls()
if not isinstance(crypto_key, (rsa.RSAPublicKey, rsa.RSAPrivateKey,
dsa.DSAPublicKey, dsa.DSAPrivateKey)):
raise TypeError("Unsupported key type")
pkey._pkey = crypto_key._evp_pkey
if isinstance(crypto_key, (rsa.RSAPublicKey, dsa.DSAPublicKey)):
pkey._only_public = True
pkey._initialized = True
return pkey
def from_cryptography_key(cls, crypto_key):
"""
Construct based on a ``cryptography`` *crypto_key*.
:param crypto_key: A ``cryptography`` key.
:type crypto_key: One of ``cryptography``'s `key interfaces`_.
:rtype: PKey
.. versionadded:: 16.1.0
"""
pkey = cls()
if not isinstance(crypto_key, (rsa.RSAPublicKey, rsa.RSAPrivateKey,
dsa.DSAPublicKey, dsa.DSAPrivateKey)):
raise TypeError("Unsupported key type")
pkey._pkey = crypto_key._evp_pkey
if isinstance(crypto_key, (rsa.RSAPublicKey, dsa.DSAPublicKey)):
pkey._only_public = True
pkey._initialized = True
return pkey
def from_cryptography_key(cls, crypto_key):
"""
Construct based on a ``cryptography`` *crypto_key*.
:param crypto_key: A ``cryptography`` key.
:type crypto_key: One of ``cryptography``'s `key interfaces`_.
:rtype: PKey
.. versionadded:: 16.1.0
"""
pkey = cls()
if not isinstance(crypto_key, (rsa.RSAPublicKey, rsa.RSAPrivateKey,
dsa.DSAPublicKey, dsa.DSAPrivateKey)):
raise TypeError("Unsupported key type")
pkey._pkey = crypto_key._evp_pkey
if isinstance(crypto_key, (rsa.RSAPublicKey, dsa.DSAPublicKey)):
pkey._only_public = True
pkey._initialized = True
return pkey
def display_item_info(item, filename, print_filename=False):
if print_filename is True:
print("#######[ {} ]#######".format(filename))
if (isinstance(item, rsa.RSAPrivateKey) or
isinstance(item, dsa.DSAPrivateKey) or
isinstance(item, ec.EllipticCurvePrivateKey)):
display_private_key(item)
elif (isinstance(item, rsa.RSAPublicKey) or
isinstance(item, dsa.DSAPublicKey) or
isinstance(item, ec.EllipticCurvePublicKey)):
display_public_key(item)
elif isinstance(item, OpenSSL.crypto.PKCS12):
display_pkcs12(item)
elif isinstance(item, OpenSSL.crypto.PKCS7):
display_pkcs7(item)
elif isinstance(item, Certificate):
display_x509_cert(item)
def fields_to_partial_json(self):
# pylint: disable=protected-access
if isinstance(self.key._wrapped, rsa.RSAPublicKey):
numbers = self.key.public_numbers()
params = {
'n': numbers.n,
'e': numbers.e,
}
else: # rsa.RSAPrivateKey
private = self.key.private_numbers()
public = self.key.public_key().public_numbers()
params = {
'n': public.n,
'e': public.e,
'd': private.d,
'p': private.p,
'q': private.q,
'dp': private.dmp1,
'dq': private.dmq1,
'qi': private.iqmp,
}
return dict((key, self._encode_param(value))
for key, value in six.iteritems(params))
def decode_pem_key(key_pem):
"""Convert plaintext PEM key into the format usable for JWT generation
Args:
key_pam (str): key data in PEM format, presented as plain string
Returns:
Parsed PEM data
"""
private_key = serialization.load_pem_private_key(
data=key_pem.encode('ascii'),
password=None,
backend=default_backend())
msg = 'Unexpected private key type'
assert isinstance(private_key, rsa.RSAPrivateKey), msg
assert private_key.key_size >= 2048, 'RSA key size too small'
return private_key
def rsa_key_fingerprint(key):
""" Return the SHA256 fingerprint of an RSA public or private key in url safe BASE64 """
fp = hashes.Hash(algorithm=hashes.SHA256(), backend=default_backend())
if isinstance(key, rsa.RSAPrivateKey):
fp.update(key.private_bytes(
encoding=serialization.Encoding.DER,
format=serialization.PrivateFormat.PKCS8,
encryption_algorithm=serialization.NoEncryption()
))
elif isinstance(key, rsa.RSAPublicKey):
fp.update(key.public_bytes(
encoding=serialization.Encoding.DER,
format=serialization.PublicFormat.PKCS1
))
return urlsafe_b64encode(fp.finalize()).decode()
def dump_pem(key_or_crt):
if isinstance(key_or_crt, rsa.RSAPrivateKey):
return key_or_crt.private_bytes(
encoding=serialization.Encoding.PEM,
format=serialization.PrivateFormat.PKCS8,
encryption_algorithm=serialization.NoEncryption()
)
elif isinstance(key_or_crt, rsa.RSAPublicKey):
return key_or_crt.public_bytes(
encoding=serialization.Encoding.DER,
format=serialization.PublicFormat.PKCS1
)
else:
return key_or_crt.public_bytes(
encoding=serialization.Encoding.PEM
)
def __save(self, private_key, file_name):
if not isinstance(private_key, RSAPrivateKey):
raise TypeError("private_key must be an instance of RSAPrivateKey, "
"actual: {}".format(type(private_key).__name__))
pem = private_key.private_bytes(
serialization.Encoding.PEM,
serialization.PrivateFormat.PKCS8,
serialization.BestAvailableEncryption(self.__key_store_passphrase))
file_path = os.path.join(self.key_store_path, file_name)
if not os.path.isdir(self.key_store_path):
os.makedirs(self.key_store_path)
if os.path.isfile(file_path):
msg = "Save failed: A key with name [{}] already exists".format(
file_name)
raise IOError(msg)
with open(file_path, 'w') as f:
f.write(pem.decode(encoding='utf8'))
def decrypt_with_private_key(secret_key, private_encryption_key):
"""
Decrypts the given secret key with the private key.
:param bytes secret_key: the secret key to decrypt
:param private_encryption_key: the private encryption key
:type private_encryption_key: :class:`~rsa.RSAPrivateKey`
:return: the decrypted key
:rtype: bytes
"""
return private_encryption_key.decrypt(
secret_key,
padding.OAEP(
mgf=padding.MGF1(algorithm=hashes.SHA256()),
algorithm=hashes.SHA256(),
label=None))
def verify_ssh_sig(self, data, msg):
if msg.get_text() != 'ssh-rsa':
return False
key = self.key
if isinstance(key, rsa.RSAPrivateKey):
key = key.public_key()
verifier = key.verifier(
signature=msg.get_binary(),
padding=padding.PKCS1v15(),
algorithm=hashes.SHA1(),
)
verifier.update(data)
try:
verifier.verify()
except InvalidSignature:
return False
else:
return True
def type(self):
"""
Return the type of the object we wrap. Currently this can only be
'RSA', 'DSA', or 'EC'.
@rtype: L{str}
@raises RuntimeError: If the object type is unknown.
"""
if isinstance(
self._keyObject, (rsa.RSAPublicKey, rsa.RSAPrivateKey)):
return 'RSA'
elif isinstance(
self._keyObject, (dsa.DSAPublicKey, dsa.DSAPrivateKey)):
return 'DSA'
elif isinstance(
self._keyObject, (ec.EllipticCurvePublicKey, ec.EllipticCurvePrivateKey)):
return 'EC'
else:
raise RuntimeError(
'unknown type of object: %r' % (self._keyObject,))
def verify_ssh_sig(self, data, msg):
if msg.get_text() != 'ssh-rsa':
return False
key = self.key
if isinstance(key, rsa.RSAPrivateKey):
key = key.public_key()
verifier = key.verifier(
signature=msg.get_binary(),
padding=padding.PKCS1v15(),
algorithm=hashes.SHA1(),
)
verifier.update(data)
try:
verifier.verify()
except InvalidSignature:
return False
else:
return True
def verify_ssh_sig(self, data, msg):
if msg.get_text() != 'ssh-rsa':
return False
key = self.key
if isinstance(key, rsa.RSAPrivateKey):
key = key.public_key()
verifier = key.verifier(
signature=msg.get_binary(),
padding=padding.PKCS1v15(),
algorithm=hashes.SHA1(),
)
verifier.update(data)
try:
verifier.verify()
except InvalidSignature:
return False
else:
return True
def pkey_from_cryptography_key(crypto_key):
'''
Modified version of `OpenSSL.crypto.PKey.from_cryptography_key()` of
PyOpenSSL which also accepts EC Keys
(cf. https://github.com/pyca/pyopenssl/pull/636).
'''
pkey = PKey()
if not isinstance(crypto_key, (rsa.RSAPublicKey, rsa.RSAPrivateKey,
dsa.DSAPublicKey, dsa.DSAPrivateKey,
ec.EllipticCurvePublicKey,
ec.EllipticCurvePrivateKey)):
raise TypeError("Unsupported key type")
pkey._pkey = crypto_key._evp_pkey
if isinstance(crypto_key, (rsa.RSAPublicKey, dsa.DSAPublicKey,
ec.EllipticCurvePublicKey)):
pkey._only_public = True
pkey._initialized = True
return pkey
def verify_ssh_sig(self, data, msg):
if msg.get_text() != 'ssh-rsa':
return False
key = self.key
if isinstance(key, rsa.RSAPrivateKey):
key = key.public_key()
verifier = key.verifier(
signature=msg.get_binary(),
padding=padding.PKCS1v15(),
algorithm=hashes.SHA1(),
)
verifier.update(data)
try:
verifier.verify()
except InvalidSignature:
return False
else:
return True
def genkeys(self, key_size=KeySize.NORMAL, password=None):
"""
Generates a Private and Public Key set and returns them in a tuple
(private, public)
"""
self.private_key = rsa.generate_private_key(
# The public exponent of the new key. Usually one of the small
# Fermat primes 3, 5, 17, 257, 65537. If in doubt you should use
# 65537. See http://www.daemonology.net/blog/2009-06-11-\
# cryptographic-right-answers.html
public_exponent=65537,
key_size=key_size,
backend=default_backend()
)
# Generate our Public Key
self.public_key = self.private_key.public_key()
# Store our password; this will be used when we save our content
# via it's searialized value later on
self.password = password
# Returns a (RSAPrivateKey, RSAPublicKey)
return (self.private_key, self.public_key)
def private_pem(self, password=None):
"""
Returns the private key PEM. This is a base64 format with delimiters.
This function returns None if the private pem information could
not be acquired.
"""
if not isinstance(self.private_key, RSAPrivateKey):
return None
if password is None:
password = self.password
if password:
return self.private_key.private_bytes(
encoding=serialization.Encoding.PEM,
format=serialization.PrivateFormat.PKCS8,
encryption_algorithm=serialization
.BestAvailableEncryption(password)
)
return self.private_key.private_bytes(
encoding=serialization.Encoding.PEM,
format=serialization.PrivateFormat.TraditionalOpenSSL,
encryption_algorithm=serialization.NoEncryption(),
)
def calculate_max_pss_salt_length(key, hash_algorithm):
if not isinstance(key, (rsa.RSAPrivateKey, rsa.RSAPublicKey)):
raise TypeError("key must be an RSA public or private key")
# bit length - 1 per RFC 3447
emlen = int(math.ceil((key.key_size - 1) / 8.0))
salt_length = emlen - hash_algorithm.digest_size - 2
assert salt_length >= 0
return salt_length
def test_convert_private_pkey_to_cryptography_key(self):
"""
PKey.to_cryptography_key creates a proper cryptography private key.
"""
pkey = load_privatekey(FILETYPE_PEM, cleartextPrivateKeyPEM)
key = pkey.to_cryptography_key()
assert isinstance(key, rsa.RSAPrivateKey)
assert pkey.bits() == key.key_size
def display_private_key(privkey):
if isinstance(privkey, rsa.RSAPrivateKey):
display_rsa_private_key(privkey)
elif isinstance(privkey, dsa.DSAPrivateKey):
display_dsa_private_key(privkey)
elif isinstance(privkey, ec.EllipticCurvePrivateKey):
display_ec_private_key(privkey)
else:
raise ValueError("Unknown private key type")
def get_private_key_label(pkey):
if isinstance(pkey, rsa.RSAPrivateKey):
return "RSA Private Key"
elif isinstance(pkey, dsa.DSAPrivateKey):
return "DSA Private Key"
elif isinstance(pkey, ec.EllipticCurvePrivateKey):
return "Elliptic Curve Private Key"
return None
def validate_privkey(value):
if isinstance(value, RSAPrivateKey) and value.key_size >= 4096:
return True
raise TypeError('Invalid private key')
def test_generate_rsa_key_success(self):
''' generate_rsa_key should return a RSAPrivateKey object with size 4096 '''
privkey=crypto.generate_rsa_key()
self.assertTrue(isinstance(privkey, rsa.RSAPrivateKey))
self.assertEqual(privkey.key_size, 4096)
def store_keys(self,
identity_id,
private_signing_key,
private_encryption_key):
"""
Stores the signing and encryption key pairs under a given identity id.
:param str identity_id: the identity id of the key owner
:param private_signing_key: the private signing key object
:type private_signing_key: :class:`RSAPrivateKey`
:param private_encryption_key: the private cryptographic key object
:type private_encryption_key: :class:`RSAPrivateKey`
"""
def __load(self, file_name):
# type: (str) -> RSAPrivateKey
file_path = os.path.join(self.key_store_path, file_name)
with(open(file_path, 'r')) as f:
return serialization.load_pem_private_key(
f.read().encode('utf-8'),
password=self.__key_store_passphrase,
backend=default_backend())
def generate_private_key():
"""
Generates a :class:`~rsa.RSAPrivateKey` object. The public key object can be
extracted by calling public_key() method on the generated key object.
:return: the generated private key object
:rtype: :class:`~rsa.RSAPrivateKey`
"""
return rsa.generate_private_key(public_exponent=65537,
key_size=4096,
backend=default_backend())
def key2bytes():
def convert(key):
if isinstance(key, rsa.RSAPrivateKey):
return key.private_bytes(
encoding=serialization.Encoding.PEM,
format=serialization.PrivateFormat.PKCS8,
encryption_algorithm=serialization.NoEncryption())
elif isinstance(key, rsa.RSAPublicKey):
der = key.public_bytes(
encoding=serialization.Encoding.DER,
format=serialization.PublicFormat.SubjectPublicKeyInfo)
return base64.b64encode(der).decode(encoding='utf-8')
return convert