def test_domain1(self): """Verify we can generate new keys in a given domain""" dsa_key_1 = DSA.generate(1024) domain_params = dsa_key_1.domain() dsa_key_2 = DSA.generate(1024, domain=domain_params) self.assertEqual(dsa_key_1.p, dsa_key_2.p) self.assertEqual(dsa_key_1.q, dsa_key_2.q) self.assertEqual(dsa_key_1.g, dsa_key_2.g) self.assertEqual(dsa_key_1.domain(), dsa_key_2.domain())
def test_nonce_reuse(secret_key=DSA.generate(1024)): # choose a "random" - k :) this time random is static in order to allow this attack to work k = random.StrongRandom().randint(1, secret_key.q - 1) # sign two messages using the same k samples = (TestDsa._sign_message(secret_key, b"This is a signed message!", k), TestDsa._sign_message(secret_key, b"Another signed Message - :)", k)) signatures = [ DsaSignature(sig, h, pubkey) for h, sig, pubkey in samples ] two_sigs = [] for sig in signatures: two_sigs.append(sig) if not len(two_sigs) == 2: continue sample = two_sigs.pop(0) print("%r - recovering privatekey from nonce reuse..." % sample) assert (sample.x is None) # not yet resolved sample.recover_nonce_reuse(two_sigs[0]) assert (sample.x is not None) # privkey recovered assert (sample.privkey == secret_key) print("%r - Private key recovered! \n%s" % (sample, sample.export_key()))
def generate_keys(key_type, key_scope, key_format='der'): """ generates private and public keys: - key_type designates the type of the key: 'rsa', 'dsa', 'ecc' - key_format designates the key representation 'der' or 'pem' - key_scope designates the scope of the key: 'sig', 'enc' -- this is mostly for naming convention output files are: key-<key_type>-<key_scope>-{pkcs8,asn1}.<key_format> """ pbl, prv = get_key_files(key_type, key_scope, key_format=key_format) if key_format == 'der': key_format = 'DER' if key_format == 'pem': key_format = 'PEM' if key_type == 'rsa': key = RSA.generate(2048) bytes_prv = key.exportKey(key_format, pkcs=8) bytes_pbl = key.publickey().exportKey(key_format) elif key_type == 'dsa': key = DSA.generate(2048) bytes_prv = key.exportKey(key_format, pkcs8=True) bytes_pbl = key.publickey().exportKey(key_format) elif key_type == 'ecc': key = ECC.generate(curve='P-256') bytes_prv = key.export_key(format=key_format, use_pkcs8=True) bytes_pbl = key.public_key().export_key(format=key_format) else: raise ImplementationError(key_type, "Unknown key type") with open(prv, 'wb') as f: f.write(bytes_prv) with open(pbl, 'wb') as f: f.write(bytes_pbl)
def create_dsa_keys(code): key = DSA.generate(1024) encrypted_key = key.exportKey( passphrase=code, pkcs8=True, protection="PBKDF2WithHMAC-SHA1AndDES-EDE3-CBC" ) with open("private_dsa_key.bin", "wb") as f: f.write(encrypted_key) with open("my_dsa_public.pem", "wb") as f: f.write(key.publickey().exportKey()) return key.publickey().exportKey()
def DSA_3072(file_name): print() print('DSA 3072 for ' + file_name + ': ') #KEY GENERATION t1 = datetime.now() key = DSA.generate(3072) t2 = datetime.now() key_speed = t2 - t1 print('TIME TAKEN FOR KEY GENERATION:(micro seconds) ' + str(key_speed.microseconds)) f = open("DSA3072_CSE565.pem", "wb") f.write(key.publickey().export_key()) f.close() #SIGNING with open(file_name + ".txt", "r") as myfile: data = myfile.read() plaintext = bytes(data, 'utf-8') hash_gen = SHA256.new(plaintext) signer = DSS.new(key, 'fips-186-3') t1 = datetime.now() signature = signer.sign(hash_gen) t2 = datetime.now() sign_time = t2 - t1 print('TIME TAKEN TO SIGN:(micro seconds) ' + str(sign_time.microseconds)) #VERIFIER f = open("DSA3072_CSE565.pem", "r") hash_gen = SHA256.new(plaintext) public_key = DSA.import_key(f.read()) verifier = DSS.new(public_key, 'fips-186-3') try: t1 = datetime.now() verifier.verify(hash_gen, signature) t2 = datetime.now() verify_time = t2 - t1 print('TIME TAKEN TO VERIFY:(micro seconds) ' + str(verify_time.microseconds)) print("THE SIGNATURE MATCHES! The message is authentic") except ValueError: print("The message is not authentic.") statinfo = os.stat(file_name + ".txt") size = statinfo.st_size sign_byte = sign_time.microseconds / size verify_byte = verify_time.microseconds / size print("TIME TO SIGN PER BYTE: " + str(sign_byte)) print("TIME TO VERIFY PER BYTE: " + str(verify_byte))
# DSA is a public-key algorithm for signing messages. # Following example at https://pycryptodome.readthedocs.io/en/latest/src/signature/dsa.html from Cryptodome.PublicKey import DSA from Cryptodome.Signature import DSS from Cryptodome.Hash import SHA256 private_key = DSA.generate(2048) # $ PublicKeyGeneration keySize=2048 public_key = private_key.publickey() # ------------------------------------------------------------------------------ # sign/verify # ------------------------------------------------------------------------------ print("sign/verify") message = b"message" signer = DSS.new(private_key, mode='fips-186-3') hasher = SHA256.new(message) # $ CryptographicOperation CryptographicOperationAlgorithm=SHA256 CryptographicOperationInput=message signature = signer.sign(hasher) # $ CryptographicOperation CryptographicOperationInput=hasher # MISSING: CryptographicOperationAlgorithm=DSA print("signature={}".format(signature)) print() verifier = DSS.new(public_key, mode='fips-186-3')
from Cryptodome.PublicKey import DSA # Create a new DSA key secret_code = "Change this to something unguessable!" key = DSA.generate(2048) encrypted_key = key.exportKey(passphrase=secret_code, pkcs8=True, protection="PBKDF2WithHMAC-SHA1AndDES-EDE3-CBC") public_key = key.publickey().exportKey(format='PEM') f_sec = open("secret_key.pem", "wb") f_sec.write(encrypted_key) f_pub = open("public_key.pem", "wb") f_pub.write(public_key)
from cryptography.hazmat.primitives.asymmetric import ec from cryptography.hazmat.primitives.asymmetric import rsa from Crypto.PublicKey import DSA as pycrypto_dsa from Crypto.PublicKey import RSA as pycrypto_rsa from Cryptodome.PublicKey import DSA as pycryptodomex_dsa from Cryptodome.PublicKey import RSA as pycryptodomex_rsa # Correct dsa.generate_private_key(key_size=2048, backend=backends.default_backend()) ec.generate_private_key(curve=ec.SECP384R1, backend=backends.default_backend()) rsa.generate_private_key(public_exponent=65537, key_size=2048, backend=backends.default_backend()) pycrypto_dsa.generate(bits=2048) pycrypto_rsa.generate(bits=2048) pycryptodomex_dsa.generate(bits=2048) pycryptodomex_rsa.generate(bits=2048) # Also correct: without keyword args dsa.generate_private_key(4096, backends.default_backend()) ec.generate_private_key(ec.SECP256K1, backends.default_backend()) rsa.generate_private_key(3, 4096, backends.default_backend()) pycrypto_dsa.generate(4096) pycrypto_rsa.generate(4096) pycryptodomex_dsa.generate(4096) pycryptodomex_rsa.generate(4096) # Incorrect: weak key sizes dsa.generate_private_key(key_size=1024, backend=backends.default_backend()) ec.generate_private_key(curve=ec.SECT163R2, backend=backends.default_backend()) rsa.generate_private_key(public_exponent=65537,
# cf. https://github.com/PyCQA/bandit/blob/b1411bfb43795d3ffd268bef17a839dee954c2b1/examples/weak_cryptographic_key_sizes.py import os from Crypto.PublicKey import DSA as pycrypto_dsa from Cryptodome.PublicKey import DSA as pycryptodomex_dsa # ok pycrypto_dsa.generate(bits=2048) # ok pycryptodomex_dsa.generate(bits=2048) # ok pycrypto_dsa.generate(4096) # ok pycryptodomex_dsa.generate(4096) # ruleid:insufficient-dsa-key-size pycrypto_dsa.generate(bits=1024) # ruleid:insufficient-dsa-key-size pycryptodomex_dsa.generate(bits=1024) # ruleid:insufficient-dsa-key-size pycrypto_dsa.generate(512) # ruleid:insufficient-dsa-key-size pycryptodomex_dsa.generate(512) pycrypto_dsa.generate(os.getenv("KEY_SIZE")) pycryptodomex_dsa.generate(os.getenv("KEY_SIZE"))
from Crypto.PublicKey import RSA as pycrypto_rsa from Cryptodome.PublicKey import DSA as pycryptodomex_dsa from Cryptodome.PublicKey import RSA as pycryptodomex_rsa # Correct dsa.generate_private_key(key_size=2048, backend=backends.default_backend()) ec.generate_private_key(curve=ec.SECP384R1, backend=backends.default_backend()) rsa.generate_private_key(public_exponent=65537, key_size=2048, backend=backends.default_backend()) pycrypto_dsa.generate(bits=2048) pycrypto_rsa.generate(bits=2048) pycryptodomex_dsa.generate(bits=2048) pycryptodomex_rsa.generate(bits=2048) # Also correct: without keyword args dsa.generate_private_key(4096, backends.default_backend()) ec.generate_private_key(ec.SECP256K1, backends.default_backend()) rsa.generate_private_key(3, 4096, backends.default_backend()) pycrypto_dsa.generate(4096) pycrypto_rsa.generate(4096) pycryptodomex_dsa.generate(4096) pycryptodomex_rsa.generate(4096)
signature = signer.sign(hash_obj) return signature def RSA_check_sign(plaintext, signature, key): ''' Проверка цифровой подписи signature для соообщения plaintext открытым ключом pub_key по стандарту PKCS#1 v1.5 ''' hash_obj = SHA256.new(plaintext) signer = pkcs1_15.new(key) try: signer.verify(hash_obj, signature) print("PKCS#1. Сообщение достоверно") return True except (ValueError, TypeError): print("PKCS#1. Сообщение недостоверно") return False # Осуществим подпись и проверку подписи по алгоритму RSA key_RSA = RSA.generate(1024, os.urandom) signature = RSA_sign(plaintext, key_RSA) print(hexlify(signature)) print(RSA_check_sign(plaintext, signature, key_RSA.publickey())) # Осуществим подпись и проверку подписи по алгоритму DSA key_DSA = DSA.generate(1024, os.urandom) signature = DSA_sign(plaintext, key_DSA) print(hexlify(signature)) print(DSA_check_sign(plaintext, signature, key_DSA.publickey()))
def keygen_public(key_size, alg, hash_alg, curve): if alg == 'rsa': key_pair = RSA.generate(key_size) priv_key = key_pair.exportKey() pub_key = key_pair.publickey().exportKey() priv_key_dict = { 'alg': 'rsa', 'type': 'private', 'size': key_size, 'hash': hash_alg, 'key': priv_key } pub_key_dict = { 'alg': 'rsa', 'type': 'public', 'size': key_size, 'hash': hash_alg, 'key': pub_key } #return priv_key_dict, pub_key_dict return [priv_key_dict, pub_key_dict] elif alg == 'dsa': key_pair = DSA.generate(key_size) priv_key = key_pair.exportKey() pub_key = key_pair.publickey().exportKey() priv_key_dict = { 'alg': 'rsa', 'type': 'private', 'size': key_size, 'hash': hash_alg, 'key': priv_key } pub_key_dict = { 'alg': 'rsa', 'type': 'public', 'size': key_size, 'hash': hash_alg, 'key': pub_key } #return priv_key_dict, pub_key_dict return [priv_key_dict, pub_key_dict] elif alg == 'ecc': if curve == 'p256': # FIPS 186-4, Section D.1.2.3 key_pair = ECC.generate(curve='P-256') priv_key = key_pair.export_key(format='PEM') pub_key = key_pair.public_key().export_key(format='PEM') priv_key_dict = { 'alg': 'ecc', 'curve': 'p256', 'type': 'private', 'hash': hash_alg, 'key': key_pair } pub_key_dict = { 'alg': 'ecc', 'curve': 'p256', 'type': 'public', 'hash': hash_alg, 'key': pub_key } return [priv_key_dict, pub_key_dict] else: print('SA_ERROR:', curve, 'not available.', flush=True) else: print('SA_ERROR:', alg, 'not yet implemented.', flush=True)