首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何在java中使用Safenet HSM露娜SA设备上的公钥/私钥对数据进行加密/解密

如何在java中使用Safenet HSM露娜SA设备上的公钥/私钥对数据进行加密/解密
EN

Stack Overflow用户
提问于 2017-11-29 22:01:21
回答 2查看 2.8K关注 0票数 0

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

我对HSM设备完全陌生。我已使用位于epass e-token设备中的密钥加密/解密数据,如下所示:

代码语言:javascript
复制
   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设备进行加密/解密。我已经安装了露娜客户端软件,并将密钥导入HSM设备。

有人能帮帮我吗?

EN

回答 2

Stack Overflow用户

发布于 2018-07-23 17:43:29

一旦您成功安装了露娜客户端。您可以使用露娜JSP或JCProv库通过驻留在HSM上的密钥对HSM执行加密操作。要检查露娜客户端是否已安装并正确注册到远程HSM,您可以在您的露娜客户端目录下运行以下命令:"VTL.exe verify“。Output of successfully VTL verify

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

代码语言:javascript
复制
 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");
    }
}

本示例使用的是露娜客户端提供的JCProv库。注意:与PKCS#11的'C‘实现接近的是JCProv低级库。

票数 0
EN

Stack Overflow用户

发布于 2020-05-21 01:09:52

您还可以使用IAIK包装器对PKCS#11执行各种操作。包装器是开源的。它有很好的文档,并且有可用的工作代码示例。

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

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/47554595

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档