pkcs#11内存错误 - 可能是什么常见原因?

时间:2010-07-12 11:04:54

标签: encryption memory-leaks cryptography pkcs#11 hsm

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

根据PKCS#11规范,CKR_DEVICE_MEMORY表示令牌没有足够的内存来执行请求的功能。

在什么情况下,我们是否让令牌的内存完全充满?

HSM已连续7天24小时不间断工作,主要是在白天加密和解密文件,并进行2次并行会话。我在过去7天内没有致电C_Finalize。所以cryptoki库从它的初始化点开始就在它的内存空间中工作(see a related post on this)。

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

更新1 :关于如何在ASP.NET的C_Finalize中调用Application_End,我有一个related detailed discussion。我不能使用它的主要原因是因为在循环/超时后,ASP.net线程访问单个会话导致CKR_OPERATION_ACTIVE错误。在我的情况下,多个应用程序通过Web服务访问HSM。

3 个答案:

答案 0 :(得分:4)

让我们分别考虑HSM和主机(Cryptoki库运行)的内存。正确实现的Cryptoki库应返回CKR_DEVICE_MEMORY,如果HSM设备缺少内存和CKR_HOST_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库不应该分配任何非堆栈内存。
  4. 这些估计仅用于说明此类库中存储器的一般问题。

答案 1 :(得分:1)

您提及here您没有关闭会话。如果这是真的,那很可能是CKR_DEVICE_MEMORY的原因。

答案 2 :(得分: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);

这是Decrypt方法。

公共字节[]解密(字节[] cryptonTextByteArray) {

    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;
}

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

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

有人帮助我吗? :)