如何将对称密钥导入到thales HSM?

问题描述

如题,如何将对称密钥(Triple DES key)导入到thales HSM?

就像 aws HSM 一样,它可以使用 imsymKey 命令。 https://docs.aws.amazon.com/cloudhsm/latest/userguide/key_mgmt_util-imSymKey.html

请提供代码和示例,非常感谢。

解决方法

  1. 安装 Java 以连接到 HSM。

1.1 将 SafeNet Java 库和 jar 文件从 /opt/safenet/lunaclient/jsp/lib 下的默认位置复制到 Java 环境目录,例如 /opt/jre/lib/ext。

1.2 编辑位于 Java SDK/JRE 安装目录 /jre/lib/security 中的 java.security 文件,内容如下:

security.provider.1=sun.security.provider.Sun

security.provider.2=com.sun.net.ssl.internal.ssl.Provider

security.provider.3=com.safenetinc.luna.provider.LunaProvider

security.provider.4=com.sun.rsajca.Provider

security.provider.5=com.sun.crypto.provider.SunJCE

security.provider.6=sun.security.jgss.SunProvider
  1. 运行代码,将 desKey 更改为您的密钥并从引用中获取 HsmManager。
    public class KeyWrappingExample {
    //
    // Alias used to store the the KEK (Key Encryption Key) on the HSM
    //
    private static final String KEK_ALIAS = "KEK_AES_TEST";
    //  OpenJDK handles AES 256 just fine,but I had to lower this to 128 for
    //  Oracle's off-the-shelf JDK which has strong crypto disabled.
    private static int KEK_NUM_KEY_BITS = 128;
    //
    //  AES has a block size of 128 bits or 16 bytes.  Used easy HEX values so you can plug them
    //  into a website like http://aes.online-domain-tools.com/ to verify encrypted values.
    //
    private static final byte[] FIXED_128BIT_IV_FOR_TESTS =
            LunaUtils.hexStringToByteArray("DEADD00D8BADF00DDEADBABED15EA5ED");
    public static void main(String[] args) throws Exception {
        final String hostKeyType = "DESede";
        HsmManager.login();
        HsmManager.setSecretKeysExtractable(false);
        SecretKey kek = createNewHsmKek();
        out.println("HSM KEK ID (a handle,not in clear):\n\t" + getHex(kek.getEncoded()));
        SecretKey des3Key = createSoftwareKey(hostKeyType);
        out.println("Software-Only 3DES Key (in the clear):\n\t" + getHex(des3Key.getEncoded()));
        byte[] wrappedHostKey = wrapKeyWithKek(kek,des3Key);
        out.println("KEK wrapped 3DES key (host key):\n\t" + getHex(wrappedHostKey));
        out.println("\nStopping and starting session with HSM.");
        HsmManager.logout();
        out.println("Pretend that the host key was stored and restored from a database while disconnected\n");
        kek = null;
        des3Key = null;
        HsmManager.login();
        kek = getExistingHsmKek();
        SecretKey unwrapped3DesKey = unwrapKeyWithKek(kek,hostKeyType,wrappedHostKey);
        out.println("Unwrapped 3DES key is same as original (in clear):\n\t" + getHex(unwrapped3DesKey.getEncoded()));
        out.println("Class of unwrapped key: " + unwrapped3DesKey.getClass().getCanonicalName());
        //
        //  Give an example using using the unwrapped LunaSecretKey in both a software
        //  cipher operation and an HSM cipher operation.  If the LunaSecretKey was
        //  protected in hardware,the SunJCE operation with it would fail.
        //
        String plainText = "12345678";
        byte[] plainTextBytes = plainText.getBytes();
        out.println("Original plaintext:\n\t" + plainText);
        //  Start software cipher operation CKM_DES3_ECB
        Cipher sunJceCipher = Cipher.getInstance("DESede/ECB/NoPadding","LunaProvider");
        sunJceCipher.init(Cipher.ENCRYPT_MODE,unwrapped3DesKey);
        byte[] cipherText = sunJceCipher.doFinal(plainText.getBytes());
        out.println("SunJCE encryption result:\n\t" + getHex(cipherText));
        //  Start Luna HSM cipher operation
        Cipher lunaHsmCipher = Cipher.getInstance("DESede/ECB/NoPadding","LunaProvider");
        lunaHsmCipher.init(Cipher.DECRYPT_MODE,unwrapped3DesKey);
        byte[] originalClearText = lunaHsmCipher.doFinal(cipherText);
        out.println("LunaProvider HSM decrypt result:\n\t" + new String(originalClearText));
        HsmManager.logout();
    }
    //
    //  KEK is generated on HSM.  We never know its value,just it's alias to
    //  access it.
    //
    private static SecretKey createNewHsmKek()  throws GeneralSecurityException {
        if (HsmManager.hasSavedKey(KEK_ALIAS)) {
             return (SecretKey) HsmManager.getSavedKey(KEK_ALIAS);
        }
        KeyGenerator kg = KeyGenerator.getInstance("AES","LunaProvider");
        kg.init(KEK_NUM_KEY_BITS);
        LunaSecretKey kek = (LunaSecretKey) kg.generateKey();
        //
        //  Since our KEK will only be used for wrap and unwrap operations,we should
        //  disable encryption and decryption operations.
        //
        //  Note:  In theory,the commented out lines below will work on Luna SA
        //         firmwares 5.2 and above,but on our AWS CloudHSM firmware disabling
        //         encrypt and decrypt functionality will disable Cipher.WRAP_MODE
        //         and Cipher.UNWRAP_MODE respectively.  This is makes sense.
        //         If the unwrapped keys are not stored and protected on the HSM,//         wrapping and unwrapping operations *are* providing somewhat general
        //         encrypt and decrypt functionality.
        //
        //LunaTokenObject obj = LunaTokenObject.LocateObjectByHandle(kek.GetKeyHandle());
        //obj.SetBooleanAttribute(LunaAPI.CKA_ENCRYPT,false);
        //obj.SetBooleanAttribute(LunaAPI.CKA_DECRYPT,false);
        HsmManager.saveKey(KEK_ALIAS,kek);
        return kek;
    }
    private static SecretKey getExistingHsmKek() throws GeneralSecurityException {
        // casting KEY -> SecretKey
        return (SecretKey) HsmManager.getSavedKey(KEK_ALIAS);
    }
    //
    //  Create software-only (not stored on HSM) key
    //
    private static SecretKey createSoftwareKey(String keyType) throws GeneralSecurityException,UnsupportedEncodingException {
        //
        // SunJCE would be used by default when running openjdk 1.7,but I decided
        // to be explicit to ensure we are generating a key in software for this
        // example.
        String desKey = "0123456789abcdef0123456789abcdef0123456789abcdef"; // user value (24 bytes)  
        byte[] keyBytes = DatatypeConverter.parseHexBinary(desKey);
        SecretKeyFactory factory = SecretKeyFactory.getInstance("DESede");
        SecretKey key = factory.generateSecret(new DESedeKeySpec(keyBytes));
        return key;
//        KeyGenerator generator = KeyGenerator.getInstance(keyType,"SunJCE");
//        generator.init(new SecureRandom());
//        return generator.generateKey();
    }
    //
    // Wrap the passed in key with the KEK on the HSM
    //
    private static byte[] wrapKeyWithKek(SecretKey hsmKek,SecretKey softwareKey) throws GeneralSecurityException {
        Cipher wrappingCipher = Cipher.getInstance("AES/CBC/PKCS5Padding","LunaProvider");
        AlgorithmParameters algParams = AlgorithmParameters.getInstance("IV","LunaProvider");
        algParams.init(new IvParameterSpec(FIXED_128BIT_IV_FOR_TESTS));
        wrappingCipher.init(Cipher.WRAP_MODE,hsmKek,algParams);
        return  wrappingCipher.wrap(softwareKey);
    }
    //
    //  Unwrap the passed in key with the KEK on the HSM
    //
    private static SecretKey unwrapKeyWithKek(SecretKey hsmKey,String keyAlgorithm,byte[] wrappedKeyBytes) throws GeneralSecurityException {
        Cipher wrappingCipher = Cipher.getInstance("AES/CBC/PKCS5Padding","LunaProvider");
        algParams.init(new IvParameterSpec(FIXED_128BIT_IV_FOR_TESTS));
        wrappingCipher.init(Cipher.UNWRAP_MODE,hsmKey,algParams);
        return  (SecretKey) wrappingCipher.unwrap(wrappedKeyBytes,keyAlgorithm,Cipher.SECRET_KEY);
    }
    private static String getHex(byte array[]) {
        return "0x" + LunaUtils.getHexString(array,false).toUpperCase();
    }
}

参考:

https://thalesdocs.com/gphsm/luna/7.4/docs/network/Content/install/software/solaris_install.htm?Highlight=jre/lib/security/java.security#Java

https://thalesdocs.com/gphsm/luna/7.4/docs/network/Content/sdk/java/jsp_overview_install.htm

https://thalesdocs.com/gphsm/luna/7.4/docs/network/Content/sdk/java/luna_jsp_config.htm

https://github.com/dimalinux/HsmKeyWrappingExample/blob/master/src/main/java/to/noc/hsm/lunasa/example/KeyWrappingExample.java