通过java获取jks或keystore签名信息( jdk无法获取keystore的md5信息解决方案

  1. 介绍:
    • Java KeyStore是一个用于存储密钥和证书的安全容器,它提供了保护密钥完整性的功能。在日常的开发和维护工作中,我们可能会需要获取证书的指纹信息,以验证证书的完整性或者进行其他相关的安全检查。然而,目前的Java开发工具箱(JDK)并没有提供直接的命令行工具来获取特定证书的MD5指纹。这种限制可能会给开发人员和系统管理员带来一些不便。

为了解决这个问题,我们创建了一个简单的Java程序,通过它,用户可以轻松地加载指定的KeyStore,遍历其中的所有证书,并获取每个证书的MD5、SHA-1和SHA-256指纹。这个程序不仅可以显示证书的指纹信息,还可以展示证书的其他重要信息,如公钥和证书详情。通过这个程序,用户可以在没有内置命令行工具支持的情况下,方便快捷地完成证书指纹的获取和验证工作。

在接下来的章节中,我们将详细介绍这个程序的代码结构、执行流程以及如何使用它来获取证书的指纹信息。

  1. 代码结构:

    • 这个代码是一个名为KeyStoreInfo的Java类,包含了一个main方法和一个辅助方法getFingerprintmain方法用于加载密钥库,遍历密钥库中的所有别名,并提取与显示相关信息。getFingerprint方法用于计算证书的指纹。
  2. 代码执行流程:

    • 代码首先检查是否提供了正确数量的参数,否则会显示使用说明并退出。
    • 然后,它创建了一个FileInputStream对象来加载指定路径的密钥库文件。
    • 使用KeyStore.getInstancekeystore.load方法来加载密钥库。
    • 使用keystore.aliases方法来获取密钥库中的所有别名,并遍历每一个别名。
    • 对于每一个别名,它获取与之相关的证书和公钥,并显示它们。
    • 使用getFingerprint方法来计算和显示证书的MD5、SHA-1和SHA-256指纹。
    • 最终,关闭文件输入流。
  3. 计算指纹方法详解:

    • getFingerprint方法接受一个证书对象和一个算法名称(如“MD5”、“SHA-1”或“SHA-256”)作为参数。
    • 使用MessageDigest.getInstance方法获取指定算法的MessageDigest对象。
    • 使用certificate.getEncodedmd.update方法来准备数据。
    • 使用md.digest方法来计算指纹。
    • 最后,将字节数组转换为十六进制字符串并返回。
  4. 错误处理:

    • 代码包含了基本的错误处理,如果在执行过程中发生异常,它会捕获异常并打印堆栈跟踪。
  5. 代码使用:

    • 使用javac编译文件
    javac -encoding UTF-8 KeyStoreInfo.java
    
    • 运行编译后的.class文件提供两个参数 keystore pathpassword
    java KeyStoreInfo your_app.keystore_path your_keystore_password
    
  6. 全部代码

import java.io.FileInputStream;
import java.security.KeyStore;
import java.security.MessageDigest;
import java.security.PublicKey;
import java.security.cert.Certificate;
import java.util.Enumeration;

public class KeyStoreInfo {

    public static void main(String[] args) {
        if (args.length != 2) {
            System.err.println("Usage: java KeyStoreInfo <keystore-path> <keystore-password>");
            System.exit(1);
        }

        String keystorePath = args[0];
        String keystorePassword = args[1];

        try {
            // 加载密钥库文件
            FileInputStream is = new FileInputStream(keystorePath);
            KeyStore keystore = KeyStore.getInstance(KeyStore.getDefaultType());
            // 提供密钥库密码
            keystore.load(is, keystorePassword.toCharArray());

            // 获取密钥库中的所有别名
            Enumeration<String> enumeration = keystore.aliases();
            while (enumeration.hasMoreElements()) {
                String alias = enumeration.nextElement();
                Certificate certificate = keystore.getCertificate(alias);
                PublicKey publicKey = certificate.getPublicKey();

                // 显示别名和公钥
                System.out.println("Alias Name: " + alias);
                System.out.println("Public Key: " + publicKey);

                // 显示证书信息
                System.out.println("Certificate: " + certificate.toString());

                // 计算并显示 MD5, SHA-1, 和 SHA-256 指纹
                System.out.println("MD5 Fingerprint: " + getFingerprint(certificate, "MD5"));
                System.out.println("SHA-1 Fingerprint: " + getFingerprint(certificate, "SHA-1"));
                System.out.println("SHA-256 Fingerprint: " + getFingerprint(certificate, "SHA-256"));
                System.out.println("---");
            }

            is.close();

        } catch (Exception e) {
            e.printStackTrace();
        }
    }
   private static String getFingerprint(Certificate certificate, String algorithm) {
      try {
          MessageDigest md = MessageDigest.getInstance(algorithm);
          byte[] publicKey = certificate.getEncoded();
          md.update(publicKey);
          byte[] digest = md.digest();

          // 将字节转换为十六进制表示形式,并在每两个字符之间插入冒号
          StringBuilder hexString = new StringBuilder();
          for (byte b : digest) {
              String hex = Integer.toHexString(0xff & b);
              if (hex.length() == 1) hexString.append('0');
              hexString.append(hex);
              hexString.append(":");  // 添加冒号
          }
          // 移除最后一个冒号
          hexString.deleteCharAt(hexString.length() - 1);
          return hexString.toString().toUpperCase();  // 转换为大写
      } catch (Exception e) {
          e.printStackTrace();
          return null;
      }
  }
}
posted @ 2023-10-26 10:20  在云端i  阅读(1391)  评论(0编辑  收藏  举报