Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Question: Encrypting/Decrypting across restarts #145

Open
santosh-shaastry opened this issue Oct 18, 2021 · 3 comments
Open

Question: Encrypting/Decrypting across restarts #145

santosh-shaastry opened this issue Oct 18, 2021 · 3 comments

Comments

@santosh-shaastry
Copy link

Hi,

I am a newbie to SoftHSM/PKCS 11. I am trying to:

Step 1

  1. Initialize the SoftHSM module
  2. Login to access the token/slot
  3. Obtain the session
  4. Encrypt a message using the session's cipher methods as described in your README documentation
  5. Persist the encrypted value in a file/database

Step 2

  • Restart the application

Step 3

  1. Initialize the SoftHSM module
  2. Read the encrypted value from the file/database
  3. Login to access the token/slot
  4. Obtain the session
  5. Attempt to decrypt the encrypted message using the session's cipher methods as described in your README documentation

Though I am able to login successfully using the same token and seem to obtain the same session, I run into the following error when performing Buffer.concat([dec, decipher.final()]).toString();

[Pkcs11Error: CKR_GENERAL_ERROR] {
relayer_1 | method: 'crypto_final',
relayer_1 | nativeStack: ' at Error (native) crypto_final:710',
relayer_1 | code: 5
relayer_1 | }

From what I understand about the PKCS 11 Session as described in the spec, unless a session is closed/logged out the application should be able to access the same session and hence the token/slot.

Appreciate any direction, inputs and help on this one. Thank you.

@microshine
Copy link
Contributor

Here is my example

Key generation

const label = "test_key";
const softHsm = graphene.Module.load("/usr/local/lib/softhsm/libsofthsm2.so");
softHsm.initialize();

try {
  const slot = softHsm.getSlots(0);
  const session = slot.open(graphene.SessionFlag.RW_SESSION | graphene.SessionFlag.SERIAL_SESSION);
  session.login("12345", graphene.UserType.USER);

  const keys = session.generateKeyPair(graphene.KeyGenMechanism.RSA, {
    keyType: graphene.KeyType.RSA,
    token: true,
    label,
    publicExponent: Buffer.from([1, 0, 1]),
    modulusBits: 2048,
    encrypt: true,
  }, {
    keyType: graphene.KeyType.RSA,
    private: true,
    sensitive: true,
    token: true,
    label,
    decrypt: true,
  });
  console.log(keys);
} catch (e) {
  console.error(e);

  softHsm.finalize();
}

Encryption

const label = "test_key";
const softHsm = graphene.Module.load("/usr/local/lib/softhsm/libsofthsm2.so");
softHsm.initialize();

try {
  const slot = softHsm.getSlots(0);
  const session = slot.open(graphene.SessionFlag.SERIAL_SESSION);

  const publicKey = session.find({
    class: graphene.ObjectClass.PUBLIC_KEY,
    label,
  }).items(0).toType();

  const cipher = session.createCipher({
    name: "RSA_PKCS_OAEP",
    params: new graphene.RsaOaepParams(graphene.MechanismEnum.SHA1, graphene.RsaMgf.MGF1_SHA1),
  }, publicKey);
  encrypted = cipher.once(data, Buffer.alloc(2048));
  console.log(encrypted);
} catch (e) {
  console.error(e);

  softHsm.finalize();
}

Decryption

const label = "test_key";
const softHsm = graphene.Module.load("/usr/local/lib/softhsm/libsofthsm2.so");
softHsm.initialize();

try {
  const slot = softHsm.getSlots(0);
  const session = slot.open(graphene.SessionFlag.SERIAL_SESSION);
  session.login("12345", graphene.UserType.USER);

  const privateKey = session.find({
    class: graphene.ObjectClass.PRIVATE_KEY,
    label,
  }).items(0).toType();

  const decipher = session.createDecipher({
    name: "RSA_PKCS_OAEP",
    params: new graphene.RsaOaepParams(graphene.MechanismEnum.SHA1, graphene.RsaMgf.MGF1_SHA1),
  }, privateKey);
  const decrypted = decipher.once(encrypted, Buffer.alloc(2048));
  console.log(decrypted);
} catch (e) {
  console.error(e);

  softHsm.finalize();
}

@santosh-shaastry
Copy link
Author

@microshine Thank you for the detailed example. I can confirm what you have shared works as expected, however without a an application restart between encryption and decryption functions. So the question I still have is, what could be a recommended way to store the Public/Private key pair in order to ensure that the data encrypted using a set of keys can be decrypted in a deterministic way even after the application restarts.

An interesting side note on something that I observed:

  1. I was hoping to obtain the session by storing the handle Buffer and using it to fetch the SessionObject (via the getObject method) after application restart
  2. However the handle Buffer's value seem to be different every time I opened the slot. This means that I get different instances of the session but all of them pointing to the same slot (0, in my case) in which the data is encrypted/stored.

Thank you for the clarification and further help.

@KawtharAlakri
Copy link

Have you managed to solve this issue by any chance and decrypt data separately from the encryption ? @santosh-shaastry
i'm trying to do that and getting the same error.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants