如何以编程方式在Java中生成和存储HMacSHA256密钥?

如何以编程方式在Java中生成和存储HMacSHA256密钥?,java,cryptography,keystore,Java,Cryptography,Keystore,我想在Java密钥库中生成并存储一个HMacSHA256密钥,以供测试之用 我通常会通过键盘工具执行此操作: keytool -genseckey -keystore keystore.jceks -storetype jceks -storepass secret -keyalg HMacSHA256 -keysize 2048 -alias HS256 -keypass secret 到目前为止,我发现我可以使用以下方法生成密钥: SecretKey key = new SecretKey

我想在Java密钥库中生成并存储一个HMacSHA256密钥,以供测试之用

我通常会通过键盘工具执行此操作:

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
表示对称密钥。而
私钥
公钥
和私钥对的一部分。有没有办法存储一个对称密钥?

是的,可以。但在Java9问世之前,PKCS#12密钥存储将在功能上受到限制。在命令行中使用的JCEKS密钥存储
keytool
不支持对称(HMAC)密钥:

在Java8上应该可以正常工作

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");
    }
}