PeculiarVentures / graphene

A simple layer for interacting with PKCS #11 / PKCS11 / CryptoKI for Node in TypeScript. (Keywords: Javascript, PKCS#11, Crypto, Smart Card, HSM)
MIT License
169 stars 34 forks source link

GOST examples #106

Open LumaRay opened 5 years ago

LumaRay commented 5 years ago

Hi. Can you please provide GOST signing / hashing / encryption exaples?

microshine commented 5 years ago

Hashing

import * as graphene from "graphene-pk11";

const softHsm = graphene.Module.load("/usr/local/lib/softhsm/libsofthsm2.so", "SoftHSMv2");

softHsm.initialize();

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

   const hash = session.createDigest(graphene.MechanismEnum.GOSTR3411).once(Buffer.from("message"));
   console.log("GOSTR3411:", hash.toString("hex")); // GOSTR3411: 4b582bce7d059e1c7a33f05761b5685de1e00bee5338da3931f50e8763994d33
}
finally {
  softHsm.finalize();
}

Unfortunately graphene doesn't implement GOST params. Params must be implemented in pkcs11js module first (etc RSA OAEP and PSS params).

PR is appreciated

LumaRay commented 5 years ago

I'm using Rutoken ECP 2.0

    var keys = session.generateKeyPair(graphene.KeyGenMechanism.GOSTR3410, {
        class: graphene.ObjectClass.PUBLIC_KEY,
        keyType: graphene.KeyType.GOSTR3410,
        token: true, // false leads to Error: CKR_TEMPLATE_INCONSISTENT
        verify: true,
        encrypt: false,
        wrap: false
    }, {
        class: graphene.ObjectClass.PRIVATE_KEY,
        keyType: graphene.KeyType.GOSTR3410,
        token: true, // false leads to Error: CKR_TEMPLATE_INCONSISTENT
        sign: true,
        decrypt: false,
        unwrap: false
    });

    var sign = session.createSign("GOSTR3410", keys.privateKey);
    // sign.once("simple text 1"); // <<< Error: CKR_DATA_LEN_RANGE
    // sign.update("simple text 1"); // <<< Error: CKR_FUNCTION_NOT_SUPPORTED
microshine commented 5 years ago

try to sign calculated hash

Buffer.from("4b582bce7d059e1c7a33f05761b5685de1e00bee5338da3931f50e8763994d33", "hex")
microshine commented 5 years ago

I'm trying to generate the same key in SoftHSMv2, but got CKR_TEMPLATE_INCOMPLETE error. GOST params are required https://github.com/opendnssec/SoftHSMv2/blob/cb2ddc07432edd4d4530c5aea22195142660d6d6/src/lib/SoftHSM.cpp#L9594

LumaRay commented 5 years ago

It finally worked this way:

    var session = slot.open(graphene.SessionFlag.SERIAL_SESSION | graphene.SessionFlag.RW_SESSION);
    session.login("12345678");
    var keys = session.generateKeyPair(graphene.KeyGenMechanism.GOSTR3410, {
        class: graphene.ObjectClass.PUBLIC_KEY,
        keyType: graphene.KeyType.GOSTR3410,
        token: true,
        verify: true,
        encrypt: false,
        wrap: false
    }, {
        class: graphene.ObjectClass.PRIVATE_KEY,
        keyType: graphene.KeyType.GOSTR3410,
        token: true,
        sign: true,
        decrypt: false,
        unwrap: false
    });

    var hash = session.createDigest(graphene.MechanismEnum.GOSTR3411).once(Buffer.from("message"));

    // sign content
    var sign = session.createSign("GOSTR3410", keys.privateKey);
    var signature = sign.once(hash);
    console.log("Signature GOSTR3410:", signature.toString("hex")); 

    // verify content
    var verify = session.createVerify("GOSTR3410", keys.publicKey);
    var verify_result = verify.once(hash, signature);
    console.log("Signature GOSTR3410 verify:", verify_result);      

It seems that only "once" sign option available, and it should take GOSTR3411 hash.

"CKR_TEMPLATE_INCOMPLETE" seems to happen only when I try to generate keys outside token: "token: false". It seems that the token can generate this only by its hardware means.

Thanks for the help, I think everyone will like to see all GOST examples, including encrypt/decrypt.

LumaRay commented 5 years ago

Here https://dev.rutoken.ru/pages/viewpage.action?pageId=13795364 I can see few parameters examples:

/* Набор параметров КриптоПро A алгоритма ГОСТ Р 34.10-2001 */
CK_BYTE         paramsGostR3410[]       = { 0x06, 0x07, 0x2a, 0x85, 0x03, 0x02, 0x02, 0x23, 0x01 };

/* Набор параметров КриптоПро A алгоритма ГОСТ Р 34.10-2012(512) */
CK_BYTE         paramsGostR3410_512[]   = { 0x06, 0x09, 0x2a, 0x85, 0x03, 0x07, 0x01, 0x02, 0x01, 0x02, 0x01 };

/* Набор параметров КриптоПро алгоритма ГОСТ Р 34.11-2012(256) */
CK_BYTE         paramsGostR3411_256[]   = { 0x06, 0x08, 0x2a, 0x85, 0x03, 0x07, 0x01, 0x01, 0x02, 0x02 };

/* Набор параметров КриптоПро алгоритма ГОСТ Р 34.11-2012(512) */
CK_BYTE         paramsGostR3411_512[]   = { 0x06, 0x08, 0x2a, 0x85, 0x03, 0x07, 0x01, 0x01, 0x02, 0x03 }; 

...

/* Набор параметров КриптоПро A алгоритма ГОСТ 28147-89 */
CK_BYTE     GOST28147params[]   = { 0x06, 0x07, 0x2a, 0x85, 0x03, 0x02, 0x02, 0x1f, 0x01 };

How to I set them?