java - 为什么 Java KeyStore 在加载 OpenPGP key 时失败?

标签 java encryption rsa public-key openpgp

我愿意花一些时间为桌面 Java 应用程序开发另一个许可证管理器。环顾四周后,我发现了 JCPUID由 Iakin 提供,可以免费使用,并且应该可以在大多数操作系统上使用我发现的 native 库 here .

我的想法是做两个模块:将显示带有 CPU ID 和验证文本字段的弹出窗口的主应用程序以及 key 生成器应用程序。用户将 CPU ID 传递给注册机所有者,注册机所有者将返回验证码(使用注册机生成)给用户。用户提交正确的验证码后,将在文件系统中创建包含该验证码的许可证文件。每次应用程序启动时,它都会检查该文件的存在性和正确性,然后加载主应用程序屏幕。

关于代码验证,我认为最好的选择是使用非对称加密,尤其是 RSA。公钥将内置到应用程序中, secret 将内置到 key 生成器中。因此 CPUID 将传递给 key 生成器所有者,然后使用 RSA 进行签名。该签名将传回给用户,用户将使用内置公钥验证其有效性。

我使用 Kleopatra 和 gpg Linux 命令行工具本身生成了 gpg key 对。然后我尝试使用这种方法签名:

    private byte[] createSignature(byte[] file) {
    byte[] signature = null;

    try {
        java.security.KeyStore keyStoreFile = java.security.KeyStore
                .getInstance("PKCS12");
        keyStoreFile.load(getClass().getClassLoader().getResourceAsStream("/secret.asc"),
        "******".toCharArray());

        PrivateKey privateKey = (PrivateKey) keyStoreFile.getKey(
                "My Name Here", "******".toCharArray());

        Signature dsa = Signature.getInstance("SHA1withRSA");
        dsa.initSign(privateKey);
        dsa.update(file, 0, file.length);
        signature = dsa.sign();

    } catch (Exception e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }
    return signature;
}

但是 privateKey 初始化抛出异常:

java.security.InvalidKeyException: Key must not be null

我猜这是因为这里的实例格式错误:

java.security.KeyStore keyStoreFile = java.security.KeyStore
            .getInstance("PKCS12");

我想知道:

  1. 这种方法到底有多好?

  2. 不同的 OpenPGP key 格式之间存在什么区别,在这种情况下哪种格式最适合使用?如何知道现有 OpenPGP 文件的格式?

最佳答案

Java 加密框架不支持 OpenPGP。 X.509 key (例如 PKCS12 格式)与 OpenPGP 不兼容——尽管它们(大部分)依赖于相同的加密算法。

要么使用 X.509 证书(您也可以为此目的创建自己的 CA),要么依赖 OpenPGP for Java 的实现。在开源库方面,您可以在 native Java 实现之间进行选择 BouncyCastle (麻省理工学院许可证),或接口(interface) GnuPG (GPL) 通过 Java GPGME binding (LGPL)。

BouncyCaSTLe 可能是更好的方法,因为您需要做的就是添加另一个 Java 库,而不是将另一个软件安装到系统中。

关于java - 为什么 Java KeyStore 在加载 OpenPGP key 时失败?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35020850/

相关文章:

java - 安卓 BigInteger ArithmeticException

php - 在 MySQL 中搜索加密数据的最佳方法

ios - 解密 AES-256-CBC 字符串(需要 IV、字符串/数据格式?)

node.js - Node/Express - 保护客户端/服务器之间通信的好方法

java - 如何使用 BigInteger 加密字符串?

java - com.parse.ParseObject 无法转换为

Java 类未找到错误

java - 使用证书和 Kerberos 对用户进行身份验证?

java - 如何停用 Spring Data 异常转换

java - 为什么 RSA 使用相同的 key 和消息会产生不同的结果?