2017-04-12 144 views
3

我想在Java密钥库中为测试目的生成并存储HMacSHA256密钥。如何以编程方式在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代表一个对称密钥。而PrivateKeyPublicKey和私钥对的一部分。有没有办法存储单个对称密钥?

回答

3

是的,你可以。但在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

相关问题