【问题标题】:How to encrypt/decrypt data using public/private keys located at Safenet HSM Luna SA device in java如何使用位于 Java 中 Safenet HSM Luna SA 设备的公钥/私钥加密/解密数据
【发布时间】:2018-05-13 06:27:22
【问题描述】:

我需要使用位于 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 设备。

谁能帮帮我

【问题讨论】:

  • 假设您的 HSM 是 PKCS#11 设备,您只需重新配置加载的配置文件。你试过什么?

标签: java encryption cryptography hsm


【解决方案1】:

成功安装 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”实现。

【讨论】:

    【解决方案2】:

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

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

    【讨论】:

      猜你喜欢
      • 2011-07-24
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-12-31
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多