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 class
ASYM_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.Cipher
asym_cipher
protected boolean
change_key_on_coord_leave
protected boolean
change_key_on_leave
protected static short
GMS_ID
protected KeyExchange
key_exchange
protected java.security.KeyPair
key_pair
protected Address
key_server_addr
protected java.util.Map<Address,byte[]>
pub_map
protected boolean
send_group_keys
protected static java.lang.ThreadLocal<Address>
srv_addr
protected boolean
use_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 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.protected ASYM_ENCRYPT.Processing
addMetadata(Message msg, boolean add_secret_keys, Address include_secret_key_only_for, boolean attach_fetch_key_header)
javax.crypto.Cipher
asymCipher()
protected void
cacheGroupKey(byte[] version)
Cache the current shared key to decrypt messages encrypted with the old shared group keyprotected static void
cacheServerAddress(Address srv)
protected void
createNewKey(java.lang.String message)
protected javax.crypto.SecretKey
createSecretKey()
Initialise the symmetric key if none is supplied in a keystoreprotected javax.crypto.spec.SecretKeySpec
decodeKey(byte[] encodedKey)
java.lang.Object
down(Event evt)
An event is to be sent down the stack.java.lang.Object
down(Message msg)
A message is sent down the stack.protected boolean
dropMulticastMessageFromNonMember(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_ENCRYPT
fetchAndSetKeyExchange()
protected static Address
getCachedServerAddress()
boolean
getChangeKeyOnCoordLeave()
boolean
getChangeKeyOnLeave()
protected byte[]
getIv(Message msg)
java.lang.String
getKeyServerAddress()
java.lang.String
getPublicKeys()
boolean
getUseExternalKeyExchange()
protected void
handleView(View v)
void
init()
Called after instance has been created (null constructor) and before protocol is started.protected void
initKeyPair()
Generates the public/private key pair from the init paramsprotected void
installPublicKeys(Address sender, byte[] buf, int offset, int length)
protected void
installSharedGroupKey(Address sender, javax.crypto.SecretKey key, byte[] version)
boolean
isKeyServer()
java.security.KeyPair
keyPair()
Address
keyServerAddr()
ASYM_ENCRYPT
keyServerAddr(Address ks)
protected java.security.PublicKey
makePublicKey(byte[] encodedKey)
Used to reconstitute public key sent in byte form from peerprotected boolean
processEncryptMessage(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 void
removeKeysFromMessageAndInstall(Message msg, byte[] version)
Removes the public and/or private keys from the payload of msg and installs them.protected static Buffer
serializeKeys(java.util.Map<Address,byte[]> keys)
protected void
serializeKeys(ByteArrayDataOutputStream out, boolean serialize_shared_keys, Address serialize_only)
Serializes all public keys and their corresponding encrypted shared group keys into a bufferASYM_ENCRYPT
setChangeKeyOnCoordLeave(boolean c)
ASYM_ENCRYPT
setChangeKeyOnLeave(boolean c)
void
setKeyStoreEntry(java.security.KeyStore.PrivateKeyEntry entry)
Sets the key store entry used to configure this protocol.ASYM_ENCRYPT
setUseExternalKeyExchange(boolean u)
protected ASYM_ENCRYPT.Processing
skipDownMessage(Message msg)
Processes a message with a GMS header (e.g.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)void
start()
This method is called on aJChannel.connect(String)
.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 ownprotected java.util.Map<Address,byte[]>
unserializeKeys(Address sender, byte[] buf, int offset, int length)
java.lang.Object
up(Event evt)
An event was received from the protocol below.java.lang.Object
up(Message msg)
A single message was received.void
up(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:Encrypt
Sets the key store entry used to configure this protocol.- Specified by:
setKeyStoreEntry
in 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:Protocol
List of events that are provided to layers below (they will be handled when sent from down below)- Overrides:
providedDownServices
in classProtocol
-
getPublicKeys
public java.lang.String getPublicKeys()
-
getKeyServerAddress
public java.lang.String getKeyServerAddress()
-
isKeyServer
public boolean isKeyServer()
-
init
public void init() throws java.lang.Exception
Description copied from class:Protocol
Called 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.Exception
Description copied from class:Protocol
This 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:
start
in 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:Protocol
An 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:Protocol
A 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:Protocol
An 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:Protocol
A 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:Protocol
Sends 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.DROP
if the message needs to be dropped,ASYM_ENCRYPT.Processing.SKIP
if the message needs to be skipped (not encrypted), orASYM_ENCRYPT.Processing.PROCESS
if 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.Exception
Initialise the symmetric key if none is supplied in a keystore- Throws:
java.lang.Exception
-
initKeyPair
protected void initKeyPair() throws java.lang.Exception
Generates the public/private key pair from the init params- Throws:
java.lang.Exception
-
handleView
protected void handleView(View v)
- Overrides:
handleView
in 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.Exception
Cache 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.Exception
Encrypts 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)
-
-