3

我正在使用 cryptoki 库CKR_DEVICE_MEMORY获取调用错误代码。C_Encrypt

从 PKCS#11 规范中,CKR_DEVICE_MEMORY意味着令牌没有足够的内存来执行请求的功能。

在什么情况下,我们会得到token的内存完全满了?

HSM 连续 7 天 24 小时不间断地工作,主要是在白天通过 2 个并行会话加密和解密文件。过去 7 天我没有打电话C_Finalize。所以cryptoki库从它被初始化的那一刻起就一直在它的内存空间中工作(参见相关的帖子)。

我可以从我的应用程序、调试日志中看到,我正在分配、正在解除分配,所以我的应用程序代码没有内存泄漏。

更新 1:关于如何调用ASP.NET有一个相关的详细讨论。我无法使用它的主要原因是在回收/超时后,ASP.net 线程访问单个会话导致 CKR_OPERATION_ACTIVE 错误。在我的情况下,多个应用程序正在通过 Web 服务访问 HSM。C_FinalizeApplication_End

4

3 回答 3

3

让我们分别考虑 HSM 和主机(运行 Cryptoki 库)的内存。如果 HSM 设备内存不足,正确实现的 Cryptoki 库应该返回 CKR_DEVICE_MEMORY,如果 Cryptoki 库无法为其内部结构分配主机内存(如果它被实现为共享库,则进程无法分配内存) . 因此,如果您的 pkcs11 库正确实现,那么 CKR_DEVICE_MEMORY 字面意思是设备(HSM)内存不足。出现此类错误的原因有很多。我们不能考虑所有分支。可以只限制一些问题。回答您的问题,Cryptoki 库中内存出现问题的三个主要原因是:

  1. 用于加密操作的内存。Cryptoki 的客户端负责分配这样的内存,而不是 Cryptoki 库。例如,Cryptoki 库的客户端必须在调用 C_EncryptFinal 之前为最终结果分配缓冲区。如果缓冲区大小不够,则 Cryptoki 返回 CKR_BUFFER_TOO_SMALL。
  2. HSM 内存。CKR_DEVICE_MEMORY 指向这种情况,但它超出了大多数软件开发人员的控制范围。
  3. Cryptoki 库中内部服务结构的内存。例如,当您打开会话时,会为此结构分配内存。当您在同一会话中停止加密过程并开始解密时,此会话的模式会发生变化。Cryptoki 库应该支持调用之间的内部状态,因为它支持多部分迭代操作。当从一种操作切换到另一种操作时,它应该释放以前的结构并在内存中分配新的结构,如堆。如果应用程序开发人员有库资源或想要帮助查找错误,那么在这种情况下值得遵循(对于这个特定事件,假设库错误地报告 CKR_DEVICE_MEMORY 而不是 CKR_HOST_MEMORY)。尝试仅针对一种操作(例如加密)运行程序。如果它在上述时间段内没有内存错误,则可能在更改操作类型时发生内存泄漏。但是您说:“一个会话用于加密,另一个用于解密”。它缩小了范围。可能用于存储多部分操作泄漏状态的内存。多次操作后监控内存量。如果您不使用多部分操作,那么很可能是情况 2,因为 Cryptoki 库在这种情况下不应分配任何非堆栈内存。

这些估计仅用于说明此类库中内存的一般问题。

于 2014-10-16T23:33:14.300 回答
1

在这里提到你没有关闭你的会话。如果这是真的,那很可能是CKR_DEVICE_MEMORYs 的原因。

于 2010-07-12T13:13:33.927 回答
0

我也有这个问题,年份是 2020 年:S .Net Framework + Rest Api 夫妇这次有这个问题。我正在使用 HSM 进行解密方法。我有一个登录方法交互频道,我们需要进行性能测试。该服务有一个来自 Pkcs11 的实例

pkcs11 = new Pkcs11(hsmPath, true);
slot = GetUsableSlot(pkcs11);
TokenInfo tokenInfo = slot.GetTokenInfo();
session = slot.OpenSession(true);
session.Login(CKU.CKU_USER, userLoginPin);
secretKey = GenerateKey(session);

这就是解密方法。

公共字节[]解密(字节[]加密文本字节数组){

    Mechanism mechanism = new Mechanism(CKM.CKM_AES_ECB);
    byte[] sourceData = encryptedTextByteArray;
    byte[] decryptedData = null;

    using (MemoryStream inputStream = new MemoryStream(sourceData), outputStream = new MemoryStream())
    {
        try
        {                
            session.Decrypt(mechanism, secretKey, inputStream, outputStream, 4096);
        }
        catch (Pkcs11Exception ex)
        {
            throw;
        }
        decryptedData = outputStream.ToArray();
    }
    return decryptedData;
}

当我尝试使用 Postman runner 进行性能测试时,一个线程没有问题。如果我增加线程数,就会出现这些错误。第一个错误:CKR_OPERATION_ACTIVE 下一个错误:CKR_DEVICE_MEMORY

我试过这些方法。- 对于每个请求关闭会话。并且还为新请求打开了会话。但没有成功。出现了同样的错误。(当然请求和响应时间增加了) - 因为每个请求都关闭了连接。并且还为新请求打开了新连接。出现了同样的错误。(当然请求和响应时间增加了)

有人帮助我吗?:)

于 2020-06-04T17:37:52.017 回答