2

pkcs11interop を使用して 3DES キーを作成し、作成するキー値を指定するか、それともキーを作成し、生成されたキー値を出力することができるかどうか疑問に思っていました。基本的に、秘密鍵を別のデバイスにエクスポートする必要があります。

CKA_VALUE 属性を使用してキーを byte[] 配列として渡そうとしましたが、成功しませんでした。

そのようなことは可能ですか?誰か助けてくれませんか?

編集:

これまでのところ運が悪いコードは次のとおりです。

public ObjectHandle generate3DESKey(string keyLabel)
{
ObjectHandle key = null;
// Generate symetric key 

// Prepare attribute template of new key
List<ObjectAttribute> objectAttributes = new List<ObjectAttribute>();
objectAttributes.Add(new ObjectAttribute(CKA.CKA_TOKEN, true));
objectAttributes.Add(new ObjectAttribute(CKA.CKA_CLASS, CKO.CKO_SECRET_KEY));
objectAttributes.Add(new ObjectAttribute(CKA.CKA_KEY_TYPE, CKK.CKK_DES3));
objectAttributes.Add(new ObjectAttribute(CKA.CKA_ENCRYPT, true));
objectAttributes.Add(new ObjectAttribute(CKA.CKA_EXTRACTABLE, true));

objectAttributes.Add(new ObjectAttribute(CKA.CKA_LABEL, keyLabel));


// Specify key generation mechanism
Mechanism mechanism = new Mechanism(CKM.CKM_DES3_KEY_GEN);

// Generate key
key = _session.GenerateKey(mechanism, objectAttributes);

List<CKA> retrieveTemplate = new List<CKA>();
retrieveTemplate.Add(CKA.CKA_VALUE);

var test = _session.GetAttributeValue(key, retrieveTemplate);
var testval = test[0].GetValueAsString();
return key;
}

このコードで私が試みているのは、3DES キーを作成し、次に示すように GetAttributeValue を使用してその値を取得することです。GetValueAsByteArray と GetValueAsString を試しましたが、すべて成功しませんでした。私が気付いたのは、作成時に抽出可能な属性を設定したにもかかわらず、取得した属性の cantread プロパティが true に設定されていることです。

これとは別に、3DES キーの生成時にキー値を渡すことも検討しましたが、私を困惑させたのは、CKA.CKA_VALUE で使用されるキー値は長さ 24 のバイト配列である必要があるとドキュメントに記載されているという事実です。作成する必要がある長さは 24 ではなく 16 です。これに似たキーを作成したいと思います。これはここで 16 進数で表されます: 1616161616161616 1010101010101010

4

1 に答える 1

0

メソッドで秘密鍵をインポートできますSession::CreateObject()。PKCS#11 仕様で定義されているように、正しいオブジェクト属性を指定する必要があります。

プレーンな形式の秘密鍵は、メソッドでエクスポートできますSession::GetAttributeValue()。プレーンな値を読み取れるようにするには、キー オブジェクトに正しい属性を指定する必要があります。

少なくともPKCS#11 v2.20 仕様の「第 10 章 - オブジェクト」「第 12.15.3 章 - DES3 秘密鍵オブジェクト」を読んでから、問題を解決できない可能性があるコードを投稿してください。

次のコード サンプルは、SoftHSM 2.1.0の魅力のように機能します。

using Net.Pkcs11Interop.Common;
using Net.Pkcs11Interop.HighLevelAPI;
using System;
using System.Collections.Generic;

namespace ExportTest
{
    class Program
    {
        static void Main(string[] args)
        {
            using (Pkcs11 pkcs11 = new Pkcs11(@"D:\SoftHSM2\lib\softhsm2.dll", false))
            {
                Slot slot = pkcs11.GetSlotList(true)[0];

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

                    // Generate exportable key
                    List<ObjectAttribute> objectAttributes = new List<ObjectAttribute>();
                    objectAttributes.Add(new ObjectAttribute(CKA.CKA_LABEL, "Generated key"));
                    objectAttributes.Add(new ObjectAttribute(CKA.CKA_CLASS, CKO.CKO_SECRET_KEY));
                    objectAttributes.Add(new ObjectAttribute(CKA.CKA_KEY_TYPE, CKK.CKK_DES3));
                    objectAttributes.Add(new ObjectAttribute(CKA.CKA_TOKEN, true));
                    objectAttributes.Add(new ObjectAttribute(CKA.CKA_ENCRYPT, true));
                    objectAttributes.Add(new ObjectAttribute(CKA.CKA_DECRYPT, true));
                    objectAttributes.Add(new ObjectAttribute(CKA.CKA_EXTRACTABLE, true));

                    ObjectHandle generatedKey = null;
                    using (Mechanism mechanism = new Mechanism(CKM.CKM_DES3_KEY_GEN))
                        generatedKey = session.GenerateKey(mechanism, objectAttributes);

                    // Export the key
                    byte[] plainKeyValue = null;
                    List<ObjectAttribute> readAttrs = session.GetAttributeValue(generatedKey, new List<CKA>() { CKA.CKA_VALUE });
                    if (readAttrs[0].CannotBeRead)
                        throw new Exception("Key cannot be exported");
                    else
                        plainKeyValue = readAttrs[0].GetValueAsByteArray();

                    // Import the key
                    objectAttributes = new List<ObjectAttribute>();
                    objectAttributes.Add(new ObjectAttribute(CKA.CKA_LABEL, "Imported key"));
                    objectAttributes.Add(new ObjectAttribute(CKA.CKA_CLASS, CKO.CKO_SECRET_KEY));
                    objectAttributes.Add(new ObjectAttribute(CKA.CKA_KEY_TYPE, CKK.CKK_DES3));
                    objectAttributes.Add(new ObjectAttribute(CKA.CKA_TOKEN, true));
                    objectAttributes.Add(new ObjectAttribute(CKA.CKA_ENCRYPT, true));
                    objectAttributes.Add(new ObjectAttribute(CKA.CKA_DECRYPT, true));
                    objectAttributes.Add(new ObjectAttribute(CKA.CKA_VALUE, plainKeyValue));

                    ObjectHandle importedKey = session.CreateObject(objectAttributes);

                    // Test encryption with generated key and decryption with imported key
                    using (Mechanism mechanism = new Mechanism(CKM.CKM_DES3_CBC, session.GenerateRandom(8)))
                    {
                        byte[] sourceData = ConvertUtils.Utf8StringToBytes("Our new password");
                        byte[] encryptedData = session.Encrypt(mechanism, generatedKey, sourceData);
                        byte[] decryptedData = session.Decrypt(mechanism, importedKey, encryptedData);
                        if (Convert.ToBase64String(sourceData) != Convert.ToBase64String(decryptedData))
                            throw new Exception("Encryption test failed");
                    }

                    session.Logout();
                }
            }
        }
    }
}
于 2016-09-30T19:15:13.380 に答える