2

I have a web page which takes a CSR (certificate signing request) and signs them. Problem is: I dont know how to extract the public key from the CSR. I tried openssl_csr_get_public_key($request) where request is the string holding the pem encoded request, but that doesn't seem to work. Any ideas on how to do this?

Thanks!

Haim Evgi
  • 123,187
  • 45
  • 217
  • 223
chacham15
  • 13,719
  • 26
  • 104
  • 207

3 Answers3

2

I find that phpseclib's pure PHP CSR implementation is generally much more "fault tolerant". eg.

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

$x509 = new File_X509();
$csr = $x509->loadCSR('...'); // see google.crt

print_r($sr);
?>

With that you should be able to access anything from the CSR that you want!

  • 1
    Yeah, I had to end up switching to phpseclib because I wanted to get/set SANs anyways, lol. But in this question, the problem was with formatting. I think that phpseclib's ASN1 parser would barf at incorrect base64 encoding. – chacham15 Apr 19 '13 at 06:51
1

You don't want to sign a public key per se, but the CSR, i.e. the signature includes metadata in the CSR that is also signed together with the public key.

The PHP command is openssl_csr_sign.

In order for this to work, you need a CSR (supplied by the client) and a CAcert file (loaded from a file on your server and passed as a string to your command). For generating the latter, look here: http://www.openssl.org/docs/apps/ca.html (official) and here (how to) http://www.freebsdmadeeasy.com/tutorials/freebsd/create-a-ca-with-openssl.php

obviously if you are a "real" CA -- e.g. you have a certificate signed by a CA that others trust -- then you would already have a cert (signed by them).

Generally speaking, it is not good practice to sign public keys supplied by others. What you want to do is ask your client to supply the CSR metadata, and then you generate their key for them, returning both the private key and the certificate -- this can be done in a PKCS 12 format (see openssl_pkcs12_export-- the entire exchange should occur over SSL.

chacham15
  • 13,719
  • 26
  • 104
  • 207
rsj
  • 788
  • 3
  • 10
  • "Warning: openssl_csr_sign() [function.openssl-csr-sign]: cannot get CSR from parameter 1" is what i get when i put the csr in as the first argument as a pem encoded string – chacham15 Nov 03 '11 at 12:58
  • Did you use openssl_csr_new() to generate the CSR locally, or was it supplied externally? In the case of the latter, how was it generated and encoded? – rsj Nov 03 '11 at 13:06
  • It could be a lot of things.. but he should be using PEM_write_bio_X509_REQ (assuming the data is sent online to you) or PEM_write_X509_REQ() if he is making files. The openssl c api is a bit tricky. He may want to generate the CSR in the command line first via openssl req -nodes -newkey rsa:2048 -keyout myserver.key -out server.csr and send the file to you to see if you can sign it. – rsj Nov 03 '11 at 16:15
  • Now I'm just curious -- did you solve your problem? Was the problem with your client's custom car generation? – rsj Nov 04 '11 at 23:46
  • Wow, i didnt see your earlier comment, sorry. The first error about cannot get the csr was a url problem. Turns out that the PHP was converting the +'s to spaces which was causing problems. The client initially signed the csr but didnt resign after data had changed which caused the second problem. – chacham15 Nov 05 '11 at 11:10
  • Wow, I am retarded. `openssl_csr_get_public_key($request)` works now with the fixed csr. – chacham15 Nov 05 '11 at 11:14
  • @chacham15. No problem. I thought it might be some encoding bug. But if your goal is to sign certificates, you need to sign the certificate, not the public key. You can of course sign anything with openssl -- an email, a blob, etc., using the generic signing facilities. But a signed public key is not a signed certificate. – rsj Nov 05 '11 at 11:19
  • Yes, as an additional security check, the message hash/signature is decrypted with the key corresponding to the csr. That way I can check that the entire message came from the user. This allows me to not blindly sign csr's. – chacham15 Nov 05 '11 at 13:02
0

Make sure that the csr is correctly formatted. Check that PHP isnt changing plusses into spaces or something of the sort.

chacham15
  • 13,719
  • 26
  • 104
  • 207