Updating PKCS12 Certificates using 'openssl' commands 1). Identify the section(s) that need to be updated. This requires reformatting the cert in PKCS12 format to text, then separating out each section into its own file, and then expanding these new files in order to read the contents. a) Converting to text format: The command to reformat a certificate (that does NOT have an encrypted private key) into text is: > openssl -info -nodes -in If the certificate has a private key that was encrypted when it was generated, delete the 'nodes' option: > openssl -info -in I'll assume the user cert filename is client.p12 and redirect the output to a new file named client.p12.pem. > openssl pkcs12 -info -nodes -in client.p12 > client.p12.pem When prompted, enter the passphrase used to decrypt the private key that is contained in this file. Look at the output file generated (client.p12.pem in this case), which is now in PEM format. Note the sections that begin with "Bag Attributes". The section that contains the private key looks like: Bag Attributes friendlyName: localKeyID: Key Attributes: -----BEGIN RSA PRIVATE KEY----- -----END RSA PRIVATE KEY----- There should also be at least 2 certs: the user's cert and one or more issuer (CA) certs that comprise the certificate chain. These are blocked off as -----BEGIN CERTIFICATE---- and -----END CERTIFICATE-----. In client.p12.txt, there are: Marcia's Grid ID (which is my own user cert) LBNL-Grid-CA - DOE Science Grid (the CA within LBNL-DSD) Certificate Manager - DOE Science Grid (the root CA which is self-signed) These sections can be in any order in the file. b) Create separate files, one for the private key and one for each cert. As an example, I did: > cp client.p12.pem key.pem > vi key.pem (delete everything from key.pem EXCEPT the PRIVATE KEY) (delete the private key portion from client.p12.pem) > cp client.p12.pem mycert.pem > vi mycert.pem (delete everyting from mycert.txt EXCEPT the user certificate) (delete the user certificate from client.p12.pem) client.p12.pem should now contain only the certificate chain. > cp client.p12.pem ca1.pem > vi ca1.pem (delete from ca1.pem the all certs not being saved in this file) (DO NOT delete from client.p12.pem the cert that was saved in ca1.pem) > cp client.p12.pem last-ca.pem > vi last-ca.pem (delete from ca1.pem the all certs not being saved in this file) (DO NOT delete from client.p12.pem the cert that was saved in ca1.pem) client.p12.pem should have all the CA certs in the certificate chain, but the output files generated for each cert in the chain are for identifying which one to update. NOTE: OpenSSL has given errors when the certificate for which you have the private key is not listed first in the certificate file! c) Assuming your user certificate is valid (or you would have skipped all of this and just gotten a new cert), read each new file containing a CA certificate to find the expired certificate by issuing the following command: > openssl x509 -in -text I redirected the output to a *.txt file > openssl x509 -in ca1.pem -text > ca1.txt > openssl x509 -in client.p12.pem > last-ca.txt Look at these files for the expiration dates and delete the file. In this case, it is the CA certificate from the DOE Science Grid that has an expiration date of Sept. 15, 2002, which is last-ca.txt. 2). Get the updated certificate in PEM format. In this case, this is the file doe.cert.new, enclosed with these directions. Replace the expired certificate in client.p12.pem with this one (i.e., delete old cert and copy-and-paste the new one). 3). Re-assemble the pieces into one file that is in PKCS12 format with the command: > openssl pkcs12 -export -chain -CAfile \ -in -inkey -name \ -out I used: > openssl pkcs12 -export -chain -CAfile client.p12.pem \ -in mycert.pem -inkey key.pem -name MARCIA -out client.p12.new Converting an Encrypted Private Key to an Unencrypted Private Key Given situation: A server's private key was stored in RSA format in a file PEM encoded file. This key was originally encrypted with a passphrase. However, we wanted to automatically launch this server from a shell script at bootup and could not be prompted for this passphrase from its C SSL code. Solution: One solution was to convert this private key to be unencrypted, which prevented being asked to supply a pass phrase during the server's run time. To do this, I used the openssl command in this general format: > openssl -in -out Example: The key was determined to be an RSA key by looking at the "BEGIN RSA PRIVATE KEY" line in the key file. The key file is named key.pem and the output is newkey.pem. The actual command is: > openssl rsa -in key.pem -out newkey.pem