导出和导入证书
为了解释清楚如何输出和输入证书,我会使用我自己的 https 服务器。这个服务器在第一部分中讨论过。然后,跟着下面的内容开始:
1、运行 https 服务器,像在第一部分中讨论的那样。
2、运行 readhttpsurl1:java readhttpsurl1 localhost。你同样会得到上面所述的异常。
3、使用下面的 keytool 命令导出服务器证书:
o 从 serverkeys 文件中导出别名为 qusay 的证书
o 将导出的证书保存在 server.cert 文件中,这个文件会由 keytool 创建
如你看到的那样,我根据要求输入了密码。成功输入密码之后,服务器证书被成功的导出并保存在 server.cert 中。
prompt> keytool -export -keystore serverkeys -alias qusay -file server.cert
enter keystore password: hellothere
certificate stored in file
4、将文件 server.cert 拷贝到 readhttpsurl1 所在的目录。使用 keytool 创建一个新的 keystore 并将服务器的 server.cert 证书导入其中。这里的命令示例:
prompt> keytool -import -keystore trustedcerts -alias qusay -file server.cert
这个命令会产生下面那样的输出。它要求输入密码,这是一个新的密码,用于 trustedcerts 这个 keystore 的。这个 keystore 由 keytool 创建。在输出信息的最后,它询问我是否愿意相信这个证书,我回答 yes。
enter keystore password: clientpass
owner: cn=localhost, ou=training and consulting, o=javacourses.com, l=toronto, st=ontario, c=ca
issuer: cn=localhost, ou=training and consulting, o=javacourses.com, l=toronto, st=ontario, c=ca
serial number: 3dcf988a
valid from: mon nov 11 06:46:18 est 2002 until: sun feb 09 06:46:18 est 2003
certificate fingerprints:
md5: 37:35:4d:3a:2b:7e:b5:09:a5:41:b3:fa:e4:3c:1d:c4
sha1: cb:7c:77:36:79:a2:37:26:e2:98:61:c2:9d:10:50:69:
99:f9:b9:1b
trust this certificate? [no]: yes
certificate was added to keystore
5、现在运行 readhttpsurl1 并告诉它哪里能找到证书。使用下面的命令:
prompt> java -djavax.net.ssl.truststore=trustedcerts readhttpsurl1 localhost
这将会与你的 https 服务器联接、校验证书,如果正确,它会下载默认页面 index.html。
--------------------------------------------------------------------------------
注意:信任管理器负责决定远端的证书是否值得信任。它使用下面的规则:
1、如果 javax.net.sll.truststore 系统属性指定了信任库,那么信任管理器会使用提供的文件来检查证书。如果那个系统属性存在但指定的文件不存在,那么就没有使用任何信任库,会抛出一个 certificateexception 异常。
2、如果 javax.net.sll.truststore 系统属性没有定义,那么它会去寻找默认的信任库:
o 如果在你的 java.home 目录的 lib/security 子目录下存在名为 jssecacerts 的信任库,那么使用的就是它。
o 如果 jssecacerts 不存在,但是 cacerts 存在 (它随 j2sdk 一起发行,含有数量有限的可信任的基本证书),使用的就是 cacerts。
在我的 windows 2000 客户机中,java.home 目录是 c:/program file/java/jre1.4.1/lib/security,在上例中,如果你将 trustedcerts 更名为 jssecacerts 并将其移动到 lib/security 子目录中,那么你以后就不需要在命令行指定 javax.net.ssl.truststore 属性了。
如果你不知道 java.home 在哪里,这里有一小段代码可以让你找到它:
public class findjavahome {
public static void main(string argv[]) {
system.out.println(system.getproperty("java.home"));
}
}
--------------------------------------------------------------------------------
url 类
示例代码 1 中的 readhttpsurl1 使用低层的套接字打开到 ssl 服务器的连接。这样做有一个缺点,如果不进行一番解析,我们就不能在命令行清楚的写出像 https://www.jam.ca 这样的 url。这里有一个更简单的办法在客户端应用程序中使用 ssl 和 jsse。
java.net.url 类支持 https 地址。例如,下面的代码段创建一个 https 地址并建立一个输入流的读入器:
url url = new url("https://www.sun.com");
bufferedreader in
= new bufferedreader(new inputstreamreader(url.openstream()));
是不是很简单?我希望当你学习 java 的新东西时,你能欣赏到它的美好之处。
示例代码 1 中的 readhttpsurl1 可以由下面使用了 url 类的示例代码 2 代替:
示例代码 2:readhttpsurl2.java
import java.net.*;
import java.io.*;
public class readhttpsurl2 {
public static void main(string argv[]) throws exception {
if(argv.length != 1) {
system.out.println("usage: java readhttpsurl2 ");
system.exit(0);
}
url url = new url(argv[0]);
bufferedreader in
= new bufferedreader(new inputstreamreader(url.openstream()));
string line;
stringbuffer sb = new stringbuffer();
while ((line = in.readline()) != null) {
sb.append(line);
}
in.close();
system.out.println(sb.tostring());
}
}
如果你想试试 readhttpsurl2,执行它的命令和上面讨论的类似。注意,无论如何,既然我们使用 url 类,你就能在命令行指定 url,包括协议的名称。这里是一个例子:
prompt> java readhttpsurl2 https://localhost
闽公网安备 35060202000074号