Package org.jgroups.protocols
Class ASYM_ENCRYPT
- java.lang.Object
-
- org.jgroups.stack.Protocol
-
- org.jgroups.protocols.Encrypt<java.security.KeyStore.PrivateKeyEntry>
-
- org.jgroups.protocols.ASYM_ENCRYPT
-
public class ASYM_ENCRYPT extends Encrypt<java.security.KeyStore.PrivateKeyEntry>
Encrypts and decrypts communication in JGroups by using a secret key distributed to all cluster members by the key server (coordinator) using asymmetric (public/private key) encryption.
The secret key is identical for all cluster members and is used to encrypt messages when sending and decrypt them when receiving messages. This protocol is typically placed underNAKACK2.
The current keyserver (always the coordinator) generates a secret key. When a new member joins, it asks the keyserver for the secret key. The keyserver encrypts the secret key with the joiner's public key and the joiner decrypts it with its private key and then installs it and starts encrypting and decrypting messages with the secret key.
View changes that identify a new keyserver will result in a new secret key being generated and then distributed to all cluster members. This overhead can be substantial in an application with a reasonable member churn.
This protocol is suited for an application that does not ship with a known key but instead it is generated and distributed by the keyserver. Since messages can only get encrypted and decrypted when the secret key was received from the keyserver, messages are dropped when the secret key hasn't been installed yet.- Author:
- Bela Ban, Steve Woodcock
-
-
Nested Class Summary
Nested Classes Modifier and Type Class Description protected static classASYM_ENCRYPT.Processing-
Nested classes/interfaces inherited from class org.jgroups.protocols.Encrypt
Encrypt.Decrypter
-
-
Field Summary
Fields Modifier and Type Field Description protected javax.crypto.Cipherasym_cipherprotected booleanchange_key_on_coord_leaveprotected booleanchange_key_on_leaveprotected static shortGMS_IDprotected KeyExchangekey_exchangeprotected java.security.KeyPairkey_pairprotected Addresskey_server_addrprotected java.util.Map<Address,byte[]>pub_mapprotected booleansend_group_keysprotected static java.lang.ThreadLocal<Address>srv_addrprotected booleanuse_external_key_exchange-
Fields inherited from class org.jgroups.protocols.Encrypt
asym_algorithm, asym_keylength, cipher_pool_size, decoding_ciphers, DEFAULT_SYM_ALGO, encoding_ciphers, encrypt_entire_message, key_map, key_map_max_size, local_addr, provider, secret_key, secure_random, sign_msgs, sym_algorithm, sym_iv_length, sym_keylength, sym_version, use_adler, view
-
Fields inherited from class org.jgroups.stack.Protocol
after_creation_hook, down_prot, ergonomics, id, log, stack, stats, up_prot
-
-
Constructor Summary
Constructors Constructor Description ASYM_ENCRYPT()
-
Method Summary
All Methods Static Methods Instance Methods Concrete Methods Modifier and Type Method Description protected MessageaddKeysToMessage(Message msg, boolean copy, boolean add_secret_keys, Address serialize_only)Adds the public and/or encrypted shared keys to the payload of msg.protected ASYM_ENCRYPT.ProcessingaddMetadata(Message msg, boolean add_secret_keys, Address include_secret_key_only_for, boolean attach_fetch_key_header)javax.crypto.CipherasymCipher()protected voidcacheGroupKey(byte[] version)Cache the current shared key to decrypt messages encrypted with the old shared group keyprotected static voidcacheServerAddress(Address srv)protected voidcreateNewKey(java.lang.String message)protected javax.crypto.SecretKeycreateSecretKey()Initialise the symmetric key if none is supplied in a keystoreprotected javax.crypto.spec.SecretKeySpecdecodeKey(byte[] encodedKey)java.lang.Objectdown(Event evt)An event is to be sent down the stack.java.lang.Objectdown(Message msg)A message is sent down the stack.protected booleandropMulticastMessageFromNonMember(Message msg)protected byte[]encryptSecretKey(java.security.Key secret_key, java.security.PublicKey public_key)Encrypts the current secret key with the requester's public key (the requester will decrypt it with its private key)ASYM_ENCRYPTfetchAndSetKeyExchange()protected static AddressgetCachedServerAddress()booleangetChangeKeyOnCoordLeave()booleangetChangeKeyOnLeave()protected byte[]getIv(Message msg)java.lang.StringgetKeyServerAddress()java.lang.StringgetPublicKeys()booleangetUseExternalKeyExchange()protected voidhandleView(View v)voidinit()Called after instance has been created (null constructor) and before protocol is started.protected voidinitKeyPair()Generates the public/private key pair from the init paramsprotected voidinstallPublicKeys(Address sender, byte[] buf, int offset, int length)protected voidinstallSharedGroupKey(Address sender, javax.crypto.SecretKey key, byte[] version)booleanisKeyServer()java.security.KeyPairkeyPair()AddresskeyServerAddr()ASYM_ENCRYPTkeyServerAddr(Address ks)protected java.security.PublicKeymakePublicKey(byte[] encodedKey)Used to reconstitute public key sent in byte form from peerprotected booleanprocessEncryptMessage(Message msg, EncryptHeader hdr, boolean retval)java.util.List<java.lang.Integer>providedDownServices()List of events that are provided to layers below (they will be handled when sent from down below)protected voidremoveKeysFromMessageAndInstall(Message msg, byte[] version)Removes the public and/or private keys from the payload of msg and installs them.protected static BufferserializeKeys(java.util.Map<Address,byte[]> keys)protected voidserializeKeys(ByteArrayDataOutputStream out, boolean serialize_shared_keys, Address serialize_only)Serializes all public keys and their corresponding encrypted shared group keys into a bufferASYM_ENCRYPTsetChangeKeyOnCoordLeave(boolean c)ASYM_ENCRYPTsetChangeKeyOnLeave(boolean c)voidsetKeyStoreEntry(java.security.KeyStore.PrivateKeyEntry entry)Sets the key store entry used to configure this protocol.ASYM_ENCRYPTsetUseExternalKeyExchange(boolean u)protected ASYM_ENCRYPT.ProcessingskipDownMessage(Message msg)Processes a message with a GMS header (e.g.protected booleanskipUpMessage(Message msg)Checks if the message contains a public key (and adds it to pub_map if present) or an encrypted group key (and installs it if present)voidstart()This method is called on aJChannel.connect(String).protected voidunserializeAndInstallKeys(Address sender, byte[] version, ByteArrayDataInputStream in)Unserializes public keys and installs them to pub_map, then reads encrypted shared keys and install our ownprotected java.util.Map<Address,byte[]>unserializeKeys(Address sender, byte[] buf, int offset, int length)java.lang.Objectup(Event evt)An event was received from the protocol below.java.lang.Objectup(Message msg)A single message was received.voidup(MessageBatch batch)Sends up a multiple messages in aMessageBatch.-
Methods inherited from class org.jgroups.protocols.Encrypt
_decrypt, asymAlgorithm, asymAlgorithm, asymKeylength, asymKeylength, code, createCipher, decryptMessage, encrypt, encryptAndSend, getAlgorithm, getModeAndPadding, handleEncryptedMessage, initCipher, initSymCiphers, inView, localAddress, makeIv, printCachedGroupKeys, secretKey, secureRandom, secureRandom, simIvLength, symAlgorithm, symAlgorithm, symIvLength, symKeyAlgorithm, symKeylength, symKeylength, symVersion, version
-
Methods inherited from class org.jgroups.stack.Protocol
accept, afterCreationHook, destroy, enableStats, getConfigurableObjects, getDownProtocol, getDownServices, getId, getIdsAbove, getLevel, getLog, getName, getProtocolStack, getSocketFactory, getThreadFactory, getTransport, getUpProtocol, getUpServices, getValue, isErgonomics, level, parse, providedUpServices, requiredDownServices, requiredUpServices, resetStatistics, resetStats, setDownProtocol, setErgonomics, setId, setLevel, setProtocolStack, setSocketFactory, setUpProtocol, setValue, statsEnabled, stop
-
-
-
-
Field Detail
-
GMS_ID
protected static final short GMS_ID
-
change_key_on_leave
protected boolean change_key_on_leave
-
change_key_on_coord_leave
protected boolean change_key_on_coord_leave
-
use_external_key_exchange
protected boolean use_external_key_exchange
-
key_exchange
protected KeyExchange key_exchange
-
key_server_addr
protected volatile Address key_server_addr
-
send_group_keys
protected volatile boolean send_group_keys
-
key_pair
protected java.security.KeyPair key_pair
-
asym_cipher
protected javax.crypto.Cipher asym_cipher
-
pub_map
protected final java.util.Map<Address,byte[]> pub_map
-
srv_addr
protected static final java.lang.ThreadLocal<Address> srv_addr
-
-
Method Detail
-
setKeyStoreEntry
public void setKeyStoreEntry(java.security.KeyStore.PrivateKeyEntry entry)
Description copied from class:EncryptSets the key store entry used to configure this protocol.- Specified by:
setKeyStoreEntryin classEncrypt<java.security.KeyStore.PrivateKeyEntry>- Parameters:
entry- a key store entry
-
getChangeKeyOnLeave
public boolean getChangeKeyOnLeave()
-
setChangeKeyOnLeave
public ASYM_ENCRYPT setChangeKeyOnLeave(boolean c)
-
getChangeKeyOnCoordLeave
public boolean getChangeKeyOnCoordLeave()
-
setChangeKeyOnCoordLeave
public ASYM_ENCRYPT setChangeKeyOnCoordLeave(boolean c)
-
getUseExternalKeyExchange
public boolean getUseExternalKeyExchange()
-
setUseExternalKeyExchange
public ASYM_ENCRYPT setUseExternalKeyExchange(boolean u)
-
keyPair
public java.security.KeyPair keyPair()
-
asymCipher
public javax.crypto.Cipher asymCipher()
-
keyServerAddr
public Address keyServerAddr()
-
keyServerAddr
public ASYM_ENCRYPT keyServerAddr(Address ks)
-
providedDownServices
public java.util.List<java.lang.Integer> providedDownServices()
Description copied from class:ProtocolList of events that are provided to layers below (they will be handled when sent from down below)- Overrides:
providedDownServicesin classProtocol
-
getPublicKeys
public java.lang.String getPublicKeys()
-
getKeyServerAddress
public java.lang.String getKeyServerAddress()
-
isKeyServer
public boolean isKeyServer()
-
init
public void init() throws java.lang.ExceptionDescription copied from class:ProtocolCalled after instance has been created (null constructor) and before protocol is started. Properties are already set. Other protocols are not yet connected and events cannot yet be sent.
-
start
public void start() throws java.lang.ExceptionDescription copied from class:ProtocolThis method is called on aJChannel.connect(String). Starts work. Protocols are connected and queues are ready to receive events. Will be called from bottom to top. This call will replace the START and START_OK events.- Overrides:
startin classProtocol- Throws:
java.lang.Exception- Thrown if protocol cannot be started successfully. This will cause the ProtocolStack to fail, soJChannel.connect(String)will throw an exception
-
down
public java.lang.Object down(Event evt)
Description copied from class:ProtocolAn event is to be sent down the stack. A protocol may want to examine its type and perform some action on it, depending on the event's type. If the event is a message MSG, then the protocol may need to add a header to it (or do nothing at all) before sending it down the stack usingdown_prot.down().
-
down
public java.lang.Object down(Message msg)
Description copied from class:ProtocolA message is sent down the stack. Protocols may examine the message and do something (e.g. add a header) with it before passing it down.
-
up
public java.lang.Object up(Event evt)
Description copied from class:ProtocolAn event was received from the protocol below. Usually the current protocol will want to examine the event type and - depending on its type - perform some computation (e.g. removing headers from a MSG event type, or updating the internal membership list when receiving a VIEW_CHANGE event). Finally the event is either a) discarded, or b) an event is sent down the stack usingdown_prot.down()or c) the event (or another event) is sent up the stack usingup_prot.up().
-
up
public java.lang.Object up(Message msg)
Description copied from class:ProtocolA single message was received. Protocols may examine the message and do something (e.g. add a header) with it before passing it up.
-
up
public void up(MessageBatch batch)
Description copied from class:ProtocolSends up a multiple messages in aMessageBatch. The sender of the batch is always the same, and so is the destination (null == multicast messages). Messages in a batch can be OOB messages, regular messages, or mixed messages, although the transport itself will create initial MessageBatches that contain only either OOB or regular messages. The default processing below sends messages up the stack individually, based on a matching criteria (callingProtocol.accept(org.jgroups.Message)), and - if true - callsProtocol.up(org.jgroups.Event)for that message and removes the message. If the batch is not empty, it is passed up, or else it is dropped. Subclasses should check if there are any messages destined for them (e.g. usingMessageBatch.getMatchingMessages(short,boolean)), then possibly remove and process them and finally pass the batch up to the next protocol. Protocols can also modify messages in place, e.g. ENCRYPT could decrypt all encrypted messages in the batch, not remove them, and pass the batch up when done.
-
dropMulticastMessageFromNonMember
protected boolean dropMulticastMessageFromNonMember(Message msg)
-
fetchAndSetKeyExchange
public ASYM_ENCRYPT fetchAndSetKeyExchange()
-
cacheServerAddress
protected static void cacheServerAddress(Address srv)
-
getCachedServerAddress
protected static Address getCachedServerAddress()
-
skipDownMessage
protected ASYM_ENCRYPT.Processing skipDownMessage(Message msg)
Processes a message with a GMS header (e.g. by adding the secret key to a JOIN response) and returns true if the message should be passed down (not encrypted) or false if the message needs to be encrypted- Returns:
- Processing
ASYM_ENCRYPT.Processing.DROPif the message needs to be dropped,ASYM_ENCRYPT.Processing.SKIPif the message needs to be skipped (not encrypted), orASYM_ENCRYPT.Processing.PROCESSif the message needs to be processed (= encrypted)
-
skipUpMessage
protected boolean skipUpMessage(Message msg)
Checks if the message contains a public key (and adds it to pub_map if present) or an encrypted group key (and installs it if present)
-
processEncryptMessage
protected boolean processEncryptMessage(Message msg, EncryptHeader hdr, boolean retval)
-
installPublicKeys
protected void installPublicKeys(Address sender, byte[] buf, int offset, int length)
-
addMetadata
protected ASYM_ENCRYPT.Processing addMetadata(Message msg, boolean add_secret_keys, Address include_secret_key_only_for, boolean attach_fetch_key_header)
-
addKeysToMessage
protected Message addKeysToMessage(Message msg, boolean copy, boolean add_secret_keys, Address serialize_only)
Adds the public and/or encrypted shared keys to the payload of msg. If msg already has a payload, the message will be copied and the new payload consists of the keys and the original payload- Parameters:
msg- The original message- Returns:
- A copy of the message
-
removeKeysFromMessageAndInstall
protected void removeKeysFromMessageAndInstall(Message msg, byte[] version)
Removes the public and/or private keys from the payload of msg and installs them. If there is some payload left (the original payload), the offset of the message will be changed. Otherwise, the payload will be nulled, to re-create the original message
-
serializeKeys
protected void serializeKeys(ByteArrayDataOutputStream out, boolean serialize_shared_keys, Address serialize_only) throws java.lang.Exception
Serializes all public keys and their corresponding encrypted shared group keys into a buffer- Throws:
java.lang.Exception
-
unserializeAndInstallKeys
protected void unserializeAndInstallKeys(Address sender, byte[] version, ByteArrayDataInputStream in)
Unserializes public keys and installs them to pub_map, then reads encrypted shared keys and install our own
-
serializeKeys
protected static Buffer serializeKeys(java.util.Map<Address,byte[]> keys) throws java.lang.Exception
- Throws:
java.lang.Exception
-
unserializeKeys
protected java.util.Map<Address,byte[]> unserializeKeys(Address sender, byte[] buf, int offset, int length)
-
createSecretKey
protected javax.crypto.SecretKey createSecretKey() throws java.lang.ExceptionInitialise the symmetric key if none is supplied in a keystore- Throws:
java.lang.Exception
-
initKeyPair
protected void initKeyPair() throws java.lang.ExceptionGenerates the public/private key pair from the init params- Throws:
java.lang.Exception
-
handleView
protected void handleView(View v)
- Overrides:
handleViewin classEncrypt<java.security.KeyStore.PrivateKeyEntry>
-
createNewKey
protected void createNewKey(java.lang.String message)
-
installSharedGroupKey
protected void installSharedGroupKey(Address sender, javax.crypto.SecretKey key, byte[] version) throws java.lang.Exception
- Throws:
java.lang.Exception
-
cacheGroupKey
protected void cacheGroupKey(byte[] version) throws java.lang.ExceptionCache the current shared key to decrypt messages encrypted with the old shared group key- Throws:
java.lang.Exception
-
encryptSecretKey
protected byte[] encryptSecretKey(java.security.Key secret_key, java.security.PublicKey public_key) throws java.lang.ExceptionEncrypts the current secret key with the requester's public key (the requester will decrypt it with its private key)- Throws:
java.lang.Exception
-
decodeKey
protected javax.crypto.spec.SecretKeySpec decodeKey(byte[] encodedKey) throws java.lang.Exception- Throws:
java.lang.Exception
-
makePublicKey
protected java.security.PublicKey makePublicKey(byte[] encodedKey)
Used to reconstitute public key sent in byte form from peer
-
getIv
protected byte[] getIv(Message msg)
-
-