65.9K
CodeProject 正在变化。 阅读更多。
Home

KeyGuard, JAR 签名工具

starIconstarIconstarIcon
emptyStarIcon
starIcon
emptyStarIcon

3.72/5 (8投票s)

2005年2月26日

CPOL

6分钟阅读

viewsIcon

85103

downloadIcon

1764

一个小型实用程序,用于自动化和简化 JAR 签名过程。

KeyGuard GUI in action.

免责声明

请注意,KeyGuard 仅适用于维护用户创建并因此由用户担保的个人证书密钥库。KeyGuard 目前每次保存对密钥库的更改时都会重写密钥库文件,这意味着在处理 KeyGuard 之前购买和安装或创建的任何证书都将被删除!通过命令行程序 "keytool" 对密钥库所做的任何更改都不会在 KeyGuard 中维护,并且在 KeyGuard 将其信息保存回密钥库时会丢失。我将不负责因您的密钥库丢失任何信息而产生的任何责任,并敦促您在使用 KeyGuard 之前备份您的 ".keystore" 文件。另请注意,此方法涵盖了用于 Sun JRE 插件的 JAR 签名,而不适用于其他 JVM。

引言

在您的 Java 和 Web 工作中,您可能需要签名一个 JAR。很可能,它是一个包含 Applet 的 JAR。有几种方法可以对 JAR 文件进行签名,尤其是包含 Applet 的 JAR 文件。然而,出于某种奇怪的原因,大多数方法都涉及命令行工具或脚本。由于我目前正在开发一个 Web 项目,该项目需要部署至少两个已签名的 Applet,每个 Applet 都有其自己的任务,我意识到我将需要对我的 JAR 文件进行大量的签名和重新签名。由于软件项目通常相当动态,我决定创建一个 GUI,它不仅可以让我签名 JAR 文件,还可以管理我项目中用于签名 JAR 文件的 Java 密钥库。

背景

在我开始描述 KeyGuard 如何帮助创建密钥库别名和签名 JAR 文件之前,有必要简要回顾一下这个过程。签名 JAR 文件的过程首先是从创建包含您的凭据的证书开始(如果您还没有)。这个过程涉及命令行程序 "keytool",它要求您提供有关您作为证书提供商的信息。一旦您提供了必要的信息,证书就会以您指定的别名存储在密钥库中。然后可以将此别名作为参数与您要签名的 JAR 文件一起传递给另一个命令行程序 "jarsigner"。为了让 KeyGuard 正常工作,"keytool" 和 "jarsigner" 都应该可以从您的 shell 提示符轻松访问。从上面的图片中可以看到,KeyGuard 维护着存储的每个证书的密码以及密钥库本身的全局密码。使用命令行程序的一个特别要求是记住您希望使用的每个证书的密码和别名,KeyGuard 非常好地解决了这个问题。

使用 KeyGuard

您可以通过以下方式之一使用 KeyGuard

  1. 直接从文章页面将 KeyGuard 用作 Applet。
  2. 下载 KeyGuard ZIP 文件,将其重命名为 JAR,然后在您的机器上使用它。

如果您选择下载 KeyGuard 并在本地使用它,您应该能够创建文件关联,以便右键单击任何 JAR 文件并使用 KeyGuard 对其进行签名,如下面的图片所示。

如果您选择从本文将 KeyGuard 用作 Applet,请注意,您必须授权 Applet 访问您的本地文件系统,否则它将无法正常运行。

KeyGuard 有两种操作模式。第一种模式是存储在密钥库中的证书及其信息的简单编辑器,此模式使用 "keytool" 命令行程序并为其提供创建您使用的证书所需的信息。第二种模式被激活以签名 JAR 文件。如果您在没有参数的情况下运行 KeyGuard.jar,它将显示证书编辑 GUI。如果您提供一个 JAR 文件(需要完整路径和文件名),则会显示 JAR 签名对话框。如果您磁盘上没有 .keystore 文件,您必须先通过 KeyGuard 添加至少一个证书来创建它,然后才能签名任何 JAR 文件。

无源代码

KeyGuard 使用了我在早期 文章 中介绍的另一个组件,该组件使 KeyGuard 能够与它使用的命令行程序进行交互。KeyGuard 本身包含在 KeyGuard.jar 文件中。KeyGuard 作为独立版本运行时不需要 Applet 的 JAR 文件,但是,正如您所注意到的,本篇文章没有可供下载的源代码。

Applet 的幕后

本节讨论 Applet 在 Applet 的 JAR 可以被签名后,预期如何利用其自由。

首先,Applet 必须使用自己的 SecurityManager 才能绕过某些默认 SecurityManager 执行的权限检查。以下代码显示了一个简单的 Applet,它已经将其自己的 SecurityManager 作为内部类包含在内。

import java.awt.*;
import java.security.*;

public class SignedApplet extends Applet {
  final class MySecurityManager extends SecurityManager {
    // Permission overriding methods..
    public void checkPermission(Permission perm) {}
    public void checkPermission(Permission perm, Object context) {}
  }
  // Rest of Applet goes here..
}

有时,正如我在测试 KeyGuard 的 Applet 版本时发现的那样,仅仅有一个作为内部类的 SecurityManager 并不足够。我不确定原因,但显然,即使是一个已签名的 Applet 也无法创建自己的 ClassLoaders,即使它已签名并且有一个作为内部类的 SecurityManager。因此,我需要创建一个实际替换默认 SecurityManagerSecurityManager 类,如下面的代码所示:

import java.security.*;

public final class KgSecurityManager extends SecurityManager {
  public static boolean init() {
    try {
      SecurityManager sm = System.getSecurityManager();
      if (!(sm instanceof KgSecurityManager)) {
        System.setSecurityManager(new KgSecurityManager());
      }
      return true;
    } catch (AccessControlException ex) {
      // Here's a little trick, if we get an AccessControlException here,
      // this means the user has refused to trust the Applet's Certificate!
      return false;
    }
  }
  // Same permission overriding methods as before..
  public void checkPermission(Permission perm) {}
  public void checkPermission(Permission perm, Object context) {}
}

现在,我的 KeyGuard Applet 可以像这样使用 KgSecurityManager

public class KgApplet extends JApplet {
  private static boolean appletAuthorized;
  
  // ...Rest of Applet code goes here...
  
  static {
    // This code will run only once, when the KgApplet class is 
    // first loaded in the Browser's JVM..
    try {
      // Try to initialize the KgSecurityManager class..
      appletAuthorized = KgSecurityManager.init();
      // Initialize the look & feel setting..
      UIManager.setLookAndFeel(UIManager.getCrossPlatformLookAndFeelClassName());
    } catch (Exception e) {
      e.printStackTrace();
    }
  }
}

Applet 现在可以检查 appletAuthorized 布尔标志,以了解它是否被允许尝试任何操作,否则如果默认 SecurityManager 仍然存在,这些操作将导致另一个 AccessControlException

关注点

我拖延撰写 KeyGuard 的时间主要是出于担心它会成为一个独立的项目。然而,这个小工具物超所值。我现在可以随意更改我的密钥库,轻松添加和删除证书,只需双击 KeyGuard.jar 文件即可。在将 KeyGuard.jar 集成到我的 XP 系统后,我可以肯定地说,我再也不需要手动使用 "keytool" 或 "jarsigner" 了。编写这个工具并连接命令行/交互式程序和现代 GUI 系统的世界也很有启发性,因为有一次我发现为 "keytool" 创建的外部进程已经在向我的程序发送输入,而我的程序还不确定进程是否已正确启动!我很有趣地看到问题出在访问进程实例的线程同步上。确实,在组合过程式编程和事件驱动/多线程程序时必须小心。如果您喜欢这个工具并能想到未来的改进,请给我留言或发送电子邮件。

历史

  • 2005 年 2 月 26 日 - KeyGuard Applet 现在托管在 GeoCities
  • 2005 年 2 月 25 日 - 创建文章
© . All rights reserved.