From 2ead761278618ac760ed312eae155a41dc757c9a Mon Sep 17 00:00:00 2001 From: Himaja Dhanyamraju <43470317+HimajaDhanyamraju2@users.noreply.github.com> Date: Tue, 6 Feb 2024 16:34:26 +0530 Subject: [PATCH] MOSIP-24522 (#240) * MOSIP-24522 Signed-off-by: HimajaDhanyamraju2 * Testing base64 encoded encryption key Signed-off-by: HimajaDhanyamraju2 * Testing with base64 encoded encryption key Signed-off-by: HimajaDhanyamraju2 --------- Signed-off-by: HimajaDhanyamraju2 Signed-off-by: Himaja Dhanyamraju <43470317+HimajaDhanyamraju2@users.noreply.github.com> --- hub/hub_service.bal | 16 +++++++++------- hub/modules/config/configurations.bal | 15 +++++++++++++-- hub/start_hub.bal | 25 ++++++++++++++++++++----- 3 files changed, 42 insertions(+), 14 deletions(-) diff --git a/hub/hub_service.bal b/hub/hub_service.bal index 4d28434..f9621b2 100644 --- a/hub/hub_service.bal +++ b/hub/hub_service.bal @@ -25,6 +25,7 @@ import kafkaHub.health_check as healthcheck; import ballerina/jballerina.java; import ballerina/crypto; import ballerina/random; +import ballerina/lang.array; http:Service healthCheckService = service object { @@ -220,19 +221,20 @@ service object { if (message.hubSecret is string) { string hubSecret = message.hubSecret; - log:printInfo("Secret before Encryption", secret = hubSecret); string encryptionKey = config:HUB_SECRET_ENCRYPTION_KEY; - log:printInfo("Encryption of the hubsecret with configured key", encryptionKey = encryptionKey); + byte[] encryptionKeyInBytes = (config:HUB_SECRET_ENCRYPTION_KEY_FORMAT).equalsIgnoreCaseAscii("base64-encoded-bytes") ? (check array:fromBase64(encryptionKey)) : encryptionKey.toBytes(); byte[16] initialVector = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]; foreach int i in 0...15 { initialVector[i] = (check random:createIntInRange(0, 255)); } - log:printInfo("Random generated iv value", iv = initialVector); - byte[] cipherText = check crypto:encryptAesGcm(hubSecret.toBytes(), encryptionKey.toBytes(), initialVector); - log:printInfo("Encrypted cipher text value", cipher = cipherText); + byte[32] randomEncKey = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]; + foreach int i in 0...31 { + randomEncKey[i] = (check random:createIntInRange(0, 255)); + } + log:printInfo("Base64 encoded random encryption key for testing", base64EncodedKey = randomEncKey.toBase64()); + byte[] cipherText = check crypto:encryptAesGcm(hubSecret.toBytes(), encryptionKeyInBytes, initialVector); cipherText.push(...initialVector); - log:printInfo("Encrypted cipher after appending iv", cipher = cipherText); - message.hubSecret = cipherText.toBase64(); + message.hubSecret = config:ENCRYPTED_SECRET_PREFIX + cipherText.toBase64() + config:ENCRYPTED_SECRET_SUFFIX; } error? persistingResult = persist:addSubscription(message.cloneReadOnly()); diff --git a/hub/modules/config/configurations.bal b/hub/modules/config/configurations.bal index 7349725..509d7af 100644 --- a/hub/modules/config/configurations.bal +++ b/hub/modules/config/configurations.bal @@ -104,5 +104,16 @@ public configurable string CONSOLIDATOR_BASE_URL = "http://websub-consolidator"; # consolidator health endpoint public configurable string CONSOLIDATOR_HEALTH_ENDPOINT = "/consolidator/actuator/health"; -# Key for encryption and decryption of the hubsecret -public configurable string HUB_SECRET_ENCRYPTION_KEY = "g8caskkhrpvrp05l"; \ No newline at end of file +# Key for encryption and decryption of the hubsecret +public configurable string HUB_SECRET_ENCRYPTION_KEY = "g8caskkhrpvrp05l"; + +# Below config will allow base64-encoded-bytes / alpha-numeric. +# Recommended to use base64-encoded-bytes since alpha-numeric is considered less secure. +# This is just given to ensure the backward compatiblity +public configurable string HUB_SECRET_ENCRYPTION_KEY_FORMAT = "base64-encoded-bytes"; + +# Prefix to the encrypted hubsecret for backward compatibility +public configurable string ENCRYPTED_SECRET_PREFIX = "cipher{"; + +# Suffix to the encrypted hubsecret for backward compatibility +public configurable string ENCRYPTED_SECRET_SUFFIX = "}"; \ No newline at end of file diff --git a/hub/start_hub.bal b/hub/start_hub.bal index 9dc4b39..5ba660f 100644 --- a/hub/start_hub.bal +++ b/hub/start_hub.bal @@ -47,6 +47,10 @@ public function main() returns error? { _ = @strand {thread: "any"} start syncRegsisteredTopicsCache(); _ = @strand {thread: "any"} start syncSubscribersCache(); + boolean|error validConfigs = validateConfigs(); + if validConfigs is error { + return validConfigs; + } // Start the Hub http:Listener httpListener = check new (config:HUB_PORT); check httpListener.attach(healthCheckService, "hub/actuator/health"); @@ -55,6 +59,18 @@ public function main() returns error? { check hubListener.'start(); } +function validateConfigs() returns boolean|error { + if (config:HUB_SECRET_ENCRYPTION_KEY_FORMAT.equalsIgnoreCaseAscii("base64-encoded-bytes")){ + byte[] decodedEncryptionKey = check array:fromBase64(config:HUB_SECRET_ENCRYPTION_KEY); + log:printInfo("Length of decoded encryption key", keyLength = decodedEncryptionKey.length()); + if (decodedEncryptionKey.length() == 32) { + return true; + } + return error("Found error in decoding the encryption key. Please set valid base64 encoded bytes as encryption key to proceed."); + } + return true; +} + function syncRegsisteredTopicsCache() { do { while true { @@ -179,18 +195,17 @@ function startMissingSubscribers(websubhub:VerifiedSubscription[] persistedSubsc string consumerGroup = check value:ensureType(subscriber["consumerGroup"]); kafka:Consumer consumerEp = check conn:createMessageConsumer(topicName, consumerGroup); - if (subscriber.hubSecret is string) { - string hubSecret = subscriber.hubSecret; + if (subscriber.hubSecret is string && (subscriber.hubSecret).startsWith(config:ENCRYPTED_SECRET_PREFIX) && (subscriber.hubSecret).endsWith(config:ENCRYPTED_SECRET_SUFFIX)) { + string hubSecretWithPattern = subscriber.hubSecret; + string hubSecret = hubSecretWithPattern.substring((config:ENCRYPTED_SECRET_PREFIX).length(), hubSecretWithPattern.length() - (config:ENCRYPTED_SECRET_SUFFIX).length()); byte[] ivAppendedCipherText = check array:fromBase64(hubSecret); int cipherLength = ivAppendedCipherText.length(); byte[] cipher = ivAppendedCipherText.slice(0, cipherLength-16); byte[] iv = ivAppendedCipherText.slice(cipherLength-16, cipherLength); - log:printInfo("Extracted iv before decryption", iv = iv); string encryptionKey = config:HUB_SECRET_ENCRYPTION_KEY; - log:printInfo("Key used for decryption", key = encryptionKey); byte[] plainText = check crypto:decryptAesGcm(cipher, encryptionKey.toBytes(), iv); subscriber.hubSecret = check string:fromBytes(plainText); - log:printInfo("secret after decryption", secret = subscriber.hubSecret); + log:printInfo("Decrypted the hubSecret", topic = subscriber.hubTopic); } websubhub:HubClient hubClientEp = check new (subscriber, {