如何以编程方式生成 HMacSHA256 密钥并将其存储在 Java 中?
How to programmatically generate and store HMacSHA256 key in Java?
我想生成一个 HMacSHA256 密钥并将其存储在 Java 密钥库中以供测试。
我通常会通过密钥工具执行此操作:
keytool -genseckey -keystore keystore.jceks -storetype jceks -storepass secret -keyalg HMacSHA256 -keysize 2048 -alias HS256 -keypass secret
到目前为止,我发现我可以使用以下方法生成密钥:
SecretKey key = new SecretKeySpec("secret".getBytes(), "HmacSHA256");
不幸的是,该密钥不是 PrivateKey
的实例,因此存储密钥失败:
KeyStore ks = ...
ks.setEntry("HS256", new SecretKeyEntry(key), new PasswordProtection("secret".toCharArray()));
异常:
java.security.KeyStoreException: Cannot store non-PrivateKeys
at sun.security.provider.JavaKeyStore.engineSetKeyEntry(JavaKeyStore.java:258)
at sun.security.provider.JavaKeyStore$JKS.engineSetKeyEntry(JavaKeyStore.java:56)
at java.security.KeyStoreSpi.engineSetEntry(KeyStoreSpi.java:550)
at sun.security.provider.KeyStoreDelegator.engineSetEntry(KeyStoreDelegator.java:179)
at sun.security.provider.JavaKeyStore$DualFormatJKS.engineSetEntry(JavaKeyStore.java:70)
at java.security.KeyStore.setEntry(KeyStore.java:1557)
at com.gentics.mesh.SecretKeyTest.testSHA(SecretKeyTest.java:31)
我认为 SecretKey
代表一个对称密钥。 PrivateKey
是 PublicKey
和私钥对的一部分。有没有办法存储单个对称密钥?
是的,你可以。但在 Java 9 发布之前,PKCS#12 密钥存储的功能将受到限制。您在命令行中使用的 JCEKS 密钥存储 keytool
但是支持对称 (HMAC) 密钥:
public class HMACKeyStore {
public static void gen( String thePath, String thePassword ) throws Exception {
KeyGenerator keygen = KeyGenerator.getInstance("HmacSHA256");
SecretKey key = keygen.generateKey();
KeyStore keystore = KeyStore.getInstance("jceks");
keystore.load(null, null);
// This call throws an exception
keystore.setKeyEntry("theKey", key, thePassword.toCharArray(), null);
keystore.store( new FileOutputStream(thePath), thePassword.toCharArray() );
SecretKey keyRetrieved = (SecretKey) keystore.getKey("theKey", thePassword.toCharArray());
System.out.println(keyRetrieved.getAlgorithm());
}
public static void main(String[] args) throws Exception {
gen("hmac_store.jceks", "password");
}
}
应该可以在 Java 8.
上正常工作
我想生成一个 HMacSHA256 密钥并将其存储在 Java 密钥库中以供测试。
我通常会通过密钥工具执行此操作:
keytool -genseckey -keystore keystore.jceks -storetype jceks -storepass secret -keyalg HMacSHA256 -keysize 2048 -alias HS256 -keypass secret
到目前为止,我发现我可以使用以下方法生成密钥:
SecretKey key = new SecretKeySpec("secret".getBytes(), "HmacSHA256");
不幸的是,该密钥不是 PrivateKey
的实例,因此存储密钥失败:
KeyStore ks = ...
ks.setEntry("HS256", new SecretKeyEntry(key), new PasswordProtection("secret".toCharArray()));
异常:
java.security.KeyStoreException: Cannot store non-PrivateKeys
at sun.security.provider.JavaKeyStore.engineSetKeyEntry(JavaKeyStore.java:258)
at sun.security.provider.JavaKeyStore$JKS.engineSetKeyEntry(JavaKeyStore.java:56)
at java.security.KeyStoreSpi.engineSetEntry(KeyStoreSpi.java:550)
at sun.security.provider.KeyStoreDelegator.engineSetEntry(KeyStoreDelegator.java:179)
at sun.security.provider.JavaKeyStore$DualFormatJKS.engineSetEntry(JavaKeyStore.java:70)
at java.security.KeyStore.setEntry(KeyStore.java:1557)
at com.gentics.mesh.SecretKeyTest.testSHA(SecretKeyTest.java:31)
我认为 SecretKey
代表一个对称密钥。 PrivateKey
是 PublicKey
和私钥对的一部分。有没有办法存储单个对称密钥?
是的,你可以。但在 Java 9 发布之前,PKCS#12 密钥存储的功能将受到限制。您在命令行中使用的 JCEKS 密钥存储 keytool
但是支持对称 (HMAC) 密钥:
public class HMACKeyStore {
public static void gen( String thePath, String thePassword ) throws Exception {
KeyGenerator keygen = KeyGenerator.getInstance("HmacSHA256");
SecretKey key = keygen.generateKey();
KeyStore keystore = KeyStore.getInstance("jceks");
keystore.load(null, null);
// This call throws an exception
keystore.setKeyEntry("theKey", key, thePassword.toCharArray(), null);
keystore.store( new FileOutputStream(thePath), thePassword.toCharArray() );
SecretKey keyRetrieved = (SecretKey) keystore.getKey("theKey", thePassword.toCharArray());
System.out.println(keyRetrieved.getAlgorithm());
}
public static void main(String[] args) throws Exception {
gen("hmac_store.jceks", "password");
}
}
应该可以在 Java 8.
上正常工作