??xml version="1.0" encoding="utf-8" standalone="yes"?> This tutorial will walk you through how to configure SSL (https://localhost:8443 access) on Tomcat in 5 minutes. For this tutorial you will need: The set up consists in 3 basic steps: Fisrt, open the terminal on your computer and type: Windows: Linux or Mac OS: The $JAVA_HOME on Mac is located on “/System/Library/Frameworks/JavaVM.framework/Versions/{your java version}/Home/” You will change the current directory to the directory Java is installed on your computer. Inside the Java Home directory, cd to the bin folder. Inside the bin folder there is a file named keytool. This guy is responsible for generating the keystore file for us. Next, type on the terminal: When you type the command above, it will ask you some questions. First, it will ask you to create a password (My password is “password“): It will create a .keystore file on your user home directory. On Windows, it will be on: C:\Documents and Settings\[username]; on Mac it will be on /Users/[username] and on Linux will be on /home/[username]. Open your Tomcat installation directory and open the conf folder. Inside this folder, you will find the server.xml file. Open it. Find the following declaration: Uncomment it and modify it to look like the following: Note we add the keystoreFile, keystorePass and changed the protocol declarations. Start tomcat service and try to access https://localhost:8443. You will see Tomcat’s local home page. Note if you try to access the default 8080 port it will be working too: http://localhost:8080 To force your web application to work with SSL, you simply need to add the following code to your web.xml file (before web-app tag ends): The url pattern is set to /* so any page/resource from your application is secure (it can be only accessed with https). The transport-guarantee tag is set to CONFIDENTIAL to make sure your app will work on SSL. If you want to turn off the SSL, you don’t need to delete the code above from web.xml, simply changeCONFIDENTIAL to NONE. Reference: http://tomcat.apache.org/tomcat-7.0-doc/ssl-howto.html (this tutorial is a little confusing, that is why I decided to write another one my own). Happy Coding!1 – Creating a Keystore file using Java
cd %JAVA_HOME%/bin
cd $JAVA_HOME/bin
keytool -genkey -alias tomcat -keyalg RSA
loiane:bin loiane$ keytool -genkey -alias tomcat -keyalg RSA Enter keystore password: password Re-enter new password: password What is your first and last name? [Unknown]: Loiane Groner What is the name of your organizational unit? [Unknown]: home What is the name of your organization? [Unknown]: home What is the name of your City or Locality? [Unknown]: Sao Paulo What is the name of your State or Province? [Unknown]: SP What is the two-letter country code for this unit? [Unknown]: BR Is CN=Loiane Groner, OU=home, O=home, L=Sao Paulo, ST=SP, C=BR correct? [no]: yes Enter key password for (RETURN if same as keystore password): password Re-enter new password: password
2 – Configuring Tomcat for using the keystore file – SSL config
<!-- <Connector port="8443" protocol="HTTP/1.1" SSLEnabled="true" maxThreads="150" scheme="https" secure="true" clientAuth="false" sslProtocol="TLS" /> -->
Connector SSLEnabled="true" acceptCount="100" clientAuth="false" disableUploadTimeout="true" enableLookups="false" maxThreads="25" port="8443" keystoreFile="/Users/loiane/.keystore" keystorePass="password" protocol="org.apache.coyote.http11.Http11NioProtocol" scheme="https" secure="true" sslProtocol="TLS" />
3 – Let’s test it!
4 – BONUS - Configuring your app to work with SSL (access through https://localhost:8443/yourApp)
<security-constraint> <web-resource-collection> <web-resource-name>securedapp</web-resource-name> <url-pattern>/*</url-pattern> </web-resource-collection> <user-data-constraint> <transport-guarantee>CONFIDENTIAL</transport-guarantee> </user-data-constraint> </security-constraint>
]]>
下面的CLIENT端可以与前文提到的JAVA服务端通信Q?br />#use strict;
use IO::Socket::SSL(debug4);
my ($v_mode, $sock, $buf);
if($ARGV[0] eq "DEBUG") { $IO::Socket::SSL::DEBUG = 1; }
# Check to make sure that we were not accidentally run in the wrong
# directory:
unless (-d "certs") {
if (-d "../certs") {
chdir "..";
} else {
# die "Please run this example from the IO::Socket::SSL distribution directory!\n";
}
}
if(!($sock = IO::Socket::SSL->new( PeerAddr => '172.19.149.52',
PeerPort => '5555',
Proto => 'tcp',
SSL_verify_mode => 0x01,
SSL_ca_file => 'mycerts/cacert.pem',
))) {
warn "unable to create socket: ", &IO::Socket::SSL::errstr, "\n";
exit(0);
} else {
warn "connect ($sock).\n" if ($IO::Socket::SSL::DEBUG);
}
# check server cert.
my ($subject_name, $issuer_name, $cipher);
if( ref($sock) eq "IO::Socket::SSL") {
$subject_name = $sock->peer_certificate("subject");
$issuer_name = $sock->peer_certificate("issuer");
$cipher = $sock->get_cipher();
}
warn "cipher: $cipher.\n", "server cert:\n",
"\t '$subject_name' \n\t '$issuer_name'.\n\n";
print $sock "Knock, knock.\n";
my ($buf) = $sock->getlines;
$sock->close();
print "read: '$buf'.\n";
另外Q也l出一个PERL的SVR端示例:#use strict;
use IO::Socket::SSL(debug4);
my ($sock, $s, $v_mode);
if($ARGV[0] eq "DEBUG") { $IO::Socket::SSL::DEBUG = 1; }
# Check to make sure that we were not accidentally run in the wrong
# directory:
unless (-d "certs") {
if (-d "../certs") {
chdir "..";
} else {
# die "Please run this example from the IO::Socket::SSL distribution directory!\n";
}
}
if(!($sock = IO::Socket::SSL->new( Listen => 5,
LocalAddr => '10.56.28.35',
LocalPort => 9000,
Proto => 'tcp',
Reuse => 1,
SSL_use_cert => 1,
SSL_verify_mode => 0x00,
SSL_cert_file => 'mycerts/cert.pem',
SSL_key_file => 'mycerts/key.pem'
)) ) {
warn "unable to create socket: ", &IO::Socket::SSL::errstr, "\n";
exit(0);
}
warn "socket created: $sock.\n";
while (1) {
warn "waiting for next connection.\n";
while(($s = $sock->accept())) {
my ($peer_cert, $subject_name, $issuer_name, $date, $str);
if( ! $s ) {
warn "error: ", $sock->errstr, "\n";
next;
}
warn "connection opened ($s).\n";
if( ref($sock) eq "IO::Socket::SSL") {
$subject_name = $s->peer_certificate("subject");
$issuer_name = $s->peer_certificate("issuer");
}
warn "\t subject: '$subject_name'.\n";
warn "\t issuer: '$issuer_name'.\n";
my $date = localtime();
print $s "my date command says it's: '$date'";
close($s);
warn "\t connection closed.\n";
}
}
$sock->close();
warn "loop exited.\n";
在PERL中写SSL的SOCKETQ要注意Q?br />SVR端中Q?br /> SSL_use_cert => 1,
SSL_verify_mode => 0x00,
SSL_cert_file => 'mycerts/cert.pem',
SSL_key_file => 'mycerts/key.pem'
CLI端是Q?br /> SSL_verify_mode => 0x01,
SSL_ca_file => 'mycerts/cacert.pem',
mode?表示Q不认证对端Q是1表示要认证对斏V?img src ="http://m.tkk7.com/alwayscy/aggbug/85368.html" width = "1" height = "1" />
]]>
]]>
B->A: 用V2加密q的P1Q即用户证书QAqP2解密出P1Q?br />
A->B: ok
B->A: 用V1加密的一D信?br />
A->B: 用P1加密一个自动生成的KQ用之前的P1解密成功q段信息则认为B是可信的了)
B->A: 用K加密的数据(之后两对密钥功能l束Q由K来加解密数据Q?br />
q里QP2是W?方的CA证书Q由于非对称加密很慢Q所以公U钥只是用来保证K的传送安全,之后通信是用K的对U加密算法来保证?br />
Z么通过以上q程Ap够确定肯定是BQ而不是某个C在假装B了呢Q因个过E中QB用V1加密q一D信息发lAQA也成功解开了。我们开头谈到公钥(P1Q只可以唯一解密U钥QV1Q加密过的信息,q样A可以完全相信B是拥有V1的,而V1是严g密,只被服务提供公司拥有Q所以保证了通信的服务方正确性?br />
q里(P2,V2)是certificate authority (CA)用来l客L名用的公U钥?br />
(P1,V1)是客戯q公私钥,提交lCAQCA所做的事情是?P2,V2)来给客户?P1,V1){Q简单吧Q?br />
V2是CA公司要保密的Q而P2是公用CA证书。用V2加密q({q)的P1Q称为用戯书,一般被安装在服务器端?br />
下面我们OpenSSL来做q一整g事情?br />
先生成CA的公U钥(Root Certificate )
准备工作
mkdir CA
cd CA
mkdir newcerts private
echo '01' > serial
touch index.txt
生成配置文g。由于openssl命o行参数太多,所以就用文件来l织各种选项?br />
其中,req_distinguished_name 节表C需要提C用戯入的信息?br />
v3_ca是有关CA公私钥生成的Qv3_req是有关用戯书生成的?br />
ca_default是用CA公私钥签名的时候,用户证书的默认信息?br />
vi ./openssl.cnf
dir = .
[ req ]
default_bits = 1024 # Size of keys
default_keyfile = key.pem # name of generated keys
default_md = md5 # message digest algorithm
string_mask = nombstr # permitted characters
distinguished_name = req_distinguished_name
req_extensions = v3_req
[ req_distinguished_name ]
# Variable name Prompt string
#---------------------- ----------------------------------
0.organizationName = Organization Name (company)
organizationalUnitName = Organizational Unit Name (department, division)
emailAddress = Email Address
emailAddress_max = 40
localityName = Locality Name (city, district)
stateOrProvinceName = State or Province Name (full name)
countryName = Country Name (2 letter code)
countryName_min = 2
countryName_max = 2
commonName = Common Name (hostname, IP, or your name)
commonName_max = 64
# Default values for the above, for consistency and less typing.
# Variable name Value
#------------------------------ ------------------------------
0.organizationName_default = EB Company
localityName_default = Shen Zhen
stateOrProvinceName_default = Guan Dong
countryName_default = CN
[ v3_ca ]
basicConstraints = CA:TRUE
subjectKeyIdentifier = hash
authorityKeyIdentifier = keyid:always,issuer:always
[ v3_req ]
basicConstraints = CA:FALSE
subjectKeyIdentifier = hash
[ ca ]
default_ca = CA_default
[ CA_default ]
serial = $dir/serial
database = $dir/index.txt
new_certs_dir = $dir/newcerts
certificate = $dir/cacert.pem
private_key = $dir/private/cakey.pem
default_days = 365
default_md = md5
preserve = no
email_in_dn = no
nameopt = default_ca
certopt = default_ca
policy = policy_match
[ policy_match ]
countryName = match
stateOrProvinceName = match
organizationName = match
organizationalUnitName = optional
commonName = supplied
emailAddress = optional
生成CA公私钥:
openssl req -new -x509 -extensions v3_ca -keyout private/cakey.pem -out cacert.pem -days 3650 -config ./openssl.cnf
会提C入密码,当用它给用户证书{旉要输入,以避免其它h用它随意产生用户证书?br />
-days表示有效期,因ؓ它是根证书,所以时间一定要很长Q否则由它生成的用户证书Ҏq期?br />
q时q成了Q?br />
P1
cacert.pem
V1
private/cakey.pem
查看信息用:
openssl x509 -in cacert.pem -noout -text
生成P2,V2Q即Certificate Signing Request (CSR)
执行Q?br />
openssl req -new -nodes -out req.pem -config ./openssl.cnf
q样q成了Q?br />
P2
req.pem
V2
key.pem
用此命o查看Q?br />
openssl req -in req.pem -text -verify -noout
用CA的私钥V1为P2{Q即生成用户证书
执行Q?br />
openssl ca -out cert.pem -config ./openssl.cnf -infiles req.pem
生成用户证书Q?br />
cert.pem
此时Q会拯一份到newcerts目录下。ƈ会更新数据库文gQindex.txt以及serail文g
用命令查看:
openssl x509 -in cert.pem -noout -text -purpose | more
如果要去除可M息部分,执行Q?br />
mv cert.pem tmp.pem
openssl x509 -in tmp.pem -out cert.pem
安装证书
key.pem(V2)和cert.pem(用V1加密q的P2Q安装到服务?br />
有的服务器需要把q两个文件连Z个,可以执行Q?br />
cat key.pem cert.pem >key-cert.pem
cacert.pem安装到客L
Apache的配|:
File Comment
/home/httpd/html Apache DocumentRoot
/home/httpd/ssl SSL-related files
/home/httpd/ssl/cert.pem Site certificate
/home/httpd/ssl/key.pem Site private key
Stunnel的配|?br />
stunnel -p /etc/ssl/certs/key-cert.pem
~辑?8.4.26Q另有两个例子:
用OpenSSL与JAVA(JSSE)通信
Perl与Java的SSL通信CZ
]]>
SDK WIN SVR 2003 SP1
MASM 8.0
q入打开sdk?000~译命o行,再运行:
%comspec% /k ""C:\Program Files\Microsoft Visual Studio 8\VC\vcvarsall.bat"" x86
d解压目录Q?br />cd /d "E:\Prj2\ForMe\RefExe\perl+ssl\openssl-0.9.8d"
再编译:
perl Configure VC-WIN32 --prefix=dist
ms\do_ms
nmake -f ms\ntdll.mak
nmake -f ms\ntdll.mak test
nmake -f ms\ntdll.mak install
完成后,dist目录是安装好的东西Q可以拷贝到别处使用