use of org.apache.pulsar.common.api.proto.PulsarApi.EncryptionKeys in project incubator-pulsar by apache.
the class MessageCrypto method decrypt.
/*
* 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 ByteBuf decrypt(MessageMetadata msgMetadata, ByteBuf payload, CryptoKeyReader keyReader) {
// If dataKey is present, attempt to decrypt using the existing key
if (dataKey != null) {
ByteBuf 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
List<EncryptionKeys> encKeys = msgMetadata.getEncryptionKeysList();
EncryptionKeys encKeyInfo = encKeys.stream().filter(kbv -> {
byte[] encDataKey = kbv.getValue().toByteArray();
List<KeyValue> encKeyMeta = kbv.getMetadataList();
return decryptDataKey(kbv.getKey(), encDataKey, encKeyMeta, keyReader);
}).findFirst().orElse(null);
if (encKeyInfo == null || dataKey == null) {
// Unable to decrypt data key
return null;
}
return getKeyAndDecryptData(msgMetadata, payload);
}
use of org.apache.pulsar.common.api.proto.PulsarApi.EncryptionKeys in project incubator-pulsar by apache.
the class MessageCrypto method getKeyAndDecryptData.
private ByteBuf getKeyAndDecryptData(MessageMetadata msgMetadata, ByteBuf payload) {
ByteBuf decryptedData = null;
List<EncryptionKeys> encKeys = msgMetadata.getEncryptionKeysList();
// Go through all keys to retrieve data key from cache
for (int i = 0; i < encKeys.size(); i++) {
byte[] msgDataKey = encKeys.get(i).getValue().toByteArray();
byte[] keyDigest = digest.digest(msgDataKey);
SecretKey storedSecretKey = dataKeyCache.getIfPresent(ByteBuffer.wrap(keyDigest));
if (storedSecretKey != null) {
// Taking a small performance hit here if the hash collides. When it
// retruns a different key, decryption fails. At this point, we would
// call decryptDataKey to refresh the cache and come here again to decrypt.
decryptedData = decryptData(storedSecretKey, msgMetadata, payload);
// If decryption succeeded, data is non null
if (decryptedData != null) {
break;
}
} else {
// First time, entry won't be present in cache
log.debug("{} Failed to decrypt data or data key is not in cache. Will attempt to refresh", logCtx);
}
}
return decryptedData;
}
Aggregations