本教程将向您展示如何使用 Java 的 keytool 工具为 GlassFish(现称 Eclipse GlassFish)生成 CSR(证书签名请求)。
GlassFish 在一个方面很特别,而且这对我们有帮助:全新安装后已经自带一个密钥库(在 Eclipse GlassFish 7.1 及更新版本中为 keystore.p12,在较旧版本中为 keystore.jks),以及一个别名为 s1as 的默认证书条目。您可以直接基于该现有密钥生成 CSR,也可以在同一别名下替换为全新密钥。无论采用哪种方式,导入已签发证书时都会重用同一个别名,因此密钥、CSR 和已签发证书都保存在同一位置。
您需要准备的内容
- 一个正常运行的 GlassFish(或 Eclipse GlassFish)安装环境。默认密钥库位于该域的 config 目录中,例如在 Eclipse GlassFish 7.1 及更新版本中为 glassfish/domains/domain1/config/keystore.p12,在较旧版本中为 keystore.jks。
- 一个已安装的 Java 环境,以确保可以使用 keytool 命令。GlassFish 自带 JDK,因此 keytool 通常已在系统路径中。可通过
keytool -help确认。 - 可访问 GlassFish 服务器的终端或 Shell。私钥必须保留在此服务器上。
- 您要保护的确切完全限定域名(FQDN),例如 www.yourdomain.com,以及要添加到 SAN 字段中的任何额外主机名。
- 用于 CSR 专有名称(Distinguished Name)字段的贵组织法律信息(国家、州/省、城市、组织名称)。
- 该域对应的 GlassFish 主密码(master password)。出厂默认值为 changeit;在生产系统上请使用
asadmin change-master-password命令进行修改。
生成 CSR 的两种方法
如果您已经生成了 CSR,请直接跳到提交 CSR部分,然后前往在 GlassFish 上安装 SSL 证书。
在 GlassFish 上常见的 keytool 操作流程有两种。请根据您的实际情况选择其一:
- 方案 A:基于现有的 s1as 密钥生成 CSR(推荐)。新创建的 GlassFish 域在默认密钥库中(7.1 及以上版本为 keystore.p12,较旧版本为 keystore.jks)已经存在一个别名为 s1as 的私钥。最快、风险最低的做法是保留该密钥,直接从中导出 CSR。跳转至方案 A。
- 方案 B:用全新密钥替换默认的 s1as 密钥,然后生成 CSR。如果您希望使用已知且当前的密钥长度和专有名称(DN),或怀疑默认密钥已被使用或泄露,请使用此方案。跳转至方案 B。
无论选择哪种方案,别名都必须保持为 s1as(如果您更改了别名,则必须同步更新 domain.xml 以保持一致)。GlassFish 的 HTTPS 监听器是通过别名来查找证书的,因此别名不匹配会导致 GlassFish 找不到密钥,TLS 也就无法启动。
方案 A:基于现有的 s1as 密钥生成 CSR
步骤 1:切换到 GlassFish config 目录
打开终端,切换到保存该域密钥库的目录。默认安装情况下,该目录是 domain1 的 config 文件夹:
cd /opt/glassfish7/glassfish/domains/domain1/config
请根据您实际的 GlassFish 安装路径进行调整(较旧的 GlassFish 4 版本会将安装目录嵌套在顶层的 glassfish4/ 文件夹下;Eclipse GlassFish 6、7 和 8 通常安装在 glassfish7/、glassfish8/ 或类似目录下)。如果您创建了自己的域,请将 domain1 替换为该域的名称。在此目录下运行 ls *.p12 *.jks 以确认密钥库文件名:在 Eclipse GlassFish 7.1 及更新版本中会看到 keystore.p12;在较旧版本中会看到 keystore.jks。请在下方命令中出现 keystore.jks 的地方替换为该实际文件名。
步骤 2:确认 s1as 条目存在
列出密钥库内容,检查 s1as 是否存在,并确认其为 PrivateKeyEntry:
keytool -list -v -keystore keystore.jks -alias s1as
输入密钥库密码(出厂默认为 changeit;在生产服务器上应与该域的主密码一致)。输出中应包含 Entry type: PrivateKeyEntry 这一行。如果您看到的是 Alias <s1as> does not exist 的提示信息,请转到方案 B,创建一个全新的条目。
步骤 3:导出带 SAN 的 CSR
现代浏览器和 TLS 客户端在验证证书时依据的是使用者备用名称(Subject Alternative Name,SAN)扩展,而不仅仅是通用名称(Common Name)。请在 CSR 中直接指定所需的 SAN,以便 CA 将其包含在最终签发的证书中:
keytool -certreq
-alias s1as
-keystore keystore.jks
-file glassfish.csr
-ext san=dns:yourdomain.com,dns:www.yourdomain.com
各参数含义如下:
- -alias s1as:现有的 GlassFish 证书别名。该别名下的私钥用于对请求进行签名。
- -keystore keystore.jks:默认的 GlassFish 密钥库文件。Eclipse GlassFish 7.1 及更新版本自带的是名为 keystore.p12 的 PKCS12 密钥库;较旧版本使用的是名为 keystore.jks 的 JKS 密钥库。请使用该目录中实际存在的文件名。命令本身在两种情况下相同;keytool 会自动识别格式。
- -file glassfish.csr:CSR 的输出文件名。您可以自行选择任意名称。
- -ext san=dns:…:使用者备用名称扩展。请列出证书必须覆盖的每一个主机名,包括裸域名(yourdomain.com)以及 www 子域名。可以用逗号分隔添加更多项,例如 dns:api.yourdomain.com。
keytool 会提示输入密钥库密码,并将 CSR 写入当前目录下的 glassfish.csr 文件。CSR 的主体(专有名称)取自 s1as 条目中已存储的信息;在全新安装的 GlassFish 上,这是自动生成的自签名证书信息,因此 DN 不会与您的公司信息匹配。大多数 CA 只验证通用名称和 SAN 列表,并允许您在订单表单中覆盖 DN 的其余部分,但如果您需要一个 DN 中已经包含贵公司法律信息的 CSR,请使用方案 B。
方案 B:用全新密钥替换默认的 s1as 密钥
当您希望完全掌控密钥长度和 DN,或者不想重用出厂生成的密钥时,可使用此方案。整体流程为:删除默认的 s1as 条目,在同一别名下创建新密钥,然后导出 CSR。保持别名为 s1as 意味着之后无需修改 domain.xml。
步骤 1:备份密钥库
在删除任何内容之前,请先复制当前密钥库,以便需要时可以回滚。在该域的 config 目录中执行:
cp keystore.jks keystore.jks.bak
步骤 2:删除默认的 s1as 条目
keytool -delete -alias s1as -keystore keystore.jks
在提示时输入密钥库密码。
步骤 3:在同一别名下创建新的私钥
在别名 s1as 下生成一个全新的 2048 位 RSA 密钥,并直接在命令中提供 DN,使命令以非交互方式执行:
keytool -genkeypair
-alias s1as
-keyalg RSA -keysize 2048
-keystore keystore.jks
-dname "CN=www.yourdomain.com, O=Your Company LLC, L=San Jose, ST=California, C=US"
-validity 825
各参数含义如下:
- -alias s1as:重用 GlassFish 的默认别名,因此无需修改 domain.xml。
- -keyalg RSA -keysize 2048:2048 位 RSA 密钥是目前公开认可的最低标准。如果您计划长期(数年)使用这个新密钥,升级到 3072 位是合理的选择。大多数公开 CA 也接受 ECDSA(-keyalg EC -groupname secp256r1),可获得更小、更快的密钥。
- -keystore keystore.jks:默认的 GlassFish 密钥库。在 Eclipse GlassFish 7.1 及更新版本中,请替换为 keystore.p12。keytool 会保留现有的密钥库格式(较旧安装为 JKS,7.1+ 为 PKCS12);两者在此处均可正常使用。
- -dname “CN=…”:写入 CSR 中的专有名称字段。请使用贵公司准确、合法的信息:
- CN:您要保护的确切 FQDN,例如 www.yourdomain.com,或类似 *.yourdomain.com 的通配符域名。请不要输入个人姓名,即便 keytool 在交互模式下的提示文字可能会让人这样理解。
- O:贵公司的完整法定名称。
- L:完整的城市名称(不要使用缩写)。
- ST:完整的州或省名称(不要使用两字母代码)。
- C:两字母的 ISO 国家代码,例如 US、GB、DE。
- OU(组织单位):目前公开 CA 已不再签发此字段。请在 DN 中省略该字段。
keytool 会提示输入密钥库密码和密钥密码。在 GlassFish 域中,密钥库密码、密钥密码和该域的主密码必须一致,否则 GlassFish 在启动时无法解锁密钥,HTTPS 将无法正常工作。在密钥密码提示时直接按 Enter 键,即可重用密钥库密码。
步骤 4:导出带 SAN 的 CSR
与方案 A 相同的命令,只是针对您的新密钥执行:
keytool -certreq
-alias s1as
-keystore keystore.jks
-file glassfish.csr
-ext san=dns:yourdomain.com,dns:www.yourdomain.com
输入密钥库密码。keytool 会将 CSR 写入当前目录下的 glassfish.csr 文件。
关键提示:请保持别名为 s1as
在 GlassFish 上使用 keytool 时,最常见的错误就是在生成密钥或导入已签名证书的过程中更改了别名。这会导致两种典型的失败情形:
- 密钥别名错误。GlassFish 的 HTTPS 监听器在 domain.xml 中固定绑定到 s1as。如果您在不同的别名下生成密钥,GlassFish 将无法找到它,监听器会回退到默认的自签名证书(或者无法启动)。如果您确实需要使用不同的别名,则必须更新 domain.xml 中所有对 s1as 的引用,使其保持一致。
- 导入时别名错误。当 CA 返回已签名证书后,您必须将其导入回持有该私钥的同一别名下。如果导入到一个全新的别名下,证书会被存储为一个不带私钥的独立信任条目,这样 TLS 将无法正常工作。
在关闭终端之前,请记录以下三项信息:
- 别名(默认为 s1as;请保持不变)。
- 密钥库文件路径,例如 glassfish/domains/domain1/config/keystore.p12(在较旧版本中为 keystore.jks)。
- 密钥库密码(必须与该域的主密码一致)。
提交前先验证 CSR
在 CA 对其进行验证之前,先自行检查 DN 中的拼写错误或缺失的 SAN。使用 keytool 打印 CSR:
keytool -printcertreq -file glassfish.csr
或者,如果已安装 OpenSSL,也可以改用它:
openssl req -noout -text -in glassfish.csr
请在输出中确认以下三点:Subject(主体)字段显示的是您准确的 DN,Subject Alternative Name(使用者备用名称)列出了您所需的每一个主机名,并且公钥(Public-Key)长度与您要求的一致(2048 位 RSA,或您所选择的其他长度)。您也可以将 CSR 粘贴到我们的CSR 解码工具中,在浏览器里进行同样的检查。
将 CSR 提交给您的证书颁发机构
使用任意文本编辑器打开 glassfish.csr 文件。该文件是纯文本格式,以 —–BEGIN CERTIFICATE REQUEST—– 开头,以 —–END CERTIFICATE REQUEST—– 结尾。请复制整个内容块,包括这两行头尾标记,并在 CA 的结账流程中将其粘贴到 CSR 字段中。在 Windows 上,可使用 Ctrl + A 然后 Ctrl + C 来获取完整文本;在 macOS 上,则使用 Cmd + A 然后 Cmd + C。
在 CA 验证您的请求并签发证书后,请继续参考如何在 GlassFish 上安装 SSL 证书。您需要先将 CA 证书链导入为受信任证书,然后将已签名的证书重新导入到同一密钥库文件(7.1+ 版本为 keystore.p12,较旧版本为 keystore.jks)中的 s1as 别名下,最后将 HTTPS 监听器指向该别名。


