如何在Java KeyStore中存储一个简单的密钥字符串?
我的 FS 上有一个文件(S3 AWS 密钥),其中包含一个字符串,该字符串是我用于加密过程的密钥。
我想把它移到一个Java KeyStore。
我知道如何使用keytool将证书导入密钥库,但我找不到导入简单字符串密钥的方法。
你能帮忙吗?
我的 FS 上有一个文件(S3 AWS 密钥),其中包含一个字符串,该字符串是我用于加密过程的密钥。
我想把它移到一个Java KeyStore。
我知道如何使用keytool将证书导入密钥库,但我找不到导入简单字符串密钥的方法。
你能帮忙吗?
你可以用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());
}
我今天下午必须这样做,@JasonG的解决方案有效,但不是keytool选项。
从Java 8开始,您可以将该选项与Keytool一起使用,这将帮助您实现所需的目标。-importpass
假设我想将敏感密码保存在别名中,该密钥库在此处使用密码保护,请执行以下操作:foobar
mypass
myks.jceks
password
$ 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,这是一种行业标准格式。
此外,我们还遇到了一些问题,一些Windows机器(运行Java 8)在尝试加载JCEKS存储时卡住了,引发了异常。PKCS12似乎是一个更好的选择。