def generate_key(prov, keytype=AT_KEYEXCHANGE, flags=CRYPT_EXPORTABLE): """Generate a keypair if type ``keytype``. :return: :class:`HCRYPTKEY` """ key = HCRYPTKEY() winproxy.CryptGenKey(prov, keytype, flags, key) return key
def genkeys(common_name, pfxpassword, outname, keysize=2048, **kwargs): """Generate a SHA256/RSA key pair. A self-signed certificate with 'common_name' is stored as 'outname'.cer. The private key is stored in 'outname'.pfx protected with 'pfxpassword'""" cert_store = crypto.CertificateStore.new_in_memory() # Create a TMP context that will hold our newly generated key-pair with crypto.CryptContext(PFW_TMP_KEY_CONTAINER, None, PROV_RSA_FULL, 0, retrycreate=True) as ctx: key = HCRYPTKEY() keysize_flags = keysize << 16 # Generate a key-pair that is exportable winproxy.CryptGenKey(ctx, AT_KEYEXCHANGE, CRYPT_EXPORTABLE | keysize_flags, key) # It does NOT destroy the key-pair from the container, # It only release the key handle # https://msdn.microsoft.com/en-us/library/windows/desktop/aa379918(v=vs.85).aspx winproxy.CryptDestroyKey(key) # Descrption of the key-container that will be used to generate the certificate KeyProvInfo = CRYPT_KEY_PROV_INFO() KeyProvInfo.pwszContainerName = PFW_TMP_KEY_CONTAINER KeyProvInfo.pwszProvName = None KeyProvInfo.dwProvType = PROV_RSA_FULL KeyProvInfo.dwFlags = 0 KeyProvInfo.cProvParam = 0 KeyProvInfo.rgProvParam = None #KeyProvInfo.dwKeySpec = AT_SIGNATURE KeyProvInfo.dwKeySpec = AT_KEYEXCHANGE crypt_algo = CRYPT_ALGORITHM_IDENTIFIER() crypt_algo.pszObjId = szOID_RSA_SHA256RSA certif_name = "CN={0}".format(common_name) # Generate a self-signed certificate based on the given key-container and signature algorithme certif = gencrypt.generate_selfsigned_certificate( certif_name, key_info=KeyProvInfo, signature_algo=crypt_algo) # Add the newly created certificate to our TMP cert-store cert_store.add_certificate(certif) # Generate a pfx from the TMP cert-store print("Password is <{0}>".format(pfxpassword)) pfx = gencrypt.generate_pfx(cert_store, pfxpassword) if outname is None: outname = common_name.lower() # Dump the certif (public key) and pfx (public + private keys) with open(outname + ".cer", "wb") as f: # The encoded certif only contains the public key f.write(certif.encoded) with open(outname + ".pfx", "wb") as f: f.write(pfx) print(certif) # Destroy the TMP key container prov = HCRYPTPROV() winproxy.CryptAcquireContextW(prov, PFW_TMP_KEY_CONTAINER, None, PROV_RSA_FULL, CRYPT_DELETEKEYSET)