Extract Der Format X 509 Public Certificate From Iis 4 Pfx

under Windows Perl

 

IIS 4 certificate files usually contain both the private key and public certificate for SSL. To convert these to RSA private key and x.509 public certificates from NET to DER format, you need to manually edit the binary key file as documented on te’s site then run the following OpenSSL commands:

# openssl rsa -inform NET -in iisfile.key -out private.pem<br># openssl x509 -inform NET -in iisfile.key -out public.crt

Eck…no thanks. The te site skips over pulling out the public certificate (yes, I know you could actual just get the certificate from within a browser, but do that for 50+ certificates). Anyways, the following perl script will located the magic hex number “30 82” followed closely by with the string certificate0, copy all the file from that point on to a tmp file, and then make a system call to OpenSSL (must be in your path on Windows platform) to convert it to x.509 formated. Example:

# perl key_to_crt.pl file1.key file2.key ...

Where file1.key ect are the IIS4 pfx key files to extract the public crt in DER format. Get a copy of OpenSSL for Windows http://gnuwin32.sourceforge.net/packages/openssl.htm. Make sure to renamed the two dll files under the bin directory before running the script.

#!/usr/bin/perl
# Copyright (C) 2003 Andrew Loree
# $Id: key2crt.pl,v 1.2 2003/10/07 12:34:41 andy Exp $
############################################################################
#
# key2crt.pl - Converts IIS 4 format SSL files to x509 DER public keys (.crt)
#              and RSA private keys (.pem) REQUIRES OPENSSL to be installed
#              and within the PATH on Windows machines
#
############################################################################
#
#  This program is free software; you can redistribute it and/or
#  modify it under the terms of the GNU General Public License
#  as published by the Free Software Foundation; either version 2
#  of the License, or (at your option) any later version.
#
#  This program is distributed in the hope that it will be useful,
#  but WITHOUT ANY WARRANTY; without even the implied warranty of
#  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
#  GNU General Public License for more details.
#
#  You should have received a copy of the GNU General Public License
#  along with this program; if not, write to the Free Software
#  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
#
#############################################################################
# Version History:
#   1.0  - Initial Release
#   1.1  - Added Private key extraction...you will be prompted for a phase
#          if necessary.
#############################################################################
use File::Basename qw(basename);
use File::stat;        # for tell
my $program = basename($0);
my $version = "1.0";
use strict;
use FileHandle;
use File::stat;
use File::Spec;
my $argc = @ARGV;
my $i;
my $filename;
my $in;
my $out;
my $buffer;
if($argc == 0){
	usage();
}
for($i = 0; $i < $argc; $i++){
	# Get previous last_modified date/time
	$filename = $ARGV[$i];
	print "$filename...";
	$in = new FileHandle;
	if ($in->open("< " . $filename)){
		binmode $in;
		read $in, $buffer,1000000;	# Read in all of the file
		my $size = length $buffer;
		$in->close;
		if ($buffer =~ /(\x30\x82.{3,8}certificate0.*)/s) {
			my $public_buffer = $1;
			$out = new FileHandle;
			$out->open("> " . $filename . ".tmp");
			binmode $out;
			syswrite $out, $public_buffer, length $public_buffer;
			$out->close;
			print "openssl...";
			my $newfilename = $filename;
			$newfilename =~ s/\.key/\.crt/i;
			my $ret = system("openssl x509 -inform NET -in " . $filename
							. ".tmp -out "  . $newfilename);
			if ($ret != 0) {
				print "ERROR DURING CONVERSION\n";
			}
			else{
				print "Complete\n";
				# remove temp file
				unlink $filename . ".tmp";
			}
		}
		else{
			print "PUBLIC CERTIFICATE NOT FOUND\n";
		}
		if ($buffer =~ /(\x30\x82.{3,8}private-key0.*)/s) {
			my $private_buffer = $1;
			$out = new FileHandle;
			$out->open("> " . $filename . ".tmp");
			binmode $out;
			syswrite $out, $private_buffer, length $private_buffer;
			$out->close;
			print "openssl...";
			my $newfilename = $filename;
			$newfilename =~ s/\.key/\.pem/i;
			my $ret = system("openssl rsa -inform NET -in " . $filename
							. ".tmp -out "  . $newfilename);
			if ($ret != 0) {
				print "ERROR DURING CONVERSION\n";
			}
			else{
				print "Complete\n";
				# remove temp file
				unlink $filename . ".tmp";
			}
		}
		else{
			print "PRIVATE CERTIFICATE NOT FOUND\n";
		}
	}
	else{
		print "ERROR OPENING THE FILE\n";
	}
}
sub usage {
    print STDERR <<end_of_usage; name="" $program="" --="" converts="" iis="" 4="" format="" ssl="" files="" to="" x509="" der="" public="" keys="" and="" rsa="" private="" requires="" openssl="" be="" installed="" within="" the="" path="" on="" windows="" machines="" usage="" file1="" file2="" ...="" description="" file="" convert="" version="" $version="" end_of_usage="" exit="" 0;="" }="" <="" pre="">