This tutorial shows how to accomplish the following PKCS#11 procedures:
- Instanciate and Initialize a Cryptoki object
- Read available slots
- Open and Close a Session
- Login and Logout
- Search for some objects
- Create a Data object
- Create a Certificate object
- Generate a key pair
- Encrypt and decrypt
- Sign and Verify
1. Instanciate and Initialize a Cryptoki object¶
// Creates a Cryptoki object and attach it to the PKCS#11 native library smaoscki.dllCryptoki
cryptoki = new Cryptoki("smaoscki.dll");
int nRet = cryptoki.Initialize();
if (nRet != 0)
{
error(nRet);
}
...
cryptoki.Finalize(IntPtr.Zero);
2. Read available slots
// Reads the set of available slots
SlotList slots = cryptoki.Slots;
if (slots.Count == 0)
throw new Exception("No slots available");
// Gets the first slot available
Slot slot = slots[0];
3. Open and Close a session¶
// Gets the first token available
if(!slot.IsTokenInserted)
{
Console.WriteLine("No token found in the slot: " + slot.Info.Description);
return;
}
Token token = slot.Token;
// Prints all information relating to the token
TokenInfo tinfo = token.Info;
Console.WriteLine(tinfo.Label);
Console.WriteLine(tinfo.ManufacturerID);
Console.WriteLine(tinfo.Model);
Console.WriteLine(tinfo.SerialNumber);
Console.WriteLine(tinfo.HardwareVersion);
// Opens a read/write serial session
Session session = token.OpenSession (Session.CKF_SERIAL_SESSION | Session.CKF_RW_SESSION, null, null);
...session.Close();
4. Login and Logout¶
// Executes the login passing the user PIN
int nRes = session.Login((int)Session.CKU_USER, "12345678");
if (nRes != 0)
{
Console.WriteLine("Wrong PIN");
return;
}
Console.WriteLine("Logged in:" + session.IsLoggedIn);
5. Search for some objects
// Searchs for an RSA private key object
// Sets the template with its attributes
CryptokiCollection template = new CryptokiCollection();
template.Add(new ObjectAttribute(ObjectAttribute.CKA_CLASS, CryptokiObject.CKO_PRIVATE_KEY));
template.Add(new ObjectAttribute(ObjectAttribute.CKA_KEY_TYPE, Key.CKK_RSA));
template.Add(new ObjectAttribute(ObjectAttribute.CKA_LABEL, "Ugo's new Key 0"));
// Launchs the search specifying the template just created
CryptokiCollection objects = session.Objects.Find(template, 10);
// If the private keys is found continue
if (objects.Count > 0)
{
foreach (Object obj in objects)
{
Console.WriteLine(((PrivateKey)obj).Label);
}
RSAPrivateKey privateKey;
privateKey = (RSAPrivateKey)objects[objects.Count - 1];
Console.WriteLine(privateKey.Label);
}
6. Create a Data object
CryptokiCollection template = new CryptokiCollection();
template.Add(new ObjectAttribute(ObjectAttribute.CKA_CLASS, CryptokiObject.CKO_DATA));
template.Add(new ObjectAttribute(ObjectAttribute.CKA_LABEL, label));
template.Add(new ObjectAttribute(ObjectAttribute.CKA_APPLICATION, application));
template.Add(new ObjectAttribute(ObjectAttribute.CKA_TOKEN, true));
template.Add(new ObjectAttribute(ObjectAttribute.CKA_PRIVATE, true);
template.Add(new ObjectAttribute(ObjectAttribute.CKA_MODIFIABLE, true);
template.Add(new ObjectAttribute(ObjectAttribute.CKA_VALUE, value));
Data data = (Data)session.Objects.Create(template);
7. Create a Certificate object
CryptokiCollection template = new CryptokiCollection();
template.Add(new ObjectAttribute(ObjectAttribute.CKA_CLASS, CryptokiObject.CKO_CERTIFICATE));
template.Add(new ObjectAttribute(ObjectAttribute.CKA_SUBJECT, cert.SubjectName.RawData));
template.Add(new ObjectAttribute(ObjectAttribute.CKA_ISSUER, cert.Issuer));
template.Add(new ObjectAttribute(ObjectAttribute.CKA_SERIAL_NUMBER, cert.SerialNumber));
template.Add(new ObjectAttribute(ObjectAttribute.CKA_ID, id));
template.Add(new ObjectAttribute(ObjectAttribute.CKA_LABEL, label));
template.Add(new ObjectAttribute(ObjectAttribute.CKA_TOKEN, true));
template.Add(new ObjectAttribute(ObjectAttribute.CKA_VALUE, cert.RawData));
template.Add(new ObjectAttribute(ObjectAttribute.CKA_MODIFIABLE, modifiable));
CryptokiObject certificate = CurrentSession.Objects.Create(template);
8. Generate a key pair
// Prepares the templates for key pair generation
CryptokiCollection templatePub = new CryptokiCollection();
templatePub.Add(new ObjectAttribute(ObjectAttribute.CKA_CLASS, CryptokiObject.CKO_PUBLIC_KEY));
templatePub.Add(new ObjectAttribute(ObjectAttribute.CKA_TOKEN, true));
templatePub.Add(new ObjectAttribute(ObjectAttribute.CKA_PRIVATE, false));
templatePub.Add(new ObjectAttribute(ObjectAttribute.CKA_LABEL, "Ugo's new Key"));
templatePub.Add(new ObjectAttribute(ObjectAttribute.CKA_ID, "1"));
templatePub.Add(new ObjectAttribute(ObjectAttribute.CKA_MODULUS_BITS, 1024));
templatePub.Add(new ObjectAttribute(ObjectAttribute.CKA_PUBLIC_EXPONENT, 0x010001));
CryptokiCollection templatePri = new CryptokiCollection();
templatePri.Add(new ObjectAttribute(ObjectAttribute.CKA_CLASS, CryptokiObject.CKO_PRIVATE_KEY));
templatePri.Add(new ObjectAttribute(ObjectAttribute.CKA_TOKEN, true));
templatePri.Add(new ObjectAttribute(ObjectAttribute.CKA_PRIVATE, true));
templatePri.Add(new ObjectAttribute(ObjectAttribute.CKA_LABEL, "Ugo's new Key 0"));
templatePri.Add(new ObjectAttribute(ObjectAttribute.CKA_ID, "1"));
//generate the key objects
Key[] keys = session.GenerateKeyPair(Mechanism.RSA_PKCS_KEY_PAIR_GEN, templatePub, templatePri);
RSAPrivateKey privateKey = (RSAPrivateKey)keys[1];
RSAPublicKey publicKey = (RSAPublicKey)keys[0];
9. Encrypt and decrypt¶
string helloworld = "Hello World";
byte[] text = Encoding.ASCII.GetBytes(helloworld);
// launches the encryption operation DES mechanism
nRes = session.EncryptInit(Mechanism.DES, key);
// computes the encryption
byte[] encrypted = session.Encrypt(text);
...
nRes = session.DecryptInit(Mechanism.DES, key);
byte[] decrypted = session.Decrypt(encrypted);
10. Sign and Verify¶
string helloworld = "Hello World";
byte[] text = Encoding.ASCII.GetBytes(helloworld);
// launches the digital signing operation with a RSA_PKCS mechanism
nRes = session.SignInit(Mechanism.SHA1_RSA_PKCS, privateKey);
// computes the signature
byte[] signature = session.Sign(text);
...
nRes = session.VerifyInit(Mechanism.SHA1_RSA_PKCS, publicKey);
nRes = session.Verify(text, signature);
if(nRes == 0)
Console.Write("Verify " + nRes);