我的FS(S3 AWS密钥)上有一个文件,其中包含一个字符串,该字符串是我用于加密过程的密钥。
我想把它转移到Java KeyStore。
我知道如何使用keytool将证书导入KeyStore,但我找不到导入简单字符串键的方法。
你能帮忙吗?
答案 0 :(得分:12)
您可以使用PBE和JCEKS执行此操作。我认为你不能用JKS做到这一点。 解决方案:
创建一个密钥库来存储和获取条目:
keytool -keystore clientkeystore -genkey -alias client -storetype jceks
现在有一些代码可以测试它。
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());
}
答案 1 :(得分:3)
我没有看到使用keytool做到这一点的方法,但有些人在讨论,我想知道你是否可以在代码中存储和检索它作为PasswordBasedEncryption(PBE)SecretKey。 (免责声明:我自己没试过)。
推动这种想法的资源: PBEKeySpec javadoc和CryptoSpec - Using Password Based Encryption example
答案 2 :(得分:1)
我知道这很老;但是我碰到了同样的用例。
https://docs.oracle.com/javase/9/tools/keytool.htm#JSWOR-GUID-5990A2E4-78E3-47B7-AE75-6D1826259549
密钥库具有importpass选项,该选项存储由别名标识的KeyStore.SecretKeyEntry。
就是这样,您可以将字符串存储在别名中。
答案 3 :(得分:1)
今天下午我必须这样做,@ JasonG的解决方案有效,但keytool选项无效。
从Java 8开始,您可以在Keytool中使用-importpass
选项,这将帮助您实现所需的功能。
假设我想在敏感的密码foobar
的密钥存储区mypass
中的myks.jceks
别名中保存敏感密码password
,请执行以下操作:< / p>
$ 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>
然后您可以使用与@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());
});
}
请注意,由于JCEKS使用专有格式,所以我使用了PKCS12,建议您迁移到行业标准格式PKCS12。
此外,在尝试加载JCEKS存储并抛出异常时,某些Windows机器(运行Java 8)被卡住了,还有一些问题。 PKCS12似乎是一个更好的选择。
答案 4 :(得分:-1)
您无法在密钥库中导入任意字符串。在密钥库中,您可以导入java库用于远程主机身份验证的证书密钥。