问题
Update: I have rewritten the sample code and the CSR is very close to the actual openssl created CSR (only missing the CA:False extended attribute)
I have a CA already and would like to dynamically generate user certs for enrolling authorized devices with phpseclib.
I know the logic is a little cloudy, this code was pieced together from a variety of different examples:
<?php
$USERNAME = "tester";
$DEVICENAME = "command";
$PASSWORD = "test";
$ID = 123;
require_once("config.inc.php"); // Sets defined paths to CA cert and key
require_once("File/X509.php");
require_once("Crypt/RSA.php");
// Setup our CA
$CA = array(); // Store our certificate authority information
$CA["key" ] = new Crypt_RSA();
$CA["key" ]->loadKey( file_get_contents(CAKEY) ); // Load our CA key to sign with
$CA["asciicert" ] = file_get_contents(CACERT);
$CA["cert" ] = new File_X509();
$CA["cert" ]->loadX509( $CA["asciicert"] ); // Load our CA cert and public key
$CA["cert" ]->setPrivateKey($CA["key"]);
// Create a new keypair
$DEVICE = array();
$DEVICE["keys" ] = new Crypt_RSA();
$DEVICE["keypair" ] = $DEVICE["keys"]->createKey(2048);
// Save our private key
$DEVICE["privkey" ] = new Crypt_RSA();
$DEVICE["privkey" ]->loadKey($DEVICE["keypair"]["privatekey"]);
// Save our public key
$DEVICE["pubkey" ] = new Crypt_RSA();
$DEVICE["pubkey" ]->loadKey($DEVICE["keypair"]["publickey"]);
// Create a new CSR
$DEVICE["csr" ] = new File_X509();
$DEVICE["csr" ]->setPrivateKey($DEVICE["privkey"]);
$DEVICE["csr" ]->setPublicKey ($DEVICE["pubkey" ]);
$DEVICE["csr" ]->setDN("C=SS, ST=obscure, L=obscure, O=secure, OU=networksecurity, CN={$USERNAME}@{$DEVICENAME}/emailAddress={$USERNAME}@{$DEVICENAME}");
// Sign the CSR
$DEVICE["signedcsr" ] = $DEVICE["csr"]->signCSR("sha256WithRSAEncryption");
$DEVICE["asciicsr" ] = $DEVICE["csr"]->saveCSR($DEVICE["signedcsr"]);
// Update the CSR with attributes
$DEVICE["cert" ] = new File_X509();
$DEVICE["cert" ]->loadX509( $DEVICE["asciicsr"] ); // Now load it back up so we can set extended attributes
$DEVICE["cert" ]->setPublicKey ($DEVICE["pubkey" ]);
$DEVICE["cert" ]->setStartDate("-1 day"); // Make it valid from yesterday...
$DEVICE["cert" ]->setEndDate("+ 5 years"); // Set a 5 year expiration on all device certs
$DEVICE["cert" ]->setSerialNumber($ID, 10); // Use our ID number in the DB, base 10 (decimal) notation
// These wont work, ill fix this later...
$DEVICE["cert" ]->setExtension("id-ce-basicConstraints", array("cA" => false ), 1 );
$DEVICE["cert" ]->setExtension("id-ce-keyUsage" , array("keyEncipherment" ,"nonRepudiation" ,"digitalSignature" ), 1 );
$DEVICE["cert" ]->setExtension("id-ce-extKeyUsage" , array("id-kp-emailProtection" ,"id-kp-clientAuth" ), 1 );
$DEVICE["cert" ]->setExtension("netscape-cert-type" , array("Email" ,"SSLClient" ), 1 );
// Finally have the CA sign the updated CSR
$DEVICE["signedcert"] = $DEVICE["cert"]->sign($CA["cert"], $DEVICE["cert"], "sha256WithRSAEncryption"); // Sign the new certificate with our CA
$DEVICE["asciicert" ] = $DEVICE["cert"]->saveX509($DEVICE["signedcert"]); // Ascii our certificate for presentation
print <<<END
User Public key:\n{$DEVICE["keypair"]["publickey"]}\n
User Private key:\n{$DEVICE["keypair"]["privatekey"]}\n
User CSR:\n{$DEVICE["asciicsr"]}\n
CA Cert:\n{$CA["asciicert"]}\n
User Certificate:\n{$DEVICE["asciicert"]}\n
END;
?>
Below is some sample output from this program:
...
User CSR:
-----BEGIN CERTIFICATE REQUEST-----
MIIC1DCCAb4CAQAwgZQxCzAJBgNVBAYMAlNTMRAwDgYDVQQIDAdvYnNjdXJlMRAw
DgYDVQQHDAdvYnNjdXJlMQ8wDQYDVQQKDAZzZWN1cmUxGDAWBgNVBAsMD25ldHdv
cmtzZWN1cml0eTEXMBUGA1UEAwwOdGVzdGVyQGNvbW1hbmQxHTAbBgkqhkiG9w0B
CQEMDnRlc3RlckBjb21tYW5kMIIBIDALBgkqhkiG9w0BAQEDggEPADCCAQoCggEB
ANzsEUPULfmkbDK2DLTWUbHxpqbxiQ0WF5vuUOXutcdJADG9uExyllRtnPmUq3yV
GhfF/jbKKwXrDMTc9JLRoPRjbCesHQq9p+WU2pgzHWOGne3b2SNB6ISSVUbmZwRd
3Uu78u2EIPw2yB/YAdMaSipuLnA4jbGwWHtMXWSr9g0en+CkJ0cHN3P0GAnDR7BF
2pq88si5Who9Dvn/Mo3npMZiAmD5D7qwD88mVFMC1j4q1xnqHi2X19Xz9+xgWZ1h
IdedpWh+v0i2kHE73Csu0Jiczxb28zdm+MjBEYGZ6X6LzCYHI5kx2wDKsxuxraMf
sY0QS/kATiTzSJMcWzxR82UCAwEAATALBgkqhkiG9w0BAQsDggEBABuThxlknbCS
Fzd8B+eM98uFW6YQmfp5js/S2+Cor3+btGi2d/siXDGusW7ceOEv4WLRikrv+0tt
rHNzndhl77ukSikA0H0VMUqNFYIL1N//W2nDhphYKWwKWHGoQ+/ZH30aLgw43iNz
IzWAj2d39bGEqAvGPzU6BDpm8o1ucMoJaqUAHNov69Ro/n+rb0k3ouuTqjewF781
lQFHMPhUY4j2JbGKpah3qPGvAgc44JR6VmG6Rh9nVhcZz5szit8K1UTgvIlSl7EH
7ggBHQl67kON19JKlKneJVsD36tczkEhuDGU5Dv4TH7SLiKwIRYHulD3bmqg2/Nq
sGAxVviaKBA=
-----END CERTIFICATE REQUEST-----
CA Cert:
-----BEGIN CERTIFICATE-----
MIIDVTCCAj2gAwIBAgICEA8wDQYJKoZIhvcNAQELBQAwSTELMAkGA1UEBhMCU1Mx
EjAQBgNVBAgMCVNlY3VyZSBDQTESMBAGA1UEBwwJU2VjdXJlIENBMRIwEAYDVQQK
DAlTZWN1cmUgQ0EwHhcNMTUwMjAxMTkzNjA2WhcNMTYwMjAxMTkzNjA2WjBPMQsw
CQYDVQQGEwJTUzEPMA0GA1UECAwGU2VjdXJlMQ8wDQYDVQQKDAZTZWN1cmUxHjAc
BgNVBAMMFW5ldHdvcmtzZWN1cml0eS5uaW5qYTCCASIwDQYJKoZIhvcNAQEBBQAD
ggEPADCCAQoCggEBAN7PJWsyd3Hn7q5/Y4N9Dcpvtip/hiSEFwrkl4UWd+bD7CGz
wQjyZziVAj7mXjgTrPCmMzwV/aRtT2WM7l1vI8WV0swsTEidvZF+EDEAujnadMxr
8JWVC+ljYvhy7nIDRYpPwkKSBWpIF1UFaG8MduHxBtqlRlOJoIDQmJkLQO5fV/kv
cujct4myMhar6TPx52xWX0FLt0B3Rn04Rb0InstyDY0NtrTMsgSq32rj3sijTCAG
WDsnxNO+jsC7uFAjjldcWnqBs7of+sVb7TPiEsq/5adE6G50ctqW8H7JpY+SFZzG
Y+wPRUxJZsYq4qt/rkEv7ldtsbhHD6wO4I61eksCAwEAAaNBMD8wDAYDVR0TBAUw
AwEB/zALBgNVHQ8EBAMCBeAwIgYDVR0RBBswGYIXKi5uZXR3b3Jrc2VjdXJpdHku
bmluamEwDQYJKoZIhvcNAQELBQADggEBAMsXyUX95AkQKadbaZ1XEWoayElWtKUc
dRB15XDJ7xoWGQo/fDYebXOJMPffIQoOGtRZcYtPaVjr3PMUCaxIAUvdmO3UMfLh
M8kQhYBzyEKw+SRwcUHmKbU8Tz5AolL1qjoNm5SWBV9RbFj2TRcR27v/apmhIR+K
6KKbcIXklKhhBPacJL7NwAgibb8Ip4OtxSuzarydddPryAwTwUSJNlmozRAx7dFk
xLkLMQMqEtW7BmJqU+YUczddYvbsxmYqfaChM/TBo7VZd84RlWoXOqqfon6JGLWN
5lN86iVnfXeGLbhLt5GKWB6e4rUbiMAqmGYO6Cd2BMFRtlp9IYZIBSY=
-----END CERTIFICATE-----
User Certificate:
-----BEGIN CERTIFICATE-----
-----END CERTIFICATE-----
I find it really confusing that the signed certificate is blank. The error checking in place seems to make me think it would simply return FALSE if there was a problem, but getting blank output between the ----- lines makes me wonder what is going on.
回答1:
From your code:
$DEVICE["cert" ]->loadX509( $DEVICE["asciicsr"] );
Try this:
$DEVICE["cert" ]->loadCSR( $DEVICE["asciicsr"] );
来源:https://stackoverflow.com/questions/28270870/phpseclib-user-cert-for-tls-authetication