# Smart Card Shell

- - Home
- - GPError
  - GPSystem
  - ByteString
  - ByteBuffer
  - TLV
  - TLVList
  - Card
  - Atr
  - Key
  - Crypto
  - Application
  - GPApplication
  - GPSecDomain
- - ASN1
  - CardFile
  - IsoSecureChannel
  - ApplFactory
  - GPXML
  - JsScript
  - CardSim
- - X509
  - CRL
  - KeyStore
  - Signed CMS
  - Enveloped CMS
  - CMS Generator
  - XMLSignature
  - SSS
  - OCSPQuery
  - LDAP
  - SOAP
  - URLConnection
- - PKCS11Provider
  - PKCS11Session
  - PKCS11Object
- - OutlineNode
  - Dialog
  - Task
- - Tools
  - Modules
- - OpenSCDP

# Key - Reference Documentation

Implements support for cryptographic keys.

Use this class to create cryptographic keys. Key values are either set in the key profile or defined using the setComponent() method.

To use AES with 192 or 256 bit, you will need to install the Java Cryptography Extension (JCE) Unlimited Strength Jurisdiction Policy available from the site where you downloaded your Java runtime. See java.sun.com or Google for details on how to install these files.

## Index of Methods

- Key() constructor
- setType()
- getType()
- setSize()
- getSize()
- setComponent()
- getComponent()
- getECPoint()

## Constants

Type | Name | Description
--- | --- | ---
Number | SECRET | Secret key type in setType() and getType() method
Number | PRIVATE | Private key type in setType() and getType() method
Number | PUBLIC | Public key type in setType() and getType() method
Number | DES | DES secure key component
Number | AES | AES secure key component
Number | MODULUS | RSA key component (modulus)
Number | EXPONENT | RSA key component (exponent)
Number | CRT_P | RSA private key component P
Number | CRT_Q | RSA private key component Q
Number | CRT_DP1 | RSA private key component (D mod P^-1)
Number | CRT_DQ1 | RSA private key component (D mod P^-1)
Number | CRT_PQ | RSA private key component (Q^-1 mod P)
Number | ECC_D | EC private key component
Number | ECC_QX | EC public key component, x coordinate of point q
Number | ECC_QY | EC public key component, y coordinate of point q
Number | ECC_CURVE_OID | Object identifier of named curve
Number | ECC_A | Elliptic curve coefficient a
Number | ECC_B | Elliptic curve coefficient b
Number | ECC_GX | Elliptic curve x coordinate of generator point G
Number | ECC_GY | Elliptic curve y coordinate of generator point G
Number | ECC_N | Elliptic curve order of base point G
Number | ECC_H | Elliptic curve cofactor of generator point G
Number | ECC_P | Elliptic curve prime p (Fp)
Number | ECC_M | Elliptic curve degree m (F2^m)
Number | ECC_K1 | Elliptic curve reduction polynom exponent k1 (F2^m)
Number | ECC_K2 | Elliptic curve reduction polynom exponent k2 (F2^m)
Number | ECC_K3 | Elliptic curve reduction polynom exponent k3 (F2^m)

## Constructor

### Prototype

Key()

Key(String profile)

Key(Key otherKey)

### Description

Create an empty key object and set properties from profile or existing key.

If no profile or existing key is specified, then an empty key is created.

See the examples in the directory ./profiles how to create XML key profiles.

### Arguments

Type | Name | Description
--- | --- | ---
`String` | profile | Name of file containing Global Platform key profile
`Key` | otherKey | Existing key whose components are copied into the new key

### Exceptions

Name | Value | Description
--- | --- | ---
GPError | GPError.INVALID_ARGUMENTS | Too many arguments given
GPError | GPError.INVALID_TYPE | On or more arguments are not of the expected type

### Example

    var key = new Key();
    assert(key != null);

    var key = new Key("profiles/kp_single_des_1.xml");
    assert(key != null);

    assert(key.profile);
    assert(key.profile.UniqueID == "2B0601040181C31F100001");
    assert(key.profile.ProfileVersion == "1.1.0");
    assert(key.profile.ErrataVersion == "0");
    assert(key.profile.Description.elementValue == "Single DES Test Key 1");
    assert(key.profile.Revisions);
    assert(key.profile.Revisions.Revision.length == 1);
    assert(key.profile.Revisions.Revision[0]);
    assert(key.profile.Revisions.Revision[0].Version == "1.0.0");
    assert(key.profile.Revisions.Revision[0].Date == "2005-12-09");
    assert(key.profile.Revisions.Revision[0].Time == "00:00:00");
    assert(key.profile.Revisions.Revision[0].By == "www.openscdp.org");
    assert(key.profile.Revisions.Revision[0].Digest == "00000000");
    assert(key.profile.KeyInfo);
    assert(key.profile.KeyInfo.Name == "SingleDESTest1");
    assert(key.profile.KeyInfo.Type == "SECRET");
    assert(key.profile.KeyInfo.SubType == "DES");
    assert(key.profile.KeyInfo.Size == "64");
    assert(key.profile.KeyInfo.Mode == "TEST");
    assert(key.profile.Attribute);
    assert(key.profile.Attribute.Sensitive == "false");
    assert(key.profile.Attribute.Importable == "true");
    assert(key.profile.Attribute.Exportable == "true");
    assert(key.profile.Usage);
    assert(key.profile.Usage.Encrypt == "true");
    assert(key.profile.Usage.Decrypt == "true");
    assert(key.profile.Usage.DecryptEncrypt == "true");
    assert(key.profile.Usage.Sign == "true");
    assert(key.profile.Usage.Verify == "true");
    assert(key.profile.Usage.Wrap == "true");
    assert(key.profile.Usage.Unwrap == "true");
    assert(key.profile.Usage.UnwrapWrap == "true");
    assert(key.profile.Usage.Derive == "true");
    assert(key.profile.Value);
    assert(key.profile.Value.Format == "DES");
    assert(key.profile.Value.Component);
    assert(key.profile.Value.Component.length == 1);
    assert(key.profile.Value.Component[0].Value == "7CA110454A1A6E57");
    assert(key.profile.Value.Component[0].Encoding == "HEX");

    var newkey = new Key(key);

    assert(newkey.getType() == Key.SECRET);
    assert(newkey.getSize() == 64);
    assert(newkey.profile == key.profile);
    assert(newkey.getComponent(Key.DES).toString(HEX) == "7CA110454A1A6E57");

    var key = new Key("profiles/kp_aes_128.xml");
    assert(key != null);
    assert(key.getComponent(Key.AES).toString(HEX) == "7CA110454A1A6E570131D9619DC1376E");

    var key = new Key("profiles/kp_ec_public.xml");
    assert(key != null);
    assert(key.getComponent(Key.ECC_P).length == 24);

## setType()

### Prototype

void setType(Number type)

### Description

Set the basic key type to either Key.SECRET, Key.PRIVATE or Key.PUBLIC.

If a profile was used to create the key, then the profile.KeyInfo.Type property is updated accordingly.

### Arguments

Type | Name | Description
--- | --- | ---
`Number` | type | Type of key. Must be either Key.SECRET, Key.PRIVATE or Key.PUBLIC

### Return

`None` | The method does not return a value

### Exceptions

Name | Value | Description
--- | --- | ---
GPError | GPError.ARGUMENTS_MISSING | Too few arguments in call
GPError | GPError.INVALID_ARGUMENTS | Too many arguments in call
GPError | GPError.INVALID_TYPE | Type of argument is invalid for method invocation

### Example

    var key = new Key();

    key.setType(Key.SECRET);
    key.setType(Key.PRIVATE);
    key.setType(Key.PUBLIC);

    key = new Key("profiles/kp_single_des_1.xml");

    key.setType(Key.SECRET);
    key.setType(Key.PRIVATE);
    key.setType(Key.PUBLIC);

## getType()

### Prototype

Number getType()

### Description

Get the basic key type which is either Key.SECRET, Key.PRIVATE or Key.PUBLIC.

### Return

`Number` | The type of the key or the undefined value if the type is not specified

### Exceptions

Name | Value | Description
--- | --- | ---
GPError | GPError.INVALID_ARGUMENTS | Too many arguments in call

### Example

    var key = new Key();

    key.setType(Key.SECRET);
    assert(key.getType() == Key.SECRET);

    key = new Key("profiles/kp_single_des_1.xml");
    assert(key.getType() == Key.SECRET);

## setSize()

### Prototype

void setSize(Number size)

### Description

Set the key size in number of bits for the key, if not already set from the profile.

This method should be used to specify the key size in a key template passed to the Crypto.generateKeyPair() method.

### Arguments

Type | Name | Description
--- | --- | ---
`Number` | size | Number of bits for key

### Return

`None` | The method does not return a value

### Exceptions

Name | Value | Description
--- | --- | ---
GPError | GPError.ARGUMENTS_MISSING | Too few arguments in call
GPError | GPError.INVALID_ARGUMENTS | Too many arguments in call
GPError | GPError.INVALID_TYPE | Type of argument is invalid for method invocation

### Example

    var key = new Key();
    key.setType(Key.PRIVATE);
    key.setSize(1024);

## getSize()

### Prototype

Number getSize()

### Description

Get the size of the key expressed as number of bits

### Return

`Number` | The number of bits comprising this key

### Exceptions

Name | Value | Description
--- | --- | ---
GPError | GPError.INVALID_ARGUMENTS | Too many arguments in call

### Example

    var key = new Key();

    key.setType(Key.PUBLIC);
    key.setSize(1024);
    assert(key.getSize() == 1024);

    key = new Key("profiles/kp_single_des_1.xml");
    assert(key.getSize() == 64);

## setComponent()

### Prototype

void setComponent(Number type, ByteString value)

### Description

Set a component for the cryptographic key.

For DES keys only the component Key.DES is defined.

For AES keys only the component Key.AES is defined. If you want to use AES with 192 or 256 bit, then will need to install the Java Cryptography Extension (JCE) Unlimited Strength Jurisdiction Policy available from the site where you downloaded your Java runtime. See java.sun.com or Google for details on how to install these files.

RSA private keys can be composed in one of two ways, either with Key.MODULUS and Key.EXPONENT or with Key.CRT_P, Key.CRT_Q, Key.CRT_DP, Key.CRT_DQ and Key.CRT_PQ.

ECC private and public keys can be composed by specifying the elliptic curve and the private value D or the public point Q, which consists of a x and y coordinate.

The elliptic curve can be either defined by the object identifier (in binary format) of the named curve or by specifying the individual curve parameter (p, a, b, Gx, Gy, n, h) for Fp or (m, k1, k2, k3, Gx, Gy, n, h) for F2m.

See the script in tools/eccutils.js for a list of pre-defined curve object identifier.

All key parameter are interpreted as unsigned big integer.

If the key type is not yet determined, then the first call of setComponent() will define the key type and subsequent setComponent() calls must only overwrite or extend the key component values already defined. This, however, only works if the key type can be derived from the component supplied (e.g. the key type (Private/Public) can not be automatically determined when specifying the modulus).

Keys are only constructed from components at the time they are needed by a cryptographic operation. The key itself is then stored as a session value until a subseqent call to setComponent() erases the cached key.

To allow for the RSA blinding operation, the public key exponent can be defined for RSA CRT private keys. This is done with the Key.EXPONENT component. If no Key.EXPONENT is defined for a RSA CRT private key, then no RSA blinding will be used.

### Arguments

Type | Name | Description
--- | --- | ---
`Number` | type | Component of key provided in value. Must be one of Key.DES, Key.AES, Key.MODULUS, Key.EXPONENT, Key.CRT_* or Key.ECC_*
`ByteString` | value | Value of component identified by type argument

### Return

`None` | The method does not return a value

### Exceptions

Name | Value | Description
--- | --- | ---
GPError | GPError.ARGUMENTS_MISSING | Too few arguments in call
GPError | GPError.INVALID_ARGUMENTS | Too many arguments in call
GPError | GPError.INVALID_TYPE | Type of argument is invalid for method invocation
GPError | GPError.INVALID_DATA | The value provided for the key component is invalid

### Example

    var key = new Key();

    // Make key a single length DES key (56 bit)
    key.setComponent(Key.DES, new ByteString("7CA110454A1A6E57", HEX));
    assert(key.getSize() == 64);

    // Make key a double length DES key (112 bit)
    key.setComponent(Key.DES, new ByteString("7CA110454A1A6E570131D9619DC1376E", HEX));
    assert(key.getSize() == 128);

    // Make key a triple length DES key (168 bit)
    key.setComponent(Key.DES,
                new ByteString("7CA110454A1A6E570131D9619DC1376E9DC1376E0131D961", HEX));
    assert(key.getSize() == 192);

    key = new Key("profiles/kp_single_des_1.xml");
    assert(key.getSize() == 64);

    // Make key a single length DES key (56 bit) - Overwriting value from profile
    key.setComponent(Key.DES, new ByteString("7CA110454A1A6E57", HEX));

    // Make key a double length DES key (112 bit)
    key.setComponent(Key.DES, new ByteString("7CA110454A1A6E570131D9619DC1376E", HEX));

    // Make key a triple length DES key (168 bit)
    key.setComponent(Key.DES,
                new ByteString("7CA110454A1A6E570131D9619DC1376E9DC1376E0131D961", HEX));

    // Make AES key

    var key = new Key();

    // Make key a 128 bit AES key
    key.setComponent(Key.AES, new ByteString("000102030405060708090a0b0c0d0e0f", HEX));
    assert(key.getSize() == 128);

    // Make key a 192 bit AES key
    key.setComponent(Key.AES,
                new ByteString("000102030405060708090a0b0c0d0e0f1011121314151617", HEX));
    assert(key.getSize() == 192);

    // Make key a 256 bit AES key
    key.setComponent(Key.AES, new ByteString("000102030405060708090a0b0c0d0e0f" +
                                             "101112131415161718191a1b1c1d1e1f", HEX));
    assert(key.getSize() == 256);

    // Make RSA private key from modulus and private exponent

    var key = new Key();

    key.setType(Key.PRIVATE);

    key.setComponent(Key.MODULUS, new ByteString(
                "b4a7e46170574f16a97082b22be58b6a2a629798419be12872a4bdba626cfae9" +
                "900f76abfb12139dce5de56564fab2b6543165a040c606887420e33d91ed7ed7", HEX));
    key.setComponent(Key.EXPONENT, new ByteString(
                "9f66f6b05410cd503b2709e88115d55daced94d1a34d4e32bf824d0dde6028ae" +
                "79c5f07b580f5dce240d7111f7ddb130a7945cd7d957d1920994da389f490c89", HEX));
    assert(key.getSize() == 512);

    // Make RSA private key from CRT components

    var key = new Key();

    key.setType(Key.PRIVATE);

    key.setComponent(Key.CRT_P, new ByteString(
                "c0a0758cdf14256f78d4708c86becdead1b50ad4ad6c5c703e2168fbf37884cb", HEX));
    key.setComponent(Key.CRT_Q, new ByteString(
                "f01734d7960ea60070f1b06f2bb81bfac48ff192ae18451d5e56c734a5aab8a5", HEX));
    key.setComponent(Key.CRT_DP1, new ByteString(
                "b54bb9edff22051d9ee60f9351a48591b6500a319429c069a3e335a1d6171391", HEX));
    key.setComponent(Key.CRT_DQ1, new ByteString(
                "d3d83daf2a0cecd3367ae6f8ae1aeb82e9ac2f816c6fc483533d8297dd7884cd", HEX));
    key.setComponent(Key.CRT_PQ, new ByteString(
                "b8f52fc6f38593dabb661d3f50f8897f8106eee68b1bce78a95b132b4e5b5d19", HEX));
    assert(key.getSize() == 512);

    // Make RSA public key from modulus and public exponent

    var key = new Key();

    key.setType(Key.PUBLIC);

    key.setComponent(Key.MODULUS, new ByteString(
                "b4a7e46170574f16a97082b22be58b6a2a629798419be12872a4bdba626cfae9" +
                "900f76abfb12139dce5de56564fab2b6543165a040c606887420e33d91ed7ed7", HEX));
    key.setComponent(Key.EXPONENT, new ByteString("11", HEX));
    assert(key.getSize() == 512);

    // Make ECC private key (Fp) / prime192v1

    var key = new Key();
    key.setType(Key.PRIVATE);

    // Setting the curve parameter using an object identifier automatically sets all
    // parameter
    var oid = new ByteString("1.2.840.10045.3.1.1", OID);
    key.setComponent(Key.ECC_CURVE_OID, oid);
    assert(key.getComponent(Key.ECC_P).toString(16).equals(
                "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFF"));
    assert(key.getComponent(Key.ECC_A).toString(16).equals(
                "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFC"));
    assert(key.getComponent(Key.ECC_B).toString(16).equals(
                "64210519E59C80E70FA7E9AB72243049FEB8DEECC146B9B1"));
    assert(key.getComponent(Key.ECC_GX).toString(16).equals(
                "188DA80EB03090F67CBF20EB43A18800F4FF0AFD82FF1012"));
    assert(key.getComponent(Key.ECC_GY).toString(16).equals(
                "07192B95FFC8DA78631011ED6B24CDD573F977A11E794811"));
    assert(key.getComponent(Key.ECC_N).toString(16).equals(
                "FFFFFFFFFFFFFFFFFFFFFFFF99DEF836146BC9B1B4D22831"));
    assert(key.getComponent(Key.ECC_H).toString(16).equals(
                "000000000000000000000000000000000000000000000001"));

    key.setComponent(Key.ECC_D, new ByteString(
                "C2C7ACAB793AF41C242456CE64D5B61054629AC23B27A0E0", HEX));
    assert(key.getSize() == 192);

    // Setting the prime automatically tries to determine the curve OID
    var l = [ "secp192r1", "secp256r1", "brainpoolP192r1", "brainpoolP224r1", "brainpoolP256r1", "brainpoolP320r1", "secp192k1", "secp192k1"];
    for (var i = 0; i < l.length; i++) {
    	var s = l[i];
    	print(s);
    	var oid = new ByteString(s, OID);
    	var k1 = new Key();
    	k1.setType(Key.PUBLIC);
    	k1.setComponent(Key.ECC_CURVE_OID, oid);
    	var p = k1.getComponent(Key.ECC_P);

    	var k2 = new Key();
    	k2.setType(Key.PUBLIC);
    	k2.setComponent(Key.ECC_P, p);
    	assert(k2.getComponent(Key.ECC_CURVE_OID).equals(oid));
    }

    // Make ECC public key (Fp) / prime192v1

    var key = new Key();
    key.setType(Key.PUBLIC);
    key.setComponent(Key.ECC_CURVE_OID, new ByteString("1.2.840.10045.3.1.1", OID));
    key.setComponent(Key.ECC_QX, new ByteString(
                "BBA0C04725F939ABE6A0D1E9CEB82F336B3A04205C6E5094", HEX));
    key.setComponent(Key.ECC_QY, new ByteString(
                "FE6D6A3F6F72616D7488113AF4ABA44581ADEE297B984A08", HEX));
    assert(key.getSize() == 192);

    // Make ECC private key (F2m) / c2m239v1

    var key = new Key();
    key.setType(Key.PRIVATE);
    key.setComponent(Key.ECC_CURVE_OID, new ByteString("1.2.840.10045.3.0.11", OID));

    assert(key.getComponent(Key.ECC_M).toString(16).equals("EF"));
    assert(key.getComponent(Key.ECC_K1).toString(16).equals("24"));
    assert(key.getComponent(Key.ECC_K2).toString(16).equals("00"));
    assert(key.getComponent(Key.ECC_K3).toString(16).equals("00"));
    assert(key.getComponent(Key.ECC_B).toString(16).equals(
                "790408F2EEDAF392B012EDEFB3392F30F4327C0CA3F31FC383C422AA8C16"));
    assert(key.getComponent(Key.ECC_GX).toString(16).equals(
                "57927098FA932E7C0A96D3FD5B706EF7E5F5C156E16B7E7C86038552E91D"));
    assert(key.getComponent(Key.ECC_GY).toString(16).equals(
                "61D8EE5077C33FECF6F1A16B268DE469C3C7744EA9A971649FC7A9616305"));
    assert(key.getComponent(Key.ECC_N).toString(16).equals(
                "2000000000000000000000000000000F4D42FFE1492A4993F1CAD666E447"));
    assert(key.getComponent(Key.ECC_H).toString(16).equals(
                "000000000000000000000000000000000000000000000000000000000004"));

    key.setComponent(Key.ECC_D, new ByteString(
                "145642755521911534651321230007534120304391871461646461466464667494947990", HEX));
    assert(key.getSize() == 239);

    // Make ECC public key (F2m) / c2m239v1

    var key = new Key();
    key.setType(Key.PUBLIC);
    key.setComponent(Key.ECC_CURVE_OID, new ByteString("1.2.840.10045.3.0.11", OID));
    key.setComponent(Key.ECC_QX, new ByteString(
                "5894609CCECF9A92533F630DE713A958E96C97CCB8F5ABB5A688A238DEED", HEX));
    key.setComponent(Key.ECC_QY, new ByteString(
                "6DC2D9D0C94EBFB7D526BA6A61764175B99CB6011E2047F9F067293F57F5", HEX));
    assert(key.getSize() == 239);

## getComponent()

### Prototype

ByteString getComponent(Number type)

### Description

Return a component of a key. Key components can only be retrieved, if they are accessible. Key components stored in a HSM are usally not accessible.

### Arguments

Type | Name | Description
--- | --- | ---
`Number` | type | Component of key requested. Must be one of Key.DES, Key.AES, Key.MODULUS, Key.EXPONENT, Key.CRT_* or Key.ECC_*

### Return

`ByteString` | The value of the key component or undefined if the component is not defined.

### Exceptions

Name | Value | Description
--- | --- | ---
GPError | GPError.ARGUMENTS_MISSING | Too few arguments in call
GPError | GPError.INVALID_ARGUMENTS | Too many arguments in call
GPError | GPError.INVALID_TYPE | Type of argument is invalid for method invocation

### Example

    var key = new Key();

    // Make key a single length DES key (56 bit)
    key.setComponent(Key.DES, new ByteString("7CA110454A1A6E57", HEX));
    assert(key.getComponent(Key.DES).toString(HEX) == "7CA110454A1A6E57");

    // Make key a double length DES key (112 bit)
    key.setComponent(Key.DES, new ByteString("7CA110454A1A6E570131D9619DC1376E", HEX));
    assert(key.getComponent(Key.DES).toString(HEX) == "7CA110454A1A6E570131D9619DC1376E");

    // Make key a triple length DES key (168 bit)
    key.setComponent(Key.DES,
                new ByteString("7CA110454A1A6E570131D9619DC1376E9DC1376E0131D961", HEX));
    assert(key.getComponent(Key.DES).toString(HEX) ==
                "7CA110454A1A6E570131D9619DC1376E9DC1376E0131D961");

    // Create key from profile
    key = new Key("profiles/kp_single_des_1.xml");
    assert(key.getComponent(Key.DES).toString(HEX) == "7CA110454A1A6E57");

    // Change component initialized by profile
    key.setComponent(Key.DES, new ByteString("A110454A1A6E577C", HEX));
    assert(key.getComponent(Key.DES).toString(HEX) == "A110454A1A6E577C");

## getECPoint()

### Prototype

ByteString getECPoint()

### Description

Return an ECPoint object.

### Return

`org.bouncycastle.math.ec.ECPoint` | The ECPoint corresponding to the ECC_QX and ECC_QY components.

### Exceptions

Name | Value | Description
--- | --- | ---
GPError | GPError.INVALID_ARGUMENTS | Too many arguments in call
GPError | GPError.INVALID_DATA | ECC_QX and ECC_QY must be specified

### Example

    var key = new Key();
    key.setType(Key.PUBLIC);
    key.setComponent(Key.ECC_CURVE_OID, new ByteString("1.2.840.10045.3.1.1", OID));
    key.setComponent(Key.ECC_QX, new ByteString(
                "bba0c04725f939abe6a0d1e9ceb82f336b3a04205c6e5094", HEX));
    key.setComponent(Key.ECC_QY, new ByteString(
                "fe6d6a3f6f72616d7488113af4aba44581adee297b984a08", HEX));
    var ecp = key.getECPoint();
    assert(ecp.getAffineXCoord().toBigInteger().toString(16) == "bba0c04725f939abe6a0d1e9ceb82f336b3a04205c6e5094");
    assert(ecp.getAffineYCoord().toBigInteger().toString(16) == "fe6d6a3f6f72616d7488113af4aba44581adee297b984a08");

© Copyright 2003 - 2024 CardContact Systems GmbH , Minden, Germany