0

我想使用 PKCS#11 和 SafeNet HSM 设备加密大量明文。我将每个明文一一加密需要很长时间。

所以我想到了 PKCS#11 中是否有任何方法可以一次加密多个数据?

我在使用 PKCS #11 API 的 SafeNet C 编程手册中找到了以下用于加密多部分数据的示例。

/* read, encrypt, digest and write the cipher text in chunks
*/ totbw = 0;
for ( ;; ) {
    br = fread(buffer, 1, sizeof(buffer), ifp);
    if ( br == 0 )
        break;
    
    /* digest */

    /* encrypt */
    curLen = sizeof(encbuffer);
    rv = C_EncryptUpdate(hrSession, buffer, (CK_SIZE)br, encbuffer, &curLen);
    CHECK_RV(FN "C_EncryptUpdate", rv);
    if (rv) return 1;
    
    /* write cipher text */
    br = fwrite(encbuffer, 1, (int)curLen, ofp);
    totbw += br;
}

该手册中提到:

对于加密,我们使用C_EncryptUpdate,它继续进行多部分加密操作,处理另一个数据部分。

我想知道这种方法是否可用于一次加密多个明文,或者它将所有缓冲区元素视为相同输入数据的块?

我正在寻找一种可以加密多个明文但将它们视为单独项目(而不是大单个项目的块)的解决方案。

4

2 回答 2

2

它将所有数据视为一个输入的块。它用于将数据加密为流。因此,如果您认为可以使用它来并行化您的加密过程,那您就错了。

顺便说一句,您使用什么机制进行加密?不要告诉我你只是直接使用非对称算法(如 RSA)。如果您这样做,这就是您的加密过程非常缓慢的原因。

更新:

在我的脑海中,你可以尝试这样的事情:

1-Genrate a random number using C_GenerateRandom.
2-Encrypt this random using HSM.
3-Use this encrypted random to encrypt your data locally.
4-Send encrypted data and non-encrypted random number to other side.

对方可以对接收到的随机数进行加密以获得加密密钥并对接收到的加密数据进行解密。

我应该说这是一个 30 秒的设计,它应该考虑其他关键部分(如时间戳)。但我想展示如何在不过度使用 HSM 卡的情况下做到这一点。

于 2021-10-13T07:59:19.903 回答
0

我有这个解决方案给你,这是两个部分:

    1. 在您的硬件中加密。这应该解决 JAVA 中的白色线程。
    1. 在您的加密程序中只使用一次 HSM 的 Salt Concept。

-------- 在您的硬件中(# CP´s)运行一个程序来加密 AES256 ----- 但是使用 HSM 获取令牌或 numberRandom,这将是我们的 SALT。

    import java.io.Serializable;
    import java.nio.charset.StandardCharsets;
    import java.security.spec.KeySpec;
    import java.util.Base64;
    import javax.crypto.Cipher;
    import javax.crypto.SecretKey;
    import javax.crypto.SecretKeyFactory;
    import javax.crypto.spec.IvParameterSpec;
    import javax.crypto.spec.PBEKeySpec;
    import javax.crypto.spec.SecretKeySpec;

    public class Encrypt implements Serializable {

        private static final String secretKeyAES = "My_Long_bytes_to_cipher";
        private static final String saltAES = "My_Salt_only_one_time_for_20M_ByHMS_Random";

        public Encrypt() {
}

public String getAES(String data) {
    try {
        byte[] iv = new byte[16];
        IvParameterSpec ivParameterSpec = new IvParameterSpec(iv);
        SecretKeyFactory secretKeyFactory = SecretKeyFactory.getInstance("PBKDF2WithHmacSHA256");
        KeySpec keySpec = new PBEKeySpec(secretKeyAES.toCharArray(), saltAES.getBytes(), 65536, 256);
        SecretKey secretKeyTemp = secretKeyFactory.generateSecret(keySpec);
        SecretKeySpec secretKey = new SecretKeySpec(secretKeyTemp.getEncoded(), "AES");
        Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
        cipher.init(Cipher.ENCRYPT_MODE, secretKey, ivParameterSpec);
        return Base64.getEncoder().encodeToString(cipher.doFinal(data.getBytes("UTF-8")));
    } catch (Exception e) {
        e.printStackTrace();
    }
    return null;
}

public String getAESDecrypt(String data) {
    byte[] iv = new byte[16];
    try {
        IvParameterSpec ivParameterSpec = new IvParameterSpec(iv);
        SecretKeyFactory secretKeyFactory = SecretKeyFactory.getInstance("PBKDF2WithHmacSHA256");
        KeySpec keySpec = new PBEKeySpec(secretKeyAES.toCharArray(), saltAES.getBytes(), 65536, 256);
        SecretKey secretKeyTemp = secretKeyFactory.generateSecret(keySpec);
        SecretKeySpec secretKey = new SecretKeySpec(secretKeyTemp.getEncoded(), "AES");
        Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
        cipher.init(Cipher.DECRYPT_MODE, secretKey, ivParameterSpec);
        return new String(cipher.doFinal(Base64.getDecoder().decode(data)));
    } catch (Exception e) {
        e.printStackTrace();
    }
    return null;
}
    }

-----这个答案解决了 HSM 请愿,但现在您应该在 JAVA 中解决 whit 请愿。

最多的处理将在 CPU 端完成

于 2021-10-18T01:47:28.113 回答