如何使用位于java中的Safenet HSM Luna SA设备的公钥/私钥加密/解密数据

时间:2017-11-29 14:01:21

标签: java encryption cryptography hsm

我需要使用位于Safenet HSM Luna SA设备中的公钥加密数据,还需要使用也位于JAVA中的HSM设备中的私钥来解密数据。

我对HSM设备完全陌生。我使用位于epass电子令牌设备中的密钥加密/解密数据,如下所示:

   private void loadKeys() {

    logger.info("In loadKeys method at "+new Date());
    try {
        char password[] = hsmServiceAppProps.getDigiSigPfxPassword().toCharArray();
        Provider userProvider = new sun.security.pkcs11.SunPKCS11(this.getClass().getClassLoader().getResourceAsStream("/pkcs11.cfg"));
        Security.addProvider(userProvider);
        KeyStore ks = KeyStore.getInstance("PKCS11");
        ks.load(null, password);

        String alias = null;
        /*X509Certificate userCert = null;
        PrivateKey userCertPrivKey = null;
        PublicKey userCertPubKey = null;
        Enumeration<String> e = ks.aliases();
        while (e.hasMoreElements()) {
            alias = (String) e.nextElement();
            logger.info("Alias of the e-Token : " + alias);
            userCert = (X509Certificate) ks.getCertificate(alias);
            userCertPubKey = (PublicKey) ks.getCertificate(alias).getPublicKey();
            userCertPrivKey = (PrivateKey) ks.getKey(alias, password);
        }*/
        alias = "*************************************";

        //X509Certificate certificate = (X509Certificate) ks.getCertificate(alias);
        publicKey = (PublicKey) ks.getCertificate(alias).getPublicKey();
        privateKey = (PrivateKey) ks.getKey(alias, password);

    } catch (Exception e) {
        logger.error("Error while getting public and private keys ->> ",e);
    }
}

private String performEncryption(String content,PublicKey publicKey) throws Exception {
    logger.debug("Encrypting using public key : "+content);
    Cipher publicEncryptCipher = Cipher.getInstance("RSA");
    publicEncryptCipher.init(Cipher.ENCRYPT_MODE, publicKey);
    byte[] encryptedBinaryData = publicEncryptCipher.doFinal(content.getBytes());
    Base64 encoder = new Base64();
    String encodedEncryptedContent =  new String(encoder.encode(encryptedBinaryData),"UTF-8");
    logger.debug("Encrypted Content ->> "+encodedEncryptedContent);
    return encodedEncryptedContent;
}

private String performDecryption(String encodedEncryptedContent, PrivateKey privateKey) throws Exception {
    logger.debug("Decrypting with private key ->> "+encodedEncryptedContent);
    Base64 decoder = new Base64();
    byte[] encryptedString = decoder.decode(encodedEncryptedContent.getBytes());
    Cipher privateDecryptCipher = Cipher.getInstance("RSA");
    privateDecryptCipher.init(Cipher.DECRYPT_MODE, privateKey);
    byte[] decryptedBinaryData = privateDecryptCipher.doFinal(encryptedString);
    String decryptedContent = new String(decryptedBinaryData,"UTF-8");
    logger.debug("Decrypted Content ->> "+decryptedContent);
    return decryptedContent;
}

我需要使用HSM设备进行加密/解密。我已经将Luna客户端软件和导入的密钥安装到HSM设备上。

任何人都可以帮助我

2 个答案:

答案 0 :(得分:0)

成功安装Luna客户端后。您可以使用Luna JSP或JCProv库通过使用HSM上的密钥在HSM上执行加密操作。 要检查Luna客户端是否已正确安装并向远程HSM注册,可以从luna客户端目录运行以下命令:“ VTL.exe verify”。 Output of successfully VTL verify

这里是使用RSA的公钥和私钥进行加密和解密的示例。

 void asymetricEncDec(CK_SESSION_HANDLE session, CK_OBJECT_HANDLE hPublicKey,
                          CK_OBJECT_HANDLE hPrivateKey)
{
    //session - handle to an open session
    //hPublicKey - handle to public asymetric key to use for encryption
    //hPrivateKey - handle to private asymetric key to use for decryption

    String startString = "this is 16 bytes";
    byte[] plainText = startString.getBytes();
    byte[] cipherText = null;
    LongRef lRefEnc = new LongRef();
    LongRef lRefDec = new LongRef();

    //mechanism to use
    CK_MECHANISM mechanism = new CK_MECHANISM(CKM.RSA_PKCS);

    /* get ready to encrypt */
    CryptokiEx.C_EncryptInit(session, mechanism, hPublicKey);

    /* get the size of the cipher text */
    CryptokiEx.C_Encrypt(session, plainText, plainText.length, null,
            lRefEnc);

    /* allocate space */
    cipherText = new byte[(int)lRefEnc.value];

    /* encrypt */
    CryptokiEx.C_Encrypt(session, plainText, plainText.length, cipherText,
            lRefEnc);

    /* get ready to decrypt */
    CryptokiEx.C_DecryptInit(session, mechanism, hPrivateKey);

    /* get the size of the plain text */
    CryptokiEx.C_Decrypt(session, cipherText, lRefEnc.value, null, lRefDec);

    /* allocate space */
    plainText = new byte[(int)lRefDec.value];

    /* decrypt */
    CryptokiEx.C_Decrypt(session, cipherText, lRefEnc.value, plainText,
            lRefDec);

    /* make sure that we end up with what we started with */
    String endString = new String(plainText, 0, (int)lRefDec.value);

    if (startString.compareTo(endString) == 0)
    {
        println("Decrypted string matches original string - hurray");
    }
    else
    {
        println("Decrypted string does not match original string - boo");
    }
}

此示例使用luna客户端提供的JCProv库。注意:JCProv较低层库接近PKCS#11的“ C”实现。

答案 1 :(得分:0)

您还可以使用IAIK PKCS#11包装器在HSM上进行各种操作。包装器是开源的。有充分的文档证明,并提供了可用的代码示例。

参考:https://jce.iaik.tugraz.at/products/core-crypto-toolkits/pkcs11-wrapper/