EC-Schlüssel und -Operationen

Die JCE-Hardwareimplementierung (IBMJCECCA) erweitert die EC-Schlüssel, die in der JCE-Softwareimplementierung verfügbar sind.

Schlüssel

In der Software-JCE-Implementierung wird das tatsächliche EC-Schlüsselmaterial im Schlüsselobjekt gespeichert. Die IBMJCECCA-Implementierung erweitert dies durch Hinzufügen der folgenden alternativen Darstellungen:
  • Ein EC-Schlüsselpaar, das bereits im CCA-Schlüsselspeicherbereich gespeichert ist. Die Schlüsselobjekte enthalten den CCA-Schlüsselspeicherbereichskennsatz für die Schlüssel.
    Das folgende Beispiel veranschaulicht die Erstellung von EC-Schlüsselobjekten für ein Schlüsselpaar, das bereits im CCA-Schlüsselspeicherbereich mit dem Kennsatz "MYEC.KEYPAIR", dann wird der CCA-Schlüsselspeicherbereichseintrag gelöscht:
    // create key objects for an existing CCA key storage area entry
    // (No checking is done to verify that the entry exists.)
    //
    KeyFactory rsaKeyFactory = KeyFactory.getInstance("EC", "IBMJCECCA");
    
    KeyLabelKeySpec spec = new KeyLabelKeySpec("MYEC.KEYPAIR");
    PublicKey pubKey = ecKeyFactory.generatePublic(spec);
    PrivateKey privKey = ecKeyFactory.generatePrivate(spec);
    
    // delete the entry from the CCA key storage area
    // (An exception is thrown if the CCA key storage area entry does not exist.)
    //
    ((ECPrivateHWKey)privKey).deletePKDSEntry();
    
    //
    // Note that, in this example, the Java key objects still
    // exist, but the CCA key storage area entry they represent has been deleted.
    // Any attempt to use the objects "pubKey" or "privKey" will
    // cause an exception containing a hardware return code and
    // reason code.
    //
  • Ein EC-Schlüsselpaar, das von einem IBMJCECCA-Aufruf an die zugrunde liegende Hardware generiert und anschließend im CCA-Schlüsselspeicherbereich gespeichert wird. Die Schlüsselobjekte enthalten den CCA-Schlüsselspeicherbereichskennsatz für die Schlüssel.
    Das folgende Beispiel veranschaulicht die Generierung eines EC-Schlüsselpaares, das im CCA-Schlüsselspeicherbereich mit einem automatisch generierten Kennsatz gespeichert wird, und die Erstellung von Schlüsselobjekten, die den Kennsatz für den CCA-Schlüsselspeicherbereichseintrag enthalten.
    // create a new CCA key storage area entry and key objects to represent it.
    //
    AlgorithmParameterSpec spec = new ECHWKeyParameterSpec(256,
                                                           KeyHWAttributeValues.PKDS,
                                                           KeyHWAttributeValues.KEYMANAGEMENT);
                                                           
    KeyPairGenerator generator = KeyPairGenerator.getInstance("EC", "IBMJCECCA");
    generator.initialize(spec);
    
    KeyPair keyPair = generator.generateKeyPair();
    PublicKey pubKey = keyPair.getPublic();
    PrivateKey privKey = keyPair.getPrivate();
    
    // delete the entry from the CCA key storage area
    // (An exception is thrown if the CCA key storage area entry does not exist.)
    //
    ((ECPrivateHWKey)privKey).deletePKDSEntry();
    
    //
    // Note that, in this example, the Java key objects still
    // exist, but the CCA key storage area entry they represent has been deleted.
    // Any attempt to use the objects "pubKey" or "privKey" will
    // cause an exception containing a hardware return code and
    // reason code.
    //
    Das folgende Beispiel veranschaulicht, wie ein EC-Schlüsselpaar generiert wird, das im CCA-Schlüsselspeicherbereich mit dem Kennsatz "ANEC.KEYPAIR" und Schlüsselobjekte erstellen, die den Kennsatz für den CCA-Schlüsselspeicherbereichseintrag enthalten:
    // create a new CCA key storage area entry and key objects to represent it
    //
    AlgorithmParameterSpec spec = new ECHWKeyParameterSpec(256, 
                                                           KeyHWAttributeValues.PKDS,
                                                           KeyHWAttributeValues.KEYMANAGEMENT,
                                                           "ANEC.KEYPAIR");
    
    KeyPairGenerator generator = KeyPairGenerator.getInstance("EC", "IBMJCECCA");
    generator.initialize(spec);
    
    KeyPair keyPair = generator.generateKeyPair();
    PublicKey pubKey = keyPair.getPublic();
    PrivateKey privKey = keyPair.getPrivate();
    
    // delete the entry from the CCA key storage area
    // (An exception is thrown if the CCA key storage area entry does not exist.)
    //
    ((ECPrivateHWKey)privKey).deletePKDSEntry();
    
    //
    // Note that, in this example, the Java key objects still
    // exist, but the CCA key storage area entry they represent has been deleted.
    // Any attempt to use the objects "pubKey" or "privKey" will
    // cause an exception containing a hardware return code and
    // reason code.
    //

Operationen

Der IBMJCECCA-Provider unterstützt die Diffie-Hellman-Schlüsselvereinbarung mit elliptischen Kurvenschlüsseln (Elliptic Curve Diffie-Hellman) unter Verwendung der Hardwareverschlüsselung, die die Verwendung der gespeicherten Schlüsselpaare für elliptische Kurven im CCA-Schlüsselspeicherbereich mit höherer Sicherheit ermöglicht. Mit einem CCA-Schlüsselspeicherbereich gespeicherten elliptischen Kurvenschlüsselpaar wird der sensible private Schlüssel nie im Klartext verfügbar gemacht.

Die Ausführung einer Diffie-Hellman-Schlüsselvereinbarung unter Verwendung von elliptischen Kurvenschlüsseln mit dem IBMJCECCA-Provider ermöglicht die Generierung unformatierter geheimer Schlüssel aus dem Diffie-Hellman-Prozess und ermöglicht die Schlüsselableitung symmetrischer Hardwareschlüssel unter Verwendung des Schlüsselvereinbarungsschemas des statischen Unified Model. Standardmäßig enthält das resultierende abgeleitete Schlüsselobjekt einen Schlüssel SECURE_INTERNAL_TOKEN.

Wenn ein KDFParameterSpec -Objekt ohne Typ oder Typ KeyType.SECURE_INTERNAL_TOKEN erstellt wird und die Elliptic Curve Diffie-Hellman-Schlüsselvereinbarung mit diesem KDFParameterSpec -Objekt initialisiert wird, enthält das resultierende abgeleitete symmetrische Schlüsselobjekt ein SECURE_INTERNAL_TOKEN-Hardware-Token. Dieses Token enthält den mit dem Hostprimärschlüssel verschlüsselten Schlüssel. Wenn ein KDFParameterSpec -Objekt mit dem Typ KeyType.CKDSerstellt wird und die Elliptic Curve Diffie-Hellman-Schlüsselvereinbarung mit diesem KDFParameterSpec -Objekt initialisiert wird, enthält das resultierende abgeleitete symmetrische Schlüsselobjekt den Kennsatz für einen CCA-Schlüsselspeicherbereichseintrag, der ein Hardware-Token enthält. Dieses Token enthält den mit dem Hostprimärschlüssel verschlüsselten Schlüssel.

Elliptic Curve Diffie-Hellman unterstützt die Schlüsselableitung symmetrischer Hardwareschlüssel mit unterschiedlichen Schlüsselnutzungsattributen. Die folgenden Schlüsselalgorithmen und Verwendungstypen werden unterstützt:

  • CIPHER DES-Schlüssel
  • CIPHER, EXPORTER oder IMPORTER mit doppelter Länge (112 -Bit) Triple DES-Schlüssel
  • AES-Schlüssel DATA, EXPORTER oder IMPORTER

Eine ausführliche Erläuterung der Verwendungstypen für symmetrische Schlüssel finden Sie im Abschnitt Funktionen der symmetrischen Chiffrierschlüssel in der Dokumentation zu Ihrer Version von z/OS. Beachten Sie, dass nicht alle symmetrischen Schlüsselverwendungstypen, die in CCA verfügbar sind, vom Provider IBMJCECCA unterstützt werden.

Wenn Sie die Elliptic Curve Diffie-Hellman-Schlüsselvereinbarung für die Schlüsselableitung initialisieren, stellen Sie sicher, dass ein KDFParameterSpec -Objekt mit gemeinsam genutzten Informationen erstellt und verwendet wird. Ein eindeutiger gemeinsam genutzter Informationssatz, der jede Elliptic Curve Diffie-Hellman-Schlüsselvereinbarung begleitet, stellt sicher, dass dasselbe Schlüsselmaterial nicht mehr als einmal abgeleitet wird. Weitere Informationen und Empfehlungen zur Formatierung dieses Felds finden Sie in der Veröffentlichung NIST SP 800-56A .

Das folgende Beispiel veranschaulicht die Generierung eines unformatierten geheimen Schlüssels aus dem Diffie-Hellman-Prozess:

// Party A generates a shared secret by using his or her own private
// EC key and the public EC key of party B
//
KeyAgreement partyAKeyAgreement = KeyAgreement.getInstance("ECDH", "IBMJCECCA");
partyAKeyAgreement.init(partyAPrivateKey, (SecureRandom) null);
partyAKeyAgreement.doPhase(partyBPublicKey, true);
byte[] partyASharedSecret = partyAKeyAgreement.generateSecret();

// Party B generates a shared secret by using his or her own private
// EC key and the public EC key of party A
//
KeyAgreement partyBKeyAgreement = KeyAgreement.getInstance("ECDH", "IBMJCECCA");
partyBKeyAgreement.init(partyBPrivateKey, (SecureRandom) null);
partyBKeyAgreement.doPhase(partyAPublicKey, true);
byte[] partyBSharedSecret = partyBKeyAgreement.generateSecret();

// The shared secret generated through this key agreement process
// by both party A and party B should have the same byte array contents
      

Das folgende Beispiel veranschaulicht die Schlüsselableitung von DES-CIPHER-Hardwareschlüsseln unter Verwendung des statischen einheitlichen Modells des Schlüsselvereinbarungsschemas:

import com.ibm.crypto.hdwrCCA.provider.SymmetricKeyConstants.KeyType;
import com.ibm.crypto.hdwrCCA.provider.SymmetricKeyConstants.KeyUsage;

// Party A
//
KeyAgreement partyAKeyAgreement = KeyAgreement.getInstance("ECDH", "IBMJCECCA");

// Party A wants to derive a 56-bit hardware CIPHER key enciphered
// under the local primary key, the sharedInfo byte array is uniquely
// constructed for this key derivation and shared with party B
//
KDFParameterSpec partyASpec = new KDFParameterSpec(
        56, sharedInfo, KeyType.SECURE_INTERNAL_TOKEN, null, KeyUsage.OP_CIPHER);

// Party A derives a hardware DES key by using his or her own private
// EC key and the public EC key of party B
//
partyAKeyAgreement.init(partyAPrivateKey, partyASpec, (SecureRandom) null);
partyAKeyAgreement.doPhase(partyBPublicKey, true);
SecretKey partyASecretKey = partyAKeyAgreement.generateSecret("DES");


// Party B
//
KeyAgreement partyBKeyAgreement = KeyAgreement.getInstance("ECDH", "IBMJCECCA");

// Party B uses the exact same key derivation specification as party A
// Party B must also use the exact same sharedInfo byte array as party A
//
KDFParameterSpec partyBSpec = new KDFParameterSpec(
        56, sharedInfo, KeyType.SECURE_INTERNAL_TOKEN, null, KeyUsage.OP_CIPHER);

// Party B derives a hardware DES key by using his or her own private
// EC key and the public EC key of party A
//
partyBKeyAgreement.init(partyBPrivateKey, partyBSpec, (SecureRandom) null);
partyBKeyAgreement.doPhase(partyAPublicKey, true);
SecretKey partyBSecretKey = partyBKeyAgreement.generateSecret("DES");

// The same hardware DES key is generated through this key derivation
// process by both party A and party B
      

Das folgende Beispiel veranschaulicht die Schlüsselableitung eines Triple DES EXPORTER-Schlüssels mit doppelter Länge (112-Bit) und eines Triple DES IMPORTER-Schlüssels mit doppelter Länge unter Verwendung des statischen einheitlichen Modells des Schlüsselvereinbarungsschemas. Beide Schlüssel werden im CCA-Schlüsselspeicherbereich gespeichert:

import com.ibm.crypto.hdwrCCA.provider.SymmetricKeyConstants.KeyType;
import com.ibm.crypto.hdwrCCA.provider.SymmetricKeyConstants.KeyUsage;

// Party A
//
KeyAgreement partyAKeyAgreement = KeyAgreement.getInstance("ECDH", "IBMJCECCA");

// Party A wants to derive an 112-bit hardware EXPORTER key enciphered
// under the local primary key and stored in the CCA key storage area, the sharedInfo
// byte array is uniquely constructed for this key derivation and shared
// with party B
//
KDFParameterSpec partyASpec = new KDFParameterSpec(
        112, sharedInfo, KeyType.CKDS, null, KeyUsage.OP_EXPORTER);

// Party A derives a double length Triple DES EXPORTER key by using
// his or her own private EC key and the public EC key of party B
//
partyAKeyAgreement.init(partyAPrivateKey, partyASpec, (SecureRandom) null);
partyAKeyAgreement.doPhase(partyBPublicKey, true);
SecretKey partyAExporterKey = partyAKeyAgreement.generateSecret("DESede");


// Party B
//
KeyAgreement partyBKeyAgreement = KeyAgreement.getInstance("ECDH", "IBMJCECCA");

// Party B uses mostly the same key derivation specification as
// party A, with the exception that he or she is deriving an IMPORTER
// key instead of an EXPORTER key. With an IMPORTER key, party B is
// able to import keys that are exported with party A's EXPORTER key

// Party B must use the exact same sharedInfo byte array as party A
//
KDFParameterSpec partyBSpec = new KDFParameterSpec(
        112, sharedInfo, KeyType.CKDS, null, KeyUsage.OP_IMPORTER);

// Party B derives a double length Triple DES IMPORTER key by using
// his or her own private EC key and the public EC key of party A.
//
partyBKeyAgreement.init(partyBPrivateKey, partyBSpec, (SecureRandom) null);
partyBKeyAgreement.doPhase(partyAPublicKey, true);
SecretKey partyBImporterKey = partyBKeyAgreement.generateSecret("DESede");

// The hardware Triple DES keys generated through this key derivation
// process by party A and party B are an EXPORTER/IMPORTER key pair

// Keys exported or wrapped by party A's EXPORTER key may be imported
// or unwrapped by party B's IMPORTER key
      

Das folgende Beispiel veranschaulicht die Schlüsselableitung eines Triple DES EXPORTER-Schlüssels mit doppelter Länge (112-Bit) und eines Triple DES IMPORTER-Schlüssels mit doppelter Länge unter Verwendung des statischen einheitlichen Modells des Schlüsselvereinbarungsschemas. In diesem Beispiel werden der EXPORTER-Schlüssel und der IMPORTER-Schlüssel mit aktivierter NoCvKEK erstellt. Beide Schlüssel werden im CCA-Schlüsselspeicherbereich gespeichert:

import com.ibm.crypto.hdwrCCA.provider.SymmetricKeyConstants.KeyType;
import com.ibm.crypto.hdwrCCA.provider.SymmetricKeyConstants.KeyUsage;

// Party A
//
KeyAgreement partyAKeyAgreement = KeyAgreement.getInstance("ECDH", "IBMJCECCA");

// Party A wants to derive an 112-bit hardware EXPORTER key enciphered
// under the local primary key and stored in the CCA key storage area, the sharedInfo
// byte array is uniquely constructed for this key derivation and shared
// with party B.
// The last parameter specifies that the NoCvKEK option should be
// enabled.
//
KDFParameterSpec partyASpec = new KDFParameterSpec(
        112, sharedInfo, KeyType.CKDS, null, KeyUsage.OP_EXPORTER, true);

// Party A derives a double length Triple DES EXPORTER key by using
// his or her own private EC key and the public EC key of party B
//
partyAKeyAgreement.init(partyAPrivateKey, partyASpec, (SecureRandom) null);
partyAKeyAgreement.doPhase(partyBPublicKey, true);
SecretKey partyAExporterKey = partyAKeyAgreement.generateSecret("DESede");


// Party B
//
KeyAgreement partyBKeyAgreement = KeyAgreement.getInstance("ECDH", "IBMJCECCA");

// Party B uses mostly the same key derivation specification as
// party A, with the exception that he or she is deriving an IMPORTER
// key instead of an EXPORTER key. With an IMPORTER key, party B is
// able to import keys that are exported with party A's EXPORTER key

// Party B must use the exact same sharedInfo byte array as party A
// The last parameter specifies that the NoCvKEK option should be
// enabled.
//
KDFParameterSpec partyBSpec = new KDFParameterSpec(
        112, sharedInfo, KeyType.CKDS, null, KeyUsage.OP_IMPORTER, true);

// Party B derives a double length Triple DES IMPORTER key by using
// his or her own private EC key and the public EC key of party A
//
partyBKeyAgreement.init(partyBPrivateKey, partyBSpec, (SecureRandom) null);
partyBKeyAgreement.doPhase(partyAPublicKey, true);
SecretKey partyBImporterKey = partyBKeyAgreement.generateSecret("DESede");

// The hardware Triple DES keys generated through this key derivation
// process by party A and party B are an EXPORTER/IMPORTER key pair

// Keys exported or wrapped by party A's EXPORTER key may be imported
// or unwrapped by party B's IMPORTER key.  Because the keys have the
// NoCvKEK option enabled, they are suitable for exchanging keys with
// non-z systems.
      

Informationen zu EXPORTER-und IMPORTER-Schlüsseln finden Sie unter Symmetrische Transportschlüssel (Schlüsselverschlüsselungsschlüssel).

Das folgende Beispiel veranschaulicht die Schlüsselableitung eines 256-Bit-AES-DATA-Hardwareschlüssels unter Verwendung des statischen einheitlichen Modells des Schlüsselvereinbarungsschemas:

import com.ibm.crypto.hdwrCCA.provider.SymmetricKeyConstants.KeyType;
import com.ibm.crypto.hdwrCCA.provider.SymmetricKeyConstants.KeyUsage;

// Party A
//
KeyAgreement partyAKeyAgreement = KeyAgreement.getInstance("ECDH", "IBMJCECCA");

// Party A wants to derive a 256-bit hardware DATA key enciphered
// under the local primary key, the sharedInfo byte array is uniquely
// constructed for this key derivation and shared with party B
//
KDFParameterSpec partyASpec = new KDFParameterSpec(
        256, sharedInfo, KeyType.SECURE_INTERNAL_TOKEN, null, KeyUsage.OP_DATA);

// Party A derives a 256-bit hardware AES key by using his or her own
// private EC key and the public EC key of party B
//
partyAKeyAgreement.init(partyAPrivateKey, partyASpec, (SecureRandom) null);
partyAKeyAgreement.doPhase(partyBPublicKey, true);
SecretKey partyASecretKey = partyAKeyAgreement.generateSecret("AES");


// Party B
//
KeyAgreement partyBKeyAgreement = KeyAgreement.getInstance("ECDH", "IBMJCECCA");

// Party B uses the exact same key derivation specification as party A
// Party B must use the exact same sharedInfo byte array as party A
//
KDFParameterSpec partyBSpec = new KDFParameterSpec(
        256, sharedInfo, KeyType.SECURE_INTERNAL_TOKEN, null, KeyUsage.OP_DATA);

// Party B derives a 256-bit hardware AES key by using his or her own
// private EC key and the public EC key of party A
//
partyBKeyAgreement.init(partyBPrivateKey, partyBSpec, (SecureRandom) null);
partyBKeyAgreement.doPhase(partyAPublicKey, true);
SecretKey partyBSecretKey = partyBKeyAgreement.generateSecret("AES");

// The same hardware AES key is generated through this key derivation
// process by both party A and party B