Generate OpenSSL private and public keys

2019-08-02 15:58发布

问题:

I have a task: generate private/public key pairs for banks.

User data like State, City, Company, Name, Email, and some other data should be included. How I can generate those keys with PHP or Shell?

UPDATE 1

I need a private key and cert for a Bank.

回答1:

PHP offers interface to OpenSSL functions. You need to generate a certificate (the keypair can't include user data), and this is a bit more complicated than generating a keypair. You can generate self-signed certificates (in such certificates Issuer and Subject fields are identical), which is probably what you need.

If you need a CA-signed certificate, than you need to generate a certificate signing request (CSR) and a private key, then send a CSR to the certificate authority that will sign it and send you back the certificate (remember that private key remains on your side, so you need to save it).

Also, google search revealed a good tutorial for you.



回答2:

Private&public key pairs do not contain identifying information like name and address. Certificates do (and also certificate requests, since those are meant to be turned into certificates).

The openssl command can generate both key pairs and certificate requests, and it can sign certificate requests to produce certificates as well. First, figure out exactly which kinds of objects you need, whether you need to use a central CA to sign certificates, etc... Then you should be able to easily find information on what arguments you need to pass to generate each type of object.



回答3:

Here is a shell script that I use for generating certificates using openssl. This is just a test script I wrote, so you might want to set some additional security. Having passwords written somewhere is not a good idea. You might want to run it thoroughly in your test environment or tweak as you like.

Here is what it requires:

  1. A proper CA certificate, its own private key etc, I assume you already have it. (I generated a self signed one and I would have it in the demoCA folder. Or you can generate using /usr/share/ssl/misc/CA.sh -newca)
  2. Openssl
  3. Text file (cert.input) having Required data {Country, State, City, Company, Org, Common name etc everything in a newline}
  4. Text file (caconfirm.input) for confirmation input (for saying 'yes')
  5. Text file for passwords. (pass.input) I will use MyPassword for all my cert related passwords.

There is only 1 only requirement, the ca private key file should not be password protected. If it is, you can run:

openssl rsa -in demoCA/private/cakey.pem -out demoCA/private/cakey_nopass.pem

Lets say I stored filename in CERT_FILE_NAME.

In the end you will get a folder with the name you provided (filename) containing: cert in pem format (filename.pem), cert in crt format (filename.crt), cert in der (binary format, (filename.der)), cert in password protected .p12 format (filename.p12), cert private key password protected (filename_Password.key) and cert private key non password protected. (filename_NoPassword.key)

#!/bin/sh
CERT_FILE_NAME=$1

#Lets generate a typical private key
openssl genrsa -passout pass:MyPassword -des3 -out ${CERT_FILE_NAME}_Password.key 1024

#Now, generate a cert signing request, and recieve the data from cert.input     
openssl req -passin pass:MyPassword -new -key ${CERT_FILE_NAME}_Password.key -out ${CERT_FILE_NAME}.csr < cert.input

#Sign the csr with the private key of our CA, and recieve the confirmation from caconfirm.input 
openssl ca -in ${CERT_FILE_NAME}.csr -cert demoCA/cacert.pem -keyfile demoCA/private/cakey_nopass.pem -out ${CERT_FILE_NAME}.crt -days 3825 < caconfirm.input

#Export my new cert to a password protected p12 file 
openssl pkcs12 -passin pass:MyPassword -passout pass:MyPassword -export -in ${CERT_FILE_NAME}.crt -inkey ${CERT_FILE_NAME}_Password.key -out ${CERT_FILE_NAME}.p12

#(Optional) Export my private key to a plain text private key
openssl rsa -passin file:pass.input -in ${CERT_FILE_NAME}_Password.key -out ${CERT_FILE_NAME}_NOPassword.key

# Output the crt into strict pem format having BEGIN/END lines
grep -A 1000 BEGIN ${CERT_FILE_NAME}.crt > ${CERT_FILE_NAME}.pem

# Convert the pem into der (binary) format
openssl x509 -outform der -in ${CERT_FILE_NAME}.pem -out ${CERT_FILE_NAME}.der

# Create a directory
mkdir ${CERT_FILE_NAME}

# Move all my cert files in the folder
mv ${CERT_FILE_NAME}*.* ${CERT_FILE_NAME}

Now the contents of the text files that we used (every item in newline):

cert.input:

Country
State
CityName
CompanyName
OrgName
CommonName

pass.input:

MyPassword

caconfirm.input:

y
y


回答4:

What type of private/public are you need? Someone who said you to do this must provide algorythm or type of keys. There is a huge variety of private/public key types, not only RSA.



回答5:

Here are PHP codes to generate PRIVATE and PUBLIC KEYS:

===method A) ====

<?php 
// generate 2048-bit RSA key
$pk_Generate = openssl_pkey_new(array(
    'private_key_bits' => 2048,
    'private_key_type' => OPENSSL_KEYTYPE_RSA
));

// getting private-key
openssl_pkey_export($pk_Generate, $pk_Generate_Private); // we pass 2nd argument as reference

// getting public-key
$pk_Generate_Details = openssl_pkey_get_details($pk_Generate);
$pk_Generate_Public = $pk_Generate_Details['key'];

// free resources
openssl_pkey_free($pk_Generate);

// getting/importing public-key using PEM format
// $pk_Generate_Private now gets into PEM format...
// this is an alternative method compared to above used "public retrieval"
$pk_Import = openssl_pkey_get_private($pk_Generate_Private); // importing
$pk_Import_Details = openssl_pkey_get_details($pk_Import); // same method to get public key, like in previous
$pk_Import_Public = $pk_Import_Details['key'];
openssl_pkey_free($pk_Import); // cleanup

// see output
echo "\r\n\r\n".$pk_Generate_Private."\r\n\r\n".$pk_Generate_Public."\r\n\r\n".$pk_Import_Public ."\r\n\r\n".'Public keys are '.(strcmp($pk_Generate_Public,$pk_Import_Public)?'different':'identical').'.';
?>

====method b) =======

include this [phpsec open-source library][1](with [examples][2]), and then execute:

<?php
include('File/X509.php');
include('Crypt/RSA.php');

// creating private key / x.509 cert for stunnel / website
$priv_Key = new Crypt_RSA();
extract($priv_Key->createKey());
$priv_Key->loadKey($privatekey);

$pub_Key = new Crypt_RSA();
$pub_Key->loadKey($publickey);
$pub_Key->setPublicKey();

$object = new File_X509();
$object->setDNProp('id-at-organizationName', 'phpseclib demo cert');
//$object->removeDNProp('id-at-organizationName');
$object->setPublicKey($pub_Key);

$cert_Issuer = new File_X509();
$cert_Issuer->setPrivateKey($priv_Key);
$cert_Issuer->setDN($object->getDN());

$x_509 = new File_X509();
//$x_509->setStartDate('-1 month'); // default: now
//$x_509->setEndDate('+1 year'); // default: +1 year from now

$result = $x_509->sign($cert_Issuer, $object);
echo "the stunnel.pem contents are as follows:\r\n\r\n".$priv_Key->getPrivateKey()."\r\n\r\n".$x_509->saveX509($result); 
?>