Пример #1
0
        /*
         * Decrypt the payload using the data key. Keys used to encrypt data key can be retrieved from msgMetadata
         *
         * @param msgMetadata Message Metadata
         *
         * @param payload Message which needs to be decrypted
         *
         * @param keyReader KeyReader implementation to retrieve key value
         *
         * @return decryptedData if success, null otherwise
         */
        public byte[] Decrypt(MessageMetadata msgMetadata, byte[] payload, ICryptoKeyReader keyReader)
        {
            // If dataKey is present, attempt to decrypt using the existing key
            if (_dataKey != null)
            {
                var decryptedData = GetKeyAndDecryptData(msgMetadata, payload);
                // If decryption succeeded, data is non null
                if (decryptedData != null)
                {
                    return(decryptedData);
                }
            }

            // dataKey is null or decryption failed. Attempt to regenerate data key
            IList <EncryptionKeys> encKeys = msgMetadata.EncryptionKeys;
            var encKeyInfo = encKeys.Where(kbv =>
            {
                var encDataKey = kbv.Value;
                IList <KeyValue> encKeyMeta = kbv.Metadatas;
                return(DecryptDataKey(kbv.Key, encDataKey, encKeyMeta, keyReader));
            }).DefaultIfEmpty(null).First();

            if (encKeyInfo == null || _dataKey == null)
            {
                // Unable to decrypt data key
                return(null);
            }

            return(GetKeyAndDecryptData(msgMetadata, payload));
        }
Пример #2
0
        /*
         * Encrypt data key using the public key(s) in the argument. <p> If more than one key name is specified, data key is
         * encrypted using each of those keys. If the public key is expired or changed, application is responsible to remove
         * the old key and add the new key <p>
         *
         * @param keyNames List of public keys to encrypt data key
         *
         * @param keyReader Implementation to read the key values
         *
         */
        public virtual void AddPublicKeyCipher(ISet <string> keyNames, ICryptoKeyReader keyReader)
        {
            // Generate data key
            _keyGenerator.GenerateKey();
            _dataKey = _keyGenerator.Key;

            foreach (var key in keyNames)
            {
                AddPublicKeyCipher(key, keyReader);
            }
        }
Пример #3
0
        private void AddPublicKeyCipher(string keyName, ICryptoKeyReader keyReader)
        {
            if (string.ReferenceEquals(keyName, null) || keyReader == null)
            {
                throw new PulsarClientException.CryptoException("Keyname or KeyReader is null");
            }

            // Read the public key and its info using callback
            var keyInfo      = keyReader.GetPublicKey(keyName, null);
            var encryptedKey = CryptoHelper.Encrypt(_dataKey, keyInfo.Key);
            var eki          = new EncryptionKeyInfo(encryptedKey, keyInfo.Metadata);

            _encryptedDataKeyMap[keyName] = eki;
        }
Пример #4
0
        private bool DecryptDataKey(string keyName, byte[] encryptedDataKey, IList <KeyValue> encKeyMeta, ICryptoKeyReader keyReader)
        {
            // Read the private key info using callback
            EncryptionKeyInfo keyInfo = keyReader.GetPrivateKey(keyName, encKeyMeta.ToDictionary(x => x.Key, x => x.Value));

            // Convert key from byte to PivateKey

            // Decrypt data key to decrypt messages
            byte[] dataKeyValue;
            string keyDigest;

            try
            {
                // Decrypt data key using private key
                dataKeyValue = CryptoHelper.Decrypt(encryptedDataKey, keyInfo.Key);
                keyDigest    = Convert.ToBase64String(_hash.ComputeHash(encryptedDataKey));
            }
            catch (Exception e)
            {
                _log.Error($"{_logCtx} Failed to decrypt data key {keyName} to decrypt messages {e.Message}");
                return(false);
            }
            _dataKey = dataKeyValue;
            _dataKeyCache.Put(keyDigest, _dataKey);
            return(true);
        }
Пример #5
0
        /*
         * Encrypt the payload using the data key and update message metadata with the keyname & encrypted data key
         *
         * @param encKeys One or more public keys to encrypt data key
         *
         * @param msgMetadata Message Metadata
         *
         * @param payload Message which needs to be encrypted
         *
         * @return encryptedData if success
         */

        public virtual byte[] Encrypt(ISet <string> encKeys, ICryptoKeyReader keyReader, MessageMetadata msgMetadata, byte[] payload)
        {
            if (encKeys.Count == 0)
            {
                return(payload);
            }

            // Update message metadata with encrypted data key
            foreach (var keyName in encKeys)
            {
                if (!_encryptedDataKeyMap.TryGetValue(keyName, out var e))
                {
                    // Attempt to load the key. This will allow us to load keys as soon as
                    // a new key is added to producer config
                    AddPublicKeyCipher(keyName, keyReader);
                }
                var keyInfo = _encryptedDataKeyMap[keyName];
                if (keyInfo != null)
                {
                    if (keyInfo.Metadata != null && keyInfo.Metadata.Count > 0)
                    {
                        IList <KeyValue> kvList = new List <KeyValue>();
                        keyInfo.Metadata.ToList().ForEach(m =>
                        {
                            kvList.Add(new KeyValue
                            {
                                Key   = m.Key,
                                Value = m.Value
                            });
                        });
                        var encKey = new EncryptionKeys {
                            Key = keyName, Value = keyInfo.Key
                        };
                        encKey.Metadatas.AddRange(kvList);
                        msgMetadata.EncryptionKeys.Add(encKey);
                    }
                    else
                    {
                        msgMetadata.EncryptionKeys.Add(new EncryptionKeys {
                            Key = keyName, Value = keyInfo.Key
                        });
                    }
                }
                else
                {
                    // We should never reach here.
                    _log.Error($"{_logCtx} Failed to find encrypted Data key for key {keyName}.");
                }
            }

            // Create gcm param
            // TODO: Replace random with counter and periodic refreshing based on timer/counter value
            _secureRandom.NextBytes(_iv);
            // Update message metadata with encryption param
            msgMetadata.EncryptionParam = _iv;
            try
            {
                // Encrypt the data

                var encData = CryptoHelper.Encrypt(_dataKey, payload, _iv, TagLen);

                return(encData);
            }
            catch (Exception e)
            {
                _log.Error($"{_logCtx} Failed to encrypt message. {e}");
                throw new PulsarClientException.CryptoException(e.Message);
            }
        }
Пример #6
0
 public ProducerConfigBuilder <T> CryptoKeyReader(ICryptoKeyReader cryptoKeyReader)
 {
     _conf.CryptoKeyReader = cryptoKeyReader;
     return(this);
 }