Swisspost 460d0e0780 sVote source code publication 5 years ago
..
lib 460d0e0780 sVote source code publication 5 years ago
spec 460d0e0780 sVote source code publication 5 years ago
.jshintrc 460d0e0780 sVote source code publication 5 years ago
.npmrc 460d0e0780 sVote source code publication 5 years ago
LICENSE 460d0e0780 sVote source code publication 5 years ago
README.md 460d0e0780 sVote source code publication 5 years ago
karma.conf.js 460d0e0780 sVote source code publication 5 years ago
package-lock.json 460d0e0780 sVote source code publication 5 years ago
package.json 460d0e0780 sVote source code publication 5 years ago
pom.xml 460d0e0780 sVote source code publication 5 years ago
webpack.config 460d0e0780 sVote source code publication 5 years ago

README.md

Asymmetric Cryptography Module

This module defines the asymmetric cryptography API for Scytl's JavaScript cryptographic library. The starting point for using this module is the instantiation of an asymmetric cryptography service.

How to view, build and test the source code of this module

Start by git cloning the project comm/scytl-cryptolib from Stash.

The source code of this module will be found in the directory scytl-cryptolib/cryptolib-js-asymmetric/lib.

To build this module, change to the directory scytl-cryptolib/cryptolib-js-asymmetric and do the following:

npm install
--or--
mvn clean install -DskipTests

The unit tests of this module will be found in the directory scytl-cryptolib/cryptolib-js-asymmetric/spec. To run the tests, change to the directory scytl-cryptolib/cryptolib-js-asymmetric and do the following:

karma test
--or--
mvn test

To only run a chosen test suite, add an f in front of the corresponding describe statement. For example:

fdescribe('create an asymmetric cryptography service that should be able to ..', function()
...

To only run a chosen test, add an f in front of the corresponding it statement. For example:

fit('create a new RsaPublicKey object', function()
...

Note: To build and test the entire scytl-cryptolib project, change to the directory scytl-cryptolib and do the following:

mvn clean install

How to generate the JSDoc for this module

To generate the JSDoc for this module, change to the directory scytl-cryptolib/cryptolib-js-asymmetric, build the module (if not already done) and do the following:

node_modules/.bin/jsdoc lib

This will generate a file called out. Double click on the file out/index.html to view the JSDoc.

How to npm install this module

To npm install this module in standalone mode, do the following:

npm install --registry https://nexus.scytl.net/content/groups/public-npm/ scytl-asymmetric

To npm install this module as a dependency of your own module, do the following:

  1. Add the following lines to the dependencies section of your module's package.json file.

    "scytl-bitwise": "^2.1.0",
    "scytl-codec": "^2.1.0",
    "scytl-cryptopolicy": "^2.1.0",
    "scytl-securerandom": "^2.1.0",
    "scytl-asymmetric": "^2.1.0",
    
  2. Make sure that the .npmrc file of your module contains the following line.

    registry=https://nexus.scytl.net/content/groups/public-npm/
    
  3. Install all dependencies.

    npm install
    

    How to instantiate an asymmetric cryptography service

The following example shows the default way to create a new instance of an asymmetric cryptography service.

var asymmetric = require('scytl-asymmetric');

var asymmetricService = asymmetric.newService();

The following example shows how to override the default cryptographic policy used for asymmetric cryptography operations by changing the encryption key pair length to 3072 bits.

var cryptoPolicy = require('scytl-cryptopolicy');
var asymmetric = require('scytl-asymmetric');

var myPolicy = cryptoPolicy.newInstance();

myPolicy.asymmetric.secretKey.encryption.lengthBytes =
  cryptoPolicy.options.asymmetric.keyPair.encryption.keyLengthBits.KL_3072;

var asymmetricService = asymmetric.newService({policy: myPolicy});

Note: It is desirable to use the property CryptographicPolicy.options to override the default policy, as shown above, in order to ensure that one is using an option that is allowed by the cryptographic policy.

The following example shows how to supply one's own secure random service object to the asymmetric cryptography service.

var asymmetric = require('scytl-asymmetric');
var secureRandom = require('scytl-securerandom');

var mySecureRandomService = secureRandom.newService();
var asymmetricService = asymmetric.newService({
  secureRandomService: mySecureRandomService
});

How to instantiate key objects.

The following example shows how to create a new RsaPublicKey object from an RSA public key in PEM format and access its components.

var publicKey = asymmetricService.newRsaPublicKey(publicKeyPem);
var modulus = publicKey.n;
var publicExponent = publicKey.e;

The following example shows how to create a new RsaPrivateKey object from an RSA private key in PEM format and access its components.

var privateKey = asymmetricService.newRsasPrivateKey(privateKeyPem);
var modulus = privateKey.n;
var publicExponent = privateKey.e;
var privateExponent = privateKey.d;
var firstPrime = privateKey.p;
var secondPrime = privateKey.q;
var firstExponent = privateKey.dP;
var secondExponent = privateKey.dQ;
var coefficient = privateKey.qInv;

The following example shows how to create a new RsaPublicKey object from its components and serialize it to PEM format.

var publicKey = asymmetricService.newRsaPublicKey(n, e);
var publicKeyPem = publicKey.toPem();

The following example shows how to create a new RsaPrivateKey object from its components and serialize it to PEM format.

var privateKey = asymmetricService.newRsaPrivateKey(n, e, d, p, q, dP, dQ, qInv);
var privateKeyPem = privateKey.toPem();

Note Key objects must always be converted to PEM format before being used as input arguments to any cryptographic functions defined by this library.

How to instantiate a key pair.

The following example shows how to generate a new key pair and retrieve its public and private components, in PEM format.

var keyPairGenerator = asymmetricService.newKeyPairGenerator();

var keyPair = keyPairGenerator.next();
var publicKeyPem = keyPair.publicKey;
var privateKeyPem = keyPair.privateKey;

The following example shows how to create a new key pair object from its components.

var keyPair = asymmetricService.newKeyPair(publicKeyPem, privateKeyPem);

How to digitally sign data and verify the signature

The following examples show how to digitally sign some data and verify the resulting signature. The input data for signature generation and verification can be in the form of a string or a byte array, wrapped in a Uint8Array object. The output of the signature generation will be in the form of a byte array, wrapped in a Uint8Array object.

var asymmetric = require('scytl-asymmetric');
var codec = require('scytl-codec');

var asymmetricService = asymmetric.newService();
var signer = asymmetricService.newSigner().init(privateKeyPem);
var sigVerifier = asymmetricService.newSignatureVerifier().init(publicKeyPem);
...

var signature = signer.sign('mydata');
var verified = sigVerifier.verify(signature, 'myData');
expect(verified).toBeTruthy();

var signature = signer.sign(new Uint8Array[0x01, 0x02, 0x03]);
var verified = sigVerifier.verify(signature, new Uint8Array[0x01, 0x02, 0x03]);
expect(verified).toBeTruthy();

The following example shows how to digitally sign some data with multiple parts.

var dataParts = ['myData1', 'myData2', 'myData3'];
...

for (var i = 0; i < dataParts.length; i++) {
  signer.update(dataParts[i]);
}
var signature = signer.sign();

--or--

for (var i = 0; i < (dataParts.length-1); i++) {
  signer.update(dataParts[i]);
}
var signature = signer.sign('myData3');

The following example shows how to verify a signature generated from some data with multiple parts.

for (var i = 0; i < dataParts.length; i++) {
  sigVerifier.update(dataParts[i]);
}
var verified = verifier.verify(signature);

--or--

for (var i = 0; i < (dataParts.length-1); i++) {
  sigVerifier.update(dataParts[i]);
}
var verified = verifier.verify(signature, 'myData3');

The following example shows how to digitally sign some data with multiple parts, using method chaining.

var signature = signer.update('myData1').update('myData2').update('myData3').sign();

--or--

var signature = signer.update('myData1').update('myData2').sign('myData3');

The following example shows how to verify a signature generated from some data with multiple data parts, using method chaining.

var verified = sigVerifier.update('myData1').update('myData2').update('myData3').verify(signature);

--or--

var verified = sigVerifier.update('myData1').update('myData2').verify(signature, 'myData3');

How to encrypt and decrypt data

The following examples show how to encrypt and decrypt some data. The input data of the encryption can be in the form of a string or a byte array, wrapped in a Uint8Array object. The output of both the encryption and the decryption will be in the form of a byte array, wrapped in a Uint8Array object. To retrieve encrypted data of type string the result of the decryption must be UTF-8 decoded.

var asymmetric = require('scytl-asymmetric');
var codec = require('scytl-codec');

var asymmetricService = asymmetric.newService();
var encrypter = asymmetricService.newEncrypter().init(publicKeyPem);
var decrypter = asymmetricService.newDecrypter().init(privateKeyPem);
...

var encryptedData = encrypter.encrypt('myData');
var decryptedData = codec.utf8Decode(decrypter.decrypt(encryptedData));
expect(decryptedData).toBe('myData');

var encryptedData = encrypter.encrypt(new Uint8Array[0x01, 0x02, 0x03]);
var decryptedData = decrypter.decrypt(encryptedData);
expect(decryptedData).toEqual(new Uint8Array[0x01, 0x02, 0x03]);