我找到了这个帖子:Connecting to SoftHSM java,它可以在存储私钥时起作用,就像示例一样。
但我需要存储密钥,例如AES。
这是我的代码:
final RealmConfiguration.Builder builder=new RealmConfiguration.Builder(this);
builder.schemaVersion(SCHEMA_VERSION);
if (SCHEMA_VERSION < 105) {
builder.deleteRealmIfMigrationNeeded();
} else {
builder.migration(new Migration());
}
final RealmConfiguration config = builder.build();
这是softhsm.cfg文件:
import java.security.*;
import sun.security.pkcs11.*;
import javax.crypto.spec.SecretKeySpec;
public class Main {
public static void main(String[] args) throws Exception {
// Set up the Sun PKCS 11 provider
String configName = "softhsm.cfg";
Provider p = new SunPKCS11(configName);
if (-1 == Security.addProvider(p)) {
throw new RuntimeException("could not add security provider");
}
// Load the key store
char[] pin = "mypin".toCharArray();
KeyStore keyStore = KeyStore.getInstance("PKCS11", p);
keyStore.load(null, pin);
// AES key
SecretKeySpec secretKeySpec = new SecretKeySpec("0123456789ABCDEF".getBytes(), "AES");
Key key = new SecretKeySpec(secretKeySpec.getEncoded(), "AES");
keyStore.setKeyEntry("AA", key, "1234".toCharArray(), null);
keyStore.store(null); //this gives me the exception.
}
}
执行keyStore.store(null)时,我收到name = SoftHSM
library = /usr/local/lib/softhsm/libsofthsm.so
slot = 0
attributes(generate, *, *) = {
CKA_TOKEN = true
}
attributes(generate, CKO_CERTIFICATE, *) = {
CKA_PRIVATE = false
}
attributes(generate, CKO_PUBLIC_KEY, *) = {
CKA_PRIVATE = false
}
答案 0 :(得分:2)
原来使用SoftHSMv1发生异常。我安装了SoftHSMv2,您可以使用git从GitHub下载它,并使用它来存储密钥。不要从OpenDNSsec网站下载SoftHSMv2,因为它不起作用!!。
最后我不得不更改softhsm.cfg文件以指向新库,由于某些原因我忽略了,SoftHSM2更改了初始化插槽的数量,您可以使用sudo softhsm2-util --show-slots
验证它
softhsm.cfg:
name = SoftHSM
library = /usr/local/lib/softhsm/libsofthsm2.so
slot = 498488451
attributes(generate, *, *) = {
CKA_TOKEN = true
}
attributes(generate, CKO_CERTIFICATE, *) = {
CKA_PRIVATE = false
}
attributes(generate, CKO_PUBLIC_KEY, *) = {
CKA_PRIVATE = false
}
我的代码:
import java.security.*;
import sun.security.pkcs11.*;
import javax.crypto.spec.SecretKeySpec;
public class Main {
public static void main(String[] args) throws Exception {
// Set up the Sun PKCS 11 provider
String configName = "softhsm.cfg";
Provider p = new SunPKCS11(configName);
if (-1 == Security.addProvider(p)) {
throw new RuntimeException("could not add security provider");
}
// Load the key store
char[] pin = "mypin".toCharArray();
KeyStore keyStore = KeyStore.getInstance("PKCS11", p);
keyStore.load(null, pin);
// AES key
SecretKeySpec secretKeySpec = new SecretKeySpec("0123456789ABCDEF".getBytes(), "AES");
Key key = new SecretKeySpec(secretKeySpec.getEncoded(), "AES");
keyStore.setKeyEntry("AA", key, "1234".toCharArray(), null);
keyStore.store(null); //this no longer gives me the exception.
Enumeration<String> aliases = keyStore.aliases();
while(aliases.hasMoreElements()){
String alias = aliases.nextElement();
System.out.println(alias + ": " + keyStore.getKey(alias,"1234".toCharArray()));
}
}
}
这给了我输出:
AA: SunPKCS11-SoftHSM AES secret key, 16 bits (id 2, token object, not sensitive, unextractable)
如果您尝试使用类似keyStore.getKey("AA", "1234".toCharArray());
之类的内容获取密钥,则会获得包含密钥属性的对象,但您无法使用.getEncoded()
来实际获取密钥,因为它是不可提取的。