/* * 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)); }
/* * 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); } }
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; }
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); }
/* * 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); } }
public ProducerConfigBuilder <T> CryptoKeyReader(ICryptoKeyReader cryptoKeyReader) { _conf.CryptoKeyReader = cryptoKeyReader; return(this); }