2

I'm trying to use Pkcs11Interop to extract the value of the key from the HSM. I know, the key has to stay in the HSM, but I need it, so...

I already do it with NCryptoki and I'd like to do it also with Pkcs11Interop

I tried this code:

// Prepare attribute template that defines search criteria
List<ObjectAttribute> objectAttributes = new List<ObjectAttribute>();
objectAttributes.Add(new ObjectAttribute(CKA.CKA_CLASS, CKO.CKO_SECRET_KEY));
objectAttributes.Add(new ObjectAttribute(CKA.CKA_KEY_TYPE, CKK.CKK_DES));
objectAttributes.Add(new ObjectAttribute(CKA.CKA_LABEL, "MY_KEY"));

// Find all objects that match provided attributes
List<ObjectHandle> foundObjects = session.FindAllObjects(objectAttributes);

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

But the plainKeyValue is all zeros, but, as you can imagine, this is not true.

SO, how can I reach my goal?

Piero Alberto
  • 3,823
  • 6
  • 56
  • 108
  • The code is working, but only with key with "sensistive=true". This is right. But, I know I can "wrap and unwrap" the key to get anyway its value, how can I do it here? – Piero Alberto Nov 30 '17 at 09:14
  • 1
    Exporting the the key value to plain text (your code is doing that) and wrapping/unwrapping the key are two very different opreations. If you receive zeros as the key value then they were send by PKCS#11 library provided by HSM vendor and I doubt NCryptoki would receive anything else than Pkcs11Interop. Maybe you could add NCryptoki code you are trying to translate? It should help me better understand what you are trying to achieve because right now I am little lost. – jariq Nov 30 '17 at 09:34
  • Thanks for the reply jariq. Look my answer, I solved in that way. Now I have another big trouble, I will post a dedicated question and then write a comment here with the link. – Piero Alberto Nov 30 '17 at 10:34
  • @jariq this is the new question https://stackoverflow.com/questions/47571378/pkcs11exception-method-c-initialize-returned-2147483907 – Piero Alberto Nov 30 '17 at 10:40

1 Answers1

3

I solved it with this code

static public byte[] findTargetKeySValue(String label, String type, string command)
{
    try
    {
        string pkcs11LibraryPath = @"C:\Program Files\SafeNet\Protect Toolkit 5\Protect Toolkit C SDK\bin\hsm\cryptoki.dll";
        Utility.Logger("cryptoki dll path " + pkcs11LibraryPath, command);
        using (Pkcs11 pkcs11 = new Pkcs11(pkcs11LibraryPath, Inter_Settings.AppType))
        {
            // Find first slot with token present
            Slot slot = Inter_Helpers.GetUsableSlot(pkcs11);
            // Open RW session
            using (Session session = slot.OpenSession(SessionType.ReadOnly))
            {
                // Login as normal user
                session.Login(CKU.CKU_USER, Inter_Settings.NormalUserPin);
                // Prepare attribute template that defines search criteria
                List<ObjectAttribute> objectAttributes = new List<ObjectAttribute>();
                objectAttributes.Add(new ObjectAttribute(CKA.CKA_CLASS, CKO.CKO_SECRET_KEY));
                if (type == "DES")
                    objectAttributes.Add(new ObjectAttribute(CKA.CKA_KEY_TYPE, CKK.CKK_DES));
                else if (type == "DES2")
                    objectAttributes.Add(new ObjectAttribute(CKA.CKA_KEY_TYPE, CKK.CKK_DES2));
                else if (type == "DES3")
                    objectAttributes.Add(new ObjectAttribute(CKA.CKA_KEY_TYPE, CKK.CKK_DES3));
                objectAttributes.Add(new ObjectAttribute(CKA.CKA_LABEL, label));//PROVAK

                List<ObjectHandle> foundObjects = session.FindAllObjects(objectAttributes);
                var key = foundObjects[0];
                byte[] plainKeyValue = null;
                List<ObjectAttribute> readAttrsSensitive = session.GetAttributeValue(key, new List<CKA>() { CKA.CKA_SENSITIVE });
                if (!readAttrsSensitive[0].GetValueAsBool())
                {
                    Utility.Logger("findTargetKeySValue chiave " + label + " non senstive", command);
                    List<ObjectAttribute> readAttrs = session.GetAttributeValue(key, new List<CKA>() { CKA.CKA_VALUE });
                    if (readAttrs[0].CannotBeRead)
                        throw new Exception("Key cannot be exported");
                    else
                        plainKeyValue = readAttrs[0].GetValueAsByteArray();
                    //Console.WriteLine(ByteArrayToAsciiHEX(plainKeyValue));
                    session.Logout();
                    return plainKeyValue;
                }
                else
                {
                    Utility.Logger("findTargetKeySValue chiave " + label + " senstive", command);
                    Console.WriteLine("wrap/unwrap");
                    objectAttributes = new List<ObjectAttribute>();
                    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_LABEL, "WRAPPING_KEY")); //WRAPPING_KEY WRK
                    foundObjects = session.FindAllObjects(objectAttributes);

                    var wrappingKey = foundObjects[0];
                    Mechanism m = new Mechanism(CKM.CKM_DES3_ECB);

                    var wrapped = session.WrapKey(m, wrappingKey, key);
                    //Console.WriteLine("wrapped " + ByteArrayToAsciiHEX(wrapped));

                    //Console.WriteLine(ByteArrayToAsciiHEX(session.Decrypt(m, wrappingKey, wrapped)));
                    var k = session.Decrypt(m, wrappingKey, wrapped); 
                    session.Logout();
                    return k;

                }
            }
        }
    }
    catch (Exception e)
    {
        //Console.WriteLine(e.ToSafeString());
        Utility.Logger("findTargetKeySValue " + e.ToSafeString(), command);
        return null;
    }
}
Piero Alberto
  • 3,823
  • 6
  • 56
  • 108
  • 1
    I face the same problem. But my problem is still unresolved.   session.Login (CKU.CKU_SO, "Elpo2014"); Could you help me with this code, I do not know where I'm making mistakes .. – TEngineer Mar 31 '18 at 08:37
  • Why do you login as CKU_SO and not as CKO_USER? – Piero Alberto Apr 03 '18 at 06:05