问题
I am using PKCS11 Compliant Crypto Device which secures my Private Key. The Crypto Device is capable of generating 500 RSA-2048 Bit Signings per second. I have written an application in C#.NET interfaced with PKCS11Interop Wrapper. Here is my code:
#region Initialization
Pkcs11 pkcs11 = new Pkcs11(pkcsLibraryPath, true);
Slot slot = pkcs11.GetSlotList(true)[slotIndex];
Session session = slot.OpenSession(false);
session.Login(CKU.CKU_USER, hsmPIN);
List<ObjectAttribute> searchObject = new List<ObjectAttribute>(2);
searchObject.Add(new ObjectAttribute(CKA.CKA_CLASS,(uint)CKO.CKO_PRIVATE_KEY));
searchObject.Add(new ObjectAttribute(CKA.CKA_LABEL, keyLabelName));
ObjectHandle privateKeyHandle = session.FindAllObjects(searchObject)[0];
byte[] dataToBeSigned = new byte[500];
byte[] signature = new byte[dataToBeSigned.Length];
#endregion Initialization
#region SEQUENTIAL Signing Loop
for(int i = 0; i<500;i++)
{
signature[i] = session.Sign(new Mechanism(CKM.CKM_SHA256_RSA_PKCS_PSS) , privateKeyHandle , dataToBeSigned[i]);
}
#endregion SEQUENTIAL Signing Loop
#region UNMANAGED Parallel Loop
Parallel.For(0, dataToBeSigned.Length, index =>
{
signature[index] = session.Sign(new Mechanism(CKM.CKM_SHA256_RSA_PKCS_PSS) , privateKeyHandle , dataToBeSigned[index]);
});
#endregion UNMANAGED Parallel Loop
#region MANAGED Parallel Loop
Parallel.For(0, dataToBeSigned.Length, index =>
{
lock(session)
{
signature[index] = session.Sign(new Mechanism(CKM.CKM_SHA256_RSA_PKCS_PSS) , privateKeyHandle , dataToBeSigned[index]);
}
});
#endregion MANAGED Parallel Loop
Here you go!!
With the Sequential Signing Loop region, I can achieve just 250-280 Signings, but never the speed of 500signings as specified by my Crypto OEM. At least I need 440~480 signings per second. How can I achieve this using a Sequential 'for' loop?
Why does my UNMANAGED Parallel loop throw an exception always? Even if I handle those exception, 40% of signings are getting failed (session.Sign() function returns null). Why is it so?
With "MANAGED Parallel Loop" code, I can achieve max speed of 280, as I got with Sequential Signing Loop. Why my MANAGED Parallel loop is slow? Is it because of 'lock'? If I remove the lock, it becomes UNMANAGED PARALLEL LOOP. How can I handle this?
If you feel, my multithreading coding (and entire PKCS11 programming and operations) is wrong, please suggest me some method to achieve maximum speed.
If you feel, there could be a problem with PCKS11Interop Wrapper which is not letting me to achieve the speed, please suggest some other wrappers. I used NCryptoki, Pkcs11.Net Wrappers, but I could not achieve max speed.
I am 100% confident that my PKCS11 Compliant device is capable of generating 500Signings. I confirmed this with my OEM. Only, when I operate the device through programmatically (either C# or Java), my speed goes down.
I request experts of this forum to clarify me on above 6 points.
Many Thanks.
Karthick
回答1:
You need to create new Session
for each signing operation.
Please read "Chapter 6 - General overview" of PKCS#11 v2.20 specification. All basic concepts of PKCS#11 API (including thread/operation isolation provided by sessions) are explained there.
After you finish this mandatory reading, you can take a look at Pkcs11RsaSignature class in Pkcs11Interop.PDF project for a working code sample.
来源:https://stackoverflow.com/questions/43203573/multi-threaded-signature-generation-c-sharp