首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >使用CKM_ECDH1_DERIVE和pkcs11interop的热机制

使用CKM_ECDH1_DERIVE和pkcs11interop的热机制
EN

Stack Overflow用户
提问于 2017-02-21 21:31:14
回答 1查看 2.1K关注 0票数 5

我买了一台NitroKey HSM,并想从EC那里得到一个秘密。以前的问题

为此,我想使用CKM_ECDH1_DERIVE机制。此HSM支持的内容,请参见:

在提到PKCS#11规范时,必须考虑:

  1. CKM_ECDH1_DERIVE机制必须与Derive函数一起使用(第188页)
  2. 机制CKM_ECDH1_DERIVE期望参数CK_ECDH1_DERIVE_PARAMS (Page222)具有以下参数:
    1. kdf:用于共享秘密值(CKD)的密钥派生函数
    2. sharedData:双方共享的一些数据
    3. publicData:另一方的EC公钥值

  3. 函数DeriveKey需要以下参数:
    1. 机制CKM.CKM_ECDH1_DERIVE
    2. ObjectHandle PrivateKey
    3. ObjectAttributes (第338页)
      1. CKA.CKA_CLASS -> CKO.CKO_SECRET_KEY
      2. CKA.CKA_KEY_TYPE -> CKK.CKK_GENERIC_SECRET
      3. 但是“但是,由于这些事实都隐含在机制中,所以没有必要指定其中的任何一个”,所以这些事实可以是空的吗?

问题

因此,有了这些信息,我尝试实现一个方法。

但我知道这个错误:

Net.Pkcs11Interop.Common.Pkcs11Exception :方法C_DeriveKey返回CKR_TEMPLATE_INCOMPLETE

Session.DeriveKey

CKR_TEMPLATE_INCOMPLETE的解释(第64页):

如果提供的模板中的属性值以及任何默认属性值和任何由对象创建函数本身贡献给对象的属性值都不足以完全指定要创建的对象,那么错误代码CKR_TEMPLATE_INCOMPLETE的尝试就会失败。

还有这里(第98页)

CKR_TEMPLATE_INCOMPLETE:为创建对象指定的模板是不完整的,并且缺少一些必要的属性。详情见10.1节。

但我用的是大赦的属性:

  1. CKA.CKA_CLASS -> CKO.CKO_SECRET_KEY
  2. CKA.CKA_KEY_TYPE -> CKK.CKK_GENERIC_SECRET

想法?

代码

代码语言:javascript
复制
private const string LibraryPath = @"C:\Windows\System32\opensc-pkcs11.dll";

public static byte[] Derive(string privateEc, string publicEc)
{
    Func<string, Session, CKO, ObjectHandle> getObjectHandle = (label, session, keyType) =>
    {
        var objectAttributes = new List<ObjectAttribute>
        {
            new ObjectAttribute(CKA.CKA_CLASS, keyType),
            new ObjectAttribute(CKA.CKA_LABEL, label),
            new ObjectAttribute(CKA.CKA_TOKEN, true)
        };

        return session.FindAllObjects(objectAttributes).First();
    };

    Func<ObjectHandle, Session, CKA, byte[]> getDataFromObject = (handle, session, type) =>
    {
        var attributes = new List<ulong> {(ulong) type};
        var requiredAttributes = session.GetAttributeValue(handle, attributes);
        return requiredAttributes[0].GetValueAsByteArray();
    };

    using (Pkcs11 pk = new Pkcs11(LibraryPath, false))
    {
        var slot = pk.GetSlotList(false).First();

        using (Session session = slot.OpenSession(false))
        {
            session.Login(CKU.CKU_USER, UserPin);

            var objectPrivate = getObjectHandle(privateEc, session, CKO.CKO_PRIVATE_KEY);
            var objectPublic = getObjectHandle(publicEc, session, CKO.CKO_PUBLIC_KEY);

            var publicKey = getDataFromObject(objectPublic, session, CKA.CKA_VALUE);

            byte[] data = session.GenerateRandom(32);
            var mechanism = new Mechanism(CKM.CKM_ECDH1_DERIVE, new CkEcdh1DeriveParams(1000, data, publicKey));

            var deriveAttributes = new List<ObjectAttribute>
            {
                new ObjectAttribute(CKA.CKA_CLASS, CKO.CKO_SECRET_KEY),
                new ObjectAttribute(CKA.CKA_KEY_TYPE, CKK.CKK_GENERIC_SECRET),
            };

            var derivedKey = session.DeriveKey(mechanism, objectPrivate, deriveAttributes);

            var derivedSecret = getDataFromObject(derivedKey, session, CKA.CKA_VALUE);

            Console.Out.WriteLine(Convert.ToBase64String(derivedSecret));

            return derivedSecret;
        }
    }
}

还请参见gist (相同代码) https://gist.github.com/dhcgn/4ea235cdb20155ec5ea9dc9bbf3c9887

更新

现在,通过更新的ObjectAttributes列表(答案是thx),我得到了异常Net.Pkcs11Interop.Common.Pkcs11Exception : Method C_DeriveKey returned CKR_DATA_LEN_RANGE

CKR_DATA_LEN_RANGE:加密操作的明文输入数据的长度很差。根据操作的机制,这可能意味着明文数据太短、太长,或者不是某个特定块的倍数。此返回值比CKR_DATA_INVALID具有更高的优先级。

对于CKA.CKA_VALUE_LEN,我尝试了不同的值,但没有成功:

代码语言:javascript
复制
CKA_VALUE_LEN
-------------
24 (192)
40 (320)
48 (384)

我偶然发现了公钥,我不确定我是否以正确的方式提取公钥。因为它有一个长度的664 Bit

CKA.CKA_VALUE of CKO.CKO_PUBLIC_KEY (664 Bit):

代码语言:javascript
复制
BFEEelKE3TrpE3e3f5nJATxEZrU0UeauhV/dFZXeXz5gqgZjuCtkJaUTainC/Mh357x3FyO7sGoPhzokD34oj5PJs0ItvATIKYtzvwaUkdZlDc0=

pkcs15-tool (864 Bit)提取

代码语言:javascript
复制
pkcs15-tool.exe --read-public-key 20
-----BEGIN PUBLIC KEY-----
MGowFAYHKoZIzj0CAQYJKyQDAwIIAQEJA1IABHpShN066RN3t3+ZyQE8RGa1NFHm
roVf3RWV3l8+YKoGY7grZCWlE2opwvzId+e8dxcju7BqD4c6JA9+KI+TybNCLbwE
yCmLc78GlJHWZQ3N
-----END PUBLIC KEY-----
  • 为什么pkcs15-toolCKO.CKO_PUBLIC_KEY之间的公钥不同?
  • CkEcdh1DeriveParamspublicData期望哪种格式?
  • 我用正确的方式提取publicData吗?或者什么是正确的方法?
  • CKA.CKA_VALUE_LEN的值必须等于我的EC (320 Bit)的长度吗?
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2017-02-21 22:02:14

这是一个非常好和完整的问题描述。

处理CKR_TEMPLATE_INCOMPLETE总是非常痛苦的,因为几乎每个库供应商都期望提供不同的属性集,而这个错误并没有显示丢失了哪些确切的属性。

在快速查看OpenSC源代码之后,我将尝试使用以下模板:

代码语言:javascript
复制
var deriveAttributes = new List<ObjectAttribute>
{
    new ObjectAttribute(CKA.CKA_TOKEN, false),
    new ObjectAttribute(CKA.CKA_CLASS, CKO.CKO_SECRET_KEY),
    new ObjectAttribute(CKA.CKA_KEY_TYPE, CKK.CKK_GENERIC_SECRET),
    new ObjectAttribute(CKA.CKA_SENSITIVE, false),
    new ObjectAttribute(CKA.CKA_EXTRACTABLE, true),
    new ObjectAttribute(CKA.CKA_ENCRYPT, true),
    new ObjectAttribute(CKA.CKA_DECRYPT, true),
    new ObjectAttribute(CKA.CKA_WRAP, true),
    new ObjectAttribute(CKA.CKA_UNWRAP, true),
    new ObjectAttribute(CKA.CKA_VALUE_LEN, ???)
};

但是,我不确定CKA_VALUE_LEN属性的正确值是什么。

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

https://stackoverflow.com/questions/42378394

复制
相关文章

相似问题

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