Данный документ представляет собой компиляцию с некоторыми комментариями
следующих документов:
Существует несколько версий SSL протокола:
Версия | Источник | Описание | Поддержка броузерами |
---|---|---|---|
SSL 2.0 | Netscape | Оригинальный протокол | Netscape 3.0,Internet Explorer 3.0 |
SSL 3.0 | Expired Internet Draft | Revisions to prevent specific security attacks, add ciphers,and support certificate chains | Netscape 3.0, Internet Explorer 3.0 |
TLS 2.0 | IETF Draft | Revision of SSL 3.0 | Нет |
Один из основных вариантов использования SSL - защита Web HTTP коммуникаций между клиентом и Web сервером. Этот вариант не пересекается и с использованием небезопасного HTTP. Защищенный вариант использует URLы, которые начинаются с https а не с http, и использует другой порт ( по умолчанию 443 ).
OpenSSL - свободная некоммерческая реализация SSL 2.0 и 3.0. Она включает реализацию открытых ключей ( public key ), которая может быть использована за пределами US. SSLeay предлагает достаточно несложный путь для освоения SSL и является темой данного документа.
Первым шагом для создания Certificate Authority является создания сертификата
для данного CA, подписанного самим же CA. Для этого используется
команда "req
" с ключом "-x509
". Сертификат
записывается в cacert.pem
и личный ключ cakey.pem
,
которые располагаются (согласно указанным в sslay.cnf переменным certificate и
private_key соответственно). commonName для самоподписанного сертификата не
должно соответствовать имени домена для сервера ( поскольку Nescape использует
имя домена для сертификации серверов). "req
" потребует введение
пароля для закрытого ключа ( private_key ). for Ex:(смотрите пути в
ssleay.cnf).
/usr/local/bin/ssleay req -new -x509 -keyout ${SSLDIR}/private/cakey.pem \
-out ${SSLDIR}/cacert.pem -config /usr/local/etc/ssleay.cnf
Using configuration from /usr/local/etc/ssleay.cnf
Generating a 512 bit private key
writing new private key to '../private/cakey.pem'
Enter PEM pass phrase:
Verifying password - Enter PEM pass phrase:
-----
You are about to be asked to enter information that will be incorperated
into your certificate request.
What you are about to enter is what is called a Distinguished Name or a DN.
There are quite a few fields but you can leave some blank
For some fields there will be a default value,
If you enter '.', the field will be left blank.
-----
Country Name (2 letter code) [US]: RU
State or Province Name (full name) [MA]: Some State
Locality Name (eg, city) [Cambridge]: some Locality
Organization Name (eg, company) [The Open Group]: None Group
Organizational Unit Name (eg, section) [Research Institute]: CT
Common Name (eg, YOUR name) [example.opengroup.org]: NONE CA
|
$SSLDIR/private
и $SSLDIR, как указано в
ssleay.conf
в CA default section. Они будут использоваться
для проверки сертификатов клиента подписанных созданным CA.
ssleay req -new -keyout newkey.pem -out newreq.pem -days 360
Using configuration from /usr/local/etc/ssleay.cnf
Generating a 1024 bit RSA private key
.......................+++++
.+++++
writing new private key to 'newkey.pem'
Enter PEM pass phrase:
Verifying password - Enter PEM pass phrase:
-----
You are about to be asked to enter information that will be incorporated
into your certificate request.
What you are about to enter is what is called a Distinguished Name or a DN.
There are quite a few fields but you can leave some blank
For some fields there will be a default value,
If you enter '.', the field will be left blank.
-----
Country Name (2 letter code) [RU]:
State or Province Name (full name) [Some State]:
Locality Name (eg, city) [Some Locality]:
Organization Name (eg, company) [Simple Org.]:
Organizational Unit Name (eg, section) [Computing Dep.]:
Common Name (eg, YOUR name) []:hostname.aaaa.ru
Email Address []:some@some.aaaa.ru
Please enter the following 'extra' attributes
to be sent with your certificate request
A challenge password []:
An optional company name []:
|
ssleay ca -policy policy_anything -out newcert.pem -config /usr/local/etc/ssleay.cnf -infiles newreq.pem
Using configuration from /usr/local/etc/ssleay.cnf
Enter PEM pass phrase:
Check that the request matches the signature
Signature ok
The Subjects Distinguished Name is as follows
countryName :PRINTABLE:'RU'
stateOrProvinceName :PRINTABLE:'Some State'
localityName :PRINTABLE:'Some Locality'
organizationName :PRINTABLE:'Simple Org.'
organizationalUnitName:PRINTABLE:'Computing Dep.'
commonName :PRINTABLE:'aaaaa.abbn.cc'
emailAddress :IA5STRING:'xz@abbn.cc'
Certificate is to be certified until Mar 16 22:46:52 2000 GMT (365 days)
Sign the certificate? [y/n]:y |
ln -s servercert.pem `x509 -noout -hash < servercert.pem`.0 |
crl2pkcs7 -inform PEM -outform DER -certfile $CA_cert.pem -out $CA_cert.der -nocrl |
<HTML><HEAD><TITLE>Load CA Certificate</TITLE></HEAD><BODY>
<H1>Load Certificate Authority Certificate</H1>
<FORM ACTION="http://example.some.somwere/cgi-bin/loadCAcert.pl" METHOD=post>
<TABLE>
<TR>
<TD>Netscape Browser (PEM Format):</TD>
<TD><INPUT TYPE="RADIO" NAME="FORMAT" VALUE="PEM" CHECKED></TD></TR>
<TR><TD>Microsoft Browser (DER Format):</TD>
<TD><INPUT TYPE="RADIO" NAME="FORMAT" VALUE="DER"></TD></TR>
</TABLE>
<INPUT TYPE="SUBMIT" VALUE="Load Certificate">
</FORM>
</BODY></HTML>
|
#!/usr/local/bin/perl -T
require 5.003;
use strict;
use CGI;
my $cert_dir = "/usr/local/CA/";
my $cert_file = "cacert.pem";
my $query = new CGI;
my $kind = $query->param('FORMAT');
if($kind eq 'DER') { $cert_file = "cacert.der"; }
my $cert_path = "$cert_dir/$cert_file";
open(CERT, "<$cert_path");
my $data = join '',<CERT>;
close(CERT);
print "Content-Type: application/x-x509-ca-cert\n";
print "Content-Length: ", length($data), "\n\n$data"; |
AddType application/x-x509-ca-cert .pem
в srm.conf
если
суффикс .pem
.
Укажем серверу его ключ: SSLCertificateKeyFile /usr/local/CA/private/serverkey.pem
И его сертификат: SSLCertificateFile /usr/local/CA/certs/servercert.pem
Далее укажем сертификат для CA и расположение сертификатов которые
могут быть использованы для аутентификации. SSLCACertificatePath /usr/local/CA/certs/
SSLCACertificateFile /usr/local/CA/cacert.pem
SSLPassPhraseDialog
. Она может принимать значения
builtin
и exec:/path/to/program
. В первом варианте при
старте сервер запрашивает пароль для расшифровки своего ключа, во втором
использует внешнюю программу, для получения пароля, пароль выдается ей на
stdout
.
Различные клиенты, такие как Nescape Navigator/Communicator и Microsoft Internet Explorer используют различный механизм для создания клиентских сертификатов.
Процедура создания сертификата представляет собой HTML формы, которые
включают в себя вызов CGI скрипта, который вызывает процедуры SSLeay/OpenSSL для
получения сертификата.
Последовательность действий такова:
HTML форма содержит поля ( с значениями по умолчанию ) для различных "distinguished name" атрибутов, которые используются в сертификате клиента, информация, позволяющая browser сгенерировать пару ключей, скрытые поля, которые зависят то типа browser, позволяющие передать эту информацию для CGI скрипта.
<HTML><HEAD><TITLE>Create Client Certificate</TITLE></HEAD><BODY>
<CENTER><H1>Create Client Certificate</H1></CENTER>
<FORM NAME="GenerateForm" ACTION="http://example.osf.org/cgi-bin/ns_key.pl">
<TABLE>
<TR><TD>Common Name:</TD><TD>
<INPUT TYPE="TEXT" NAME="commonName" VALUE="Client Certificate" SIZE=64>
</TD></TR>
<TR><TD>email:</TD><TD>
<INPUT TYPE="TEXT" NAME="emailAddress" VALUE="f.hirsch@opengroup.org" SIZE=40>
</TD></TR>
<TR><TD>Organization:</TD><TD>
<INPUT TYPE="TEXT" NAME="organizationName" VALUE="The Open Group">
</TD></TR>
<TR><TD>Organizational Unit:</TD><TD>
<INPUT TYPE="TEXT" NAME="organizationalUnitName" VALUE="Research Institute">
</TD></TR>
<TR><TD>Locality (City):</TD><TD>
<INPUT TYPE="TEXT" NAME="localityName" VALUE="Cambridge">
</TD></TR>
<TR><TD>State:</TD><TD>
<INPUT TYPE="TEXT" NAME="stateOrProvinceName" VALUE="MA">
</TD></TR>
<TR><TD>Country:</TD><TD>
<INPUT TYPE="TEXT" NAME="countryName" VALUE="US" SIZE="2">
</TD></TR>
</TABLE>
<!--
' keygen is Netscape specific and will be ignored in
' internet explorer
-->
<KEYGEN NAME="SPKAC" CHALLENGE="challengePassword">
<INPUT TYPE="SUBMIT" NAME="SUBMIT">
</FORM>
<P><HR></BODY></HTML>
|
#!/usr/local/bin/perl
require 5.003;
use strict;
use CGI;
use File::CounterFile; # module to maintain certificate request counter
my $doc_dir = $ENV{'DOCUMENT_ROOT'}; # apache specific location for storage
unless($doc_dir) {
print "<HTML><HEAD><TITLE>Failure</TITLE></HEAD>";
print "<BODY>DOCUMENT_ROOT not defined</BODY></HTML>";
exit(0);
}
my $base_dir = $doc_dir;
$base_dir =~ s/\/htdocs//;
my $SSLDIR = '/usr/local/ssl'; # define where SSLeay files are located
my $CA = "$SSLDIR/bin/ca";
my $CONFIG = "/usr/local/etc/ssleay.cnf";
my $CAPASS = "caKEY";
my $query = new CGI; # get a handle on the form data
my $key = $query->param('SPKAC'); # this will fail if not Netscape browser
unless($key) { fail("No Key provided $key. Netscape required"); }
my $counter = new File::CounterFile("$base_dir/.counter", 1);
unless($counter) { fail("Could not create counter: $!"); }
my $count = $counter->inc();
my $certs_dir = "$base_dir/certs";
my $req_file = "$certs_dir/cert$count.req"; # certificate request filename
my $result_file = "$certs_dir/cert$count.result"; # certificate filename
# Explicitly list form fields we must have for certificate creation to work.
my @req_names = ('commonName', 'emailAddress', 'organizationName',
'organizationalUnitName', 'localityName', 'stateOrProvinceName',
'countryName', 'SPKAC');
# build the request file
open(REQ, ">$req_file") or fail("Could not create request $req_file: $!");
my $name;
foreach $name (@req_names) {
my $value = $query->param("$name");
$value =~ tr/\n//d;
print REQ "$name = $value\n";
}
close(REQ);
# make sure we actually created a request file
unless(-f $req_file) { fail("request missing: $req_file"); }
unless(-e $CA) { fail("command missing"); } # ensure that ca command will run
# command for processing certificate request, without password
my $cmd = "$CA -config $CONFIG -spkac $req_file -out $result_file -days 360";
my $rc = system("$cmd -key $CAPASS 2>errs");
if($rc != 0) { fail("$cmd<P>rc = $rc", "errs"); }
open(CERT, "<$result_file") or fail("Could not open $result_file<P>$!");
# send the client certificate to the browser
print "Content-Type: application/x-x509-user-cert\n";
my $result = join '', <CERT>;
close CERT;
my $len = length($result);
print "Content-Length: $len\n\n";
print $result;
exit(0);
sub fail {
my($msg, $errs) = @_;
print $query->header;
print $query->start_html(-title => "Certificate Request Failure");
print "<H2>Certificate request failed</H2>$msg<P>";
if($errs) {
if(open(ERR, "<errs")) {
while(<ERR>) {
print "$_<BR>";
}
close ERR;
}
}
print $query->dump();
print $query->end_html();
exit(0);
}
|
CGI скрипт создает файл, содержащий значения для "distinguished name", переданных формой и специальный SPKAC значение для "Signed Public Key And Challenge (SPKAC)" созданное Navigator/Communicator.
SSLeay/OpenSSL ca команда вызывается, используя данный файл в качестве аргумента.(Смотри ns-ca.doc в документации к SSLeay/OpenSSL)
$SSLDIR/bin/ca -spkac $req_file -out $result_file -days 360 -key $CAPASS \
2>errs
|