生成OpenSSL私钥和公钥


Generate OpenSSL private and public keys

我有一项任务:为银行生成私钥/公钥对。

用户数据,如州、市、公司、姓名、电子邮件和其他一些数据都应该包括在内。如何使用PHP或Shell生成这些密钥?

更新1

我需要银行的私钥和证书。

PHP提供了OpenSSL函数的接口。您需要生成一个证书(密钥对不能包括用户数据),这比生成密钥对要复杂一些。您可以生成自签名证书(在这样的证书中,Issuer和Subject字段是相同的),这可能就是您所需要的。

如果您需要CA签名的证书,则需要生成证书签名请求(CSR)和私钥,然后向将对其进行签名的证书颁发机构发送CSR,并将证书发回(请记住,私钥仍在您身边,因此您需要保存它)。

此外,谷歌搜索为您展示了一个很好的教程。

私有&公钥对不包含诸如名称和地址之类的标识信息。证书是这样做的(还有证书请求,因为这些请求是要转换为证书的)。

openssl命令可以生成密钥对和证书请求,也可以对证书请求进行签名以生成证书。首先,弄清楚你需要哪种类型的对象,是否需要使用中央CA来签署证书,等等。然后,你应该能够很容易地找到生成每种类型对象所需传递的参数的信息。

这里有一个shell脚本,我使用它来使用openssl生成证书。这只是我写的一个测试脚本,所以您可能需要设置一些额外的安全性。把密码写在某个地方不是一个好主意。您可能希望在测试环境中彻底运行它,或者根据自己的喜好进行调整。

以下是它的要求:

  1. 一个合适的CA证书,它自己的私钥等等,我想你已经拥有了。(我生成了一个自签名的,我会把它放在demoCA文件夹中。或者你可以使用/usr/share/ssl/misc/CA.sh-newca生成)
  2. Openssl
  3. 具有必填数据的文本文件(cert.input){国家、州、城市、公司、组织、通用名称等,所有内容都在换行符中}
  4. 用于确认输入的文本文件(caconfirm.input)(用于表示"是")
  5. 密码的文本文件。(pass.input)我将对所有与证书相关的密码使用MyPassword

只有一个唯一的要求,ca私钥文件不应受到密码保护。如果是,您可以运行:

openssl rsa-in-democCA/private/cakey.pem-outdemoCA/private/cakey_nopass.pem

假设我将文件名存储在CERT_FILE_NAME中。

最后,您将获得一个具有您提供的名称(文件名)的文件夹,其中包含:pem格式的cert(filename.pem),crt格式的cert(filename.crt),der(二进制格式,(filename.der)),密码保护.p12格式的cert,密码保护的cert私钥(filename_password.key)和非密码保护的cert私钥。(文件名_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}

现在,我们使用的文本文件的内容(换行符中的每一项):

cert.input:

Country
State
CityName
CompanyName
OrgName
CommonName

pass.input:

MyPassword

caconfirm.input:

y
y

以下是生成PRIVATE和PUBLIC密钥的PHP代码:

===方法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').'.';
?>

===方法b)=======

包括这个[phpsec开源库][1](带有[示例][2]),然后执行:

<?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); 
?>

您需要什么类型的私有/公共?让你这么做的人必须提供算法或密钥类型。私钥/公钥类型多种多样,不仅仅是RSA。