如何在Java KeyStore中存储一个简单的密钥字符串?

Roy*_*ari 9 java keystore

我的FS(S3 AWS密钥)上有一个文件,其中包含一个字符串,该字符串是我用于加密过程的密钥.

我想将它移动到Java KeyStore.

我知道如何使用keytool将证书导入KeyStore,但我找不到导入简单字符串键的方法.

你能帮我吗?

Jas*_*onG 12

您可以使用PBE和JCEKS执行此操作.我认为你不能用JKS做到这一点.解:

创建一个密钥库来存储和获取条目:

keytool -keystore clientkeystore -genkey -alias client -storetype jceks
Run Code Online (Sandbox Code Playgroud)

现在有一些代码来测试它.

   public static String getPasswordFromKeystore(String entry, String keystoreLocation, String keyStorePassword) throws Exception{

        KeyStore ks = KeyStore.getInstance("JCEKS");
        ks.load(null, keyStorePassword.toCharArray());
        KeyStore.PasswordProtection keyStorePP = new KeyStore.PasswordProtection(keyStorePassword.toCharArray());

        FileInputStream fIn = new FileInputStream(keystoreLocation);

        ks.load(fIn, keyStorePassword.toCharArray());

        SecretKeyFactory factory = SecretKeyFactory.getInstance("PBE");

        KeyStore.SecretKeyEntry ske =
                (KeyStore.SecretKeyEntry)ks.getEntry(entry, keyStorePP);

        PBEKeySpec keySpec = (PBEKeySpec)factory.getKeySpec(
                ske.getSecretKey(),
                PBEKeySpec.class);

        char[] password = keySpec.getPassword();

        return new String(password);

    }

    public static void makeNewKeystoreEntry(String entry, String entryPassword, String keyStoreLocation, String keyStorePassword)
            throws Exception {
        SecretKeyFactory factory = SecretKeyFactory.getInstance("PBE");
        SecretKey generatedSecret =
                factory.generateSecret(new PBEKeySpec(
                        entryPassword.toCharArray()));

        KeyStore ks = KeyStore.getInstance("JCEKS");
        ks.load(null, keyStorePassword.toCharArray());
        KeyStore.PasswordProtection keyStorePP = new KeyStore.PasswordProtection(keyStorePassword.toCharArray());

        ks.setEntry(entry, new KeyStore.SecretKeyEntry(
                generatedSecret), keyStorePP);

        FileOutputStream fos = new java.io.FileOutputStream(keyStoreLocation);
        ks.store(fos, keyStorePassword.toCharArray());
    }
Run Code Online (Sandbox Code Playgroud)

  • 唯一令人讨厌的是您仍然暴露了您的密钥库密码。必须存储在环境变量或用户特定的内容中。 (2认同)

Ale*_*lex 7

我今天下午必须这样做,@JasonG 的解决方案有效,但 keytool 选项无效。

从 Java 8 开始,您可以将该-importpass选项与 Keytool 一起使用,这将帮助您实现所需。

假设我想将敏感密码保存在名为protected的密钥库foobar中的mypass别名中,请执行以下操作:myks.jcekspassword

$ keytool -importpass -storetype pkcs12 -alias mypass -keystore myks.p12
Enter keystore password: <password>
Re-enter new password: <password>
Enter the password to be stored: <foobar>
Re-enter password: <foobar>
Enter key password for <mypass>
    (RETURN if same as keystore password): <password>
Re-enter new password: <password>
Run Code Online (Sandbox Code Playgroud)

然后你很高兴去使用与@JasonG 相同的代码,我的代码中有这个:

private Try<String> loadKey(Resource path, String pw) {
    return Try.of(() -> {
        KeyStore ks = KeyStore.getInstance("PKCS12");
        ks.load(path.getInputStream(), pw.toCharArray());

        SecretKeyFactory factory = SecretKeyFactory.getInstance("PBE");
        SecretKeyEntry ske = (SecretKeyEntry) ks.getEntry("mypass",
                new PasswordProtection(pw.toCharArray()));

        PBEKeySpec keySpec = (PBEKeySpec) factory.getKeySpec(
                ske.getSecretKey(), PBEKeySpec.class);

        return new String(keySpec.getPassword());
    });
}
Run Code Online (Sandbox Code Playgroud)

请注意,由于 JCEKS 使用专有格式,因此我使用了 PKCS12,建议迁移到行业标准格式 PKCS12。

此外,我们在尝试加载 JCEKS 存储时遇到一些 Windows 机器(运行 Java 8)卡住的问题,抛出异常。PKCS12 似乎是更好的选择。


Cha*_*lie 5

我没有看到用 keytool 来做这件事的方法,但有些人想知道你是否可以在代码中存储和检索它作为 PasswordBasedEncryption (PBE) SecretKey。(免责声明:我自己没有尝试过)。

引发这种想法的资源: PBEKeySpec javadocCryptoSpec - Using Password Based Encryption example


小智 5

我知道这已经很旧了;但我遇到了同样的用例。

https://docs.oracle.com/javase/9​​/tools/keytool.htm#JSWOR-GUID-5990A2E4-78E3-47B7-AE75-6D1826259549

密钥库有一个 importpass 选项,用于存储由别名标识的 KeyStore.SecretKeyEntry。

就是这样,您可以将字符串存储在别名中。