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

时间:2017-04-12 15:55:08

标签: java cryptography keystore

我想生成并存储HMacSHA256密钥,以便在Java密钥库中进行测试。

我通常会通过keytool执行此操作:

struct A {
    var first: String?
    var second: String?
    var third: String?
}

let a = A(first: "foo", second: nil, third: "baz")

let dictionary = Dictionary(unwrappingValues: [
    "first"  : a.first,
    "second" : a.second,
    "third"  : a.third
])

print(dictionary) // ["third": "baz", "first": "foo"]

到目前为止,我发现我可以使用以下方式生成密钥:

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

1 个答案:

答案 0 :(得分:3)

是的,你可以。但是在Java 9问世之前,PKCS#12密钥库的功能将受到限制。您在命令行keytool中使用的JCEKS密钥库确实支持对称(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上正常工作。