{"id":24,"date":"2025-10-15T11:45:25","date_gmt":"2025-10-15T11:45:25","guid":{"rendered":"https:\/\/ciphermq.com\/docs\/?page_id=24"},"modified":"2025-10-15T12:20:41","modified_gmt":"2025-10-15T12:20:41","slug":"ciphermq-full-key-exchange-process","status":"publish","type":"page","link":"https:\/\/ciphermq.com\/docs\/index.php\/ciphermq-full-key-exchange-process\/","title":{"rendered":"CipherMQ Full Key Exchange Process"},"content":{"rendered":"\n\n\n<!DOCTYPE html>\n<html lang=\"en\" dir=\"ltr\">\n<head>\n    <meta charset=\"UTF-8\">\n    <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\">\n    <title>CipherMQ Full Key Exchange Animation<\/title>\n    <script src=\"https:\/\/cdn.tailwindcss.com\"><\/script>\n    <style>\n        @import url('https:\/\/fonts.googleapis.com\/css2?family=Inter:wght@400;500;600;700&display=swap');\n        body {\n            font-family: 'Inter', sans-serif;\n            background-color: #f8f9fa;\n            direction: ltr;\n            #display: flex;\n            justify-content: center;\n            align-items: center;\n            min-height: 100vh;\n            padding: 1rem;\n            box-sizing: border-box;\n        }\n        .container {\n            width: 100%;\n            max-width: 900px; \/* Reduced from 1200px *\/\n            display: flex;\n            flex-direction: column;\n            align-items: center;\n        }\n        .graph-container {\n            position: relative;\n            width: 100%;\n            min-height: 400px; \/* Reduced from 600px *\/\n            background: linear-gradient(135deg, #ffffff 0%, #f1f3f5 100%);\n            border-radius: 1.5rem;\n            box-shadow: 0 20px 40px -10px rgba(0, 0, 0, 0.2);\n            padding: 1.5rem; \/* Reduced from 3rem *\/\n            display: grid;\n            grid-template-columns: repeat(3, 1fr);\n            grid-template-rows: auto auto auto;\n            gap: 2rem; \/* Reduced from 4rem *\/\n            align-items: center;\n            justify-items: center;\n        }\n        .node.sender { grid-area: 1 \/ 1 \/ 2 \/ 2; }\n        .node.server-controller { grid-area: 1 \/ 2 \/ 2 \/ 3; }\n        .node.receiver { grid-area: 1 \/ 3 \/ 2 \/ 4; }\n        .node.key-manager { grid-area: 2 \/ 2 \/ 3 \/ 3; }\n        .node.database { grid-area: 3 \/ 2 \/ 4 \/ 3; }\n        @media (max-width: 767px) {\n            .graph-container {\n                gap: 1rem; \/* Reduced from 2rem *\/\n                padding: 1rem; \/* Reduced from 1.5rem *\/\n                min-height: 300px; \/* Reduced from 450px *\/\n            }\n            .node {\n                max-width: 90px; \/* Reduced from 110px *\/\n                height: 60px; \/* Reduced from 80px *\/\n                padding: 0.5rem;\n                border-radius: 1rem;\n            }\n            .node-icon {\n                width: 24px; \/* Reduced from 30px *\/\n                height: 24px;\n                margin-bottom: 0.2rem;\n            }\n            .node span {\n                font-size: 2vw; \/* Reduced from 2.5vw *\/\n                line-height: 1;\n            }\n            .node-label {\n                font-size: 1.5vw; \/* Reduced from 2vw *\/\n                margin-top: 0.2rem;\n            }\n            h1 {\n                font-size: 4vw; \/* Reduced from 5vw *\/\n                margin-bottom: 1rem; \/* Added to reduce space *\/\n            }\n            .action-button {\n                padding: 0.5rem 1rem; \/* Reduced from 0.75rem 1.5rem *\/\n                font-size: 2.5vw; \/* Reduced from 3.5vw *\/\n                border-radius: 0.75rem;\n            }\n            .status-log {\n                margin-top: 1rem; \/* Reduced from 1.5rem *\/\n                padding: 0.75rem; \/* Reduced from 1rem *\/\n                font-size: 2.5vw; \/* Reduced from 3vw *\/\n                border-radius: 0.75rem;\n            }\n            .status-log h3 {\n                font-size: 3vw; \/* Reduced from 4vw *\/\n            }\n            .animated-object {\n                font-size: 2vw; \/* Reduced from 2.5vw *\/\n                padding: 0.3rem 0.8rem; \/* Reduced from 0.5rem 1rem *\/\n            }\n        }\n        .node {\n            display: flex;\n            flex-direction: column;\n            justify-content: center;\n            align-items: center;\n            text-align: center;\n            font-weight: 600;\n            color: #1f2937;\n            background-color: #e5e7eb;\n            border-radius: 1.5rem;\n            padding: 1rem 0.5rem; \/* Reduced from 1.5rem 1rem *\/\n            box-shadow: 0 5px 10px -3px rgba(0,0,0,0.1);\n            transition: transform 0.3s cubic-bezier(0.2, 0.8, 0.2, 1), box-shadow 0.3s ease-in-out;\n            cursor: default;\n            width: 100%;\n            max-width: 140px; \/* Reduced from 180px *\/\n            height: 90px; \/* Reduced from 120px *\/\n        }\n        .node:hover {\n            transform: translateY(-5px);\n            box-shadow: 0 15px 30px -8px rgba(0,0,0,0.2);\n        }\n        .node-label {\n            font-size: 0.75rem; \/* Reduced from 0.875rem *\/\n            font-weight: 500;\n            color: #6c757d;\n            margin-top: 0.3rem;\n        }\n        .node-icon {\n            width: 32px; \/* Reduced from 40px *\/\n            height: 32px;\n            color: #3b82f6;\n            margin-bottom: 0.5rem;\n        }\n        .node.sender, .node.receiver { background: #e9f5ed; border: 2px solid #7bc59c; } \/* Reduced border thickness *\/\n        .node.server-controller, .node.key-manager { background: #e8f3fb; border: 2px solid #6cb7f3; }\n        .node.database { background: #f6eaf3; border: 2px solid #d381b1; }\n        .animated-object {\n            position: absolute;\n            background: linear-gradient(45deg, #1e3a8a, #3b82f6);\n            color: white;\n            padding: 0.5rem 1rem; \/* Reduced from 0.75rem 1.5rem *\/\n            border-radius: 9999px;\n            font-size: 0.85rem; \/* Reduced from 0.95rem *\/\n            font-weight: 600;\n            opacity: 0;\n            z-index: 20;\n            box-shadow: 0 4px 8px rgba(0,0,0,0.2);\n            transition: transform 0.5s ease-in-out, opacity 0.5s;\n        }\n        .action-button {\n            background: linear-gradient(135deg, #3b82f6, #1e40af);\n            color: white;\n            padding: 0.75rem 2rem; \/* Reduced from 1rem 2.5rem *\/\n            border-radius: 1rem;\n            cursor: pointer;\n            transition: transform 0.3s, box-shadow 0.3s;\n            box-shadow: 0 5px 10px -3px rgba(0,0,0,0.1);\n            font-weight: 700;\n            font-size: 1rem; \/* Reduced from 1.125rem *\/\n            border: none;\n            outline: none;\n            text-shadow: 0 1px 2px rgba(0,0,0,0.2);\n        }\n        .action-button:hover {\n            transform: translateY(-3px);\n            box-shadow: 0 15px 30px -8px rgba(0,0,0,0.2);\n        }\n        .action-button:active {\n            transform: translateY(0);\n            box-shadow: 0 3px 6px -2px rgba(0,0,0,0.2);\n        }\n        .action-button:disabled {\n            background: linear-gradient(135deg, #9ca3af, #6b7280);\n            cursor: not-allowed;\n        }\n        .status-log {\n            width: 100%;\n            max-width: 600px; \/* Reduced from 800px *\/\n            background-color: #e2e8f0;\n            border-radius: 1rem;\n            padding: 1rem; \/* Reduced from 1.5rem *\/\n            margin-top: 2rem; \/* Reduced from 3rem *\/\n            font-size: 0.875rem; \/* Reduced from 1rem *\/\n            color: #374151;\n            box-shadow: inset 0 2px 4px rgba(0,0,0,0.1);\n        }\n        .status-log h3 {\n            font-weight: 600;\n            font-size: 1rem; \/* Reduced from 1.25rem *\/\n            margin-bottom: 0.5rem;\n            color: #1f2937;\n        }\n        .status-log p {\n            line-height: 1.4;\n            margin-bottom: 0.5rem;\n            opacity: 0.7;\n        }\n    <\/style>\n<\/head>\n<body>\n\n    <div class=\"container\">\n  \n        <div class=\"graph-container\" id=\"graph-container\">\n            <!-- Icons from lucide-react, rendered as SVG for this example -->\n            <div id=\"sender\" class=\"node sender\">\n                <svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"40\" height=\"40\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" class=\"lucide lucide-upload node-icon\"><path d=\"M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4\"\/><polyline points=\"17 8 12 3 7 8\"\/><line x1=\"12\" x2=\"12\" y1=\"3\" y2=\"15\"\/><\/svg>\n                <span>Sender<\/span>\n            <\/div>\n            <div id=\"server-controller\" class=\"node server-controller\">\n                <svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"40\" height=\"40\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" class=\"lucide lucide-server node-icon\"><rect x=\"2\" y=\"2\" width=\"20\" height=\"8\" rx=\"2\" ry=\"2\"\/><rect x=\"2\" y=\"14\" width=\"20\" height=\"8\" rx=\"2\" ry=\"2\"\/><line x1=\"6\" x2=\"6\" y1=\"6\" y2=\"6\"\/><line x1=\"6\" x2=\"6\" y1=\"18\" y2=\"18\"\/><\/svg>\n                <span>Server Controller<\/span>\n            <\/div>\n            <div id=\"receiver\" class=\"node receiver\">\n                <svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"40\" height=\"40\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" class=\"lucide lucide-download node-icon\"><path d=\"M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4\"\/><polyline points=\"7 10 12 15 17 10\"\/><line x1=\"12\" x2=\"12\" y1=\"15\" y2=\"3\"\/><\/svg>\n                <span>Receiver<\/span>\n            <\/div>\n            <div id=\"key-manager\" class=\"node key-manager\">\n                <svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"40\" height=\"40\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" class=\"lucide lucide-key-round node-icon\"><path d=\"M2 18v3l1-1c1.5-1.4 4-1.8 7-1.8h.7l5.6-5.6c.3-.3.4-.7.4-1.1v-.2c0-1-.8-1.8-1.8-1.8h-.7c-2.4 0-4.6-.9-6.2-2.5L2 18Z\"\/><path d=\"M15 9h.1\"\/><\/svg>\n                <span>Key Manager<\/span>\n            <\/div>\n            <div id=\"database\" class=\"node database\">\n                <svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"40\" height=\"40\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" class=\"lucide lucide-database node-icon\"><ellipse cx=\"12\" cy=\"5\" rx=\"9\" ry=\"3\"\/><path d=\"M3 5v14a9 3 0 0 0 18 0V5\"\/><path d=\"M3 12h18\"\/><path d=\"M3 12a9 3 0 0 0 18 0\"\/><\/svg>\n                <span>Database<\/span>\n            <\/div>\n        <\/div>\n        \n        <button id=\"start-animation\" class=\"action-button mt-16\">Start Animation<\/button>\n\n        <div class=\"status-log\" id=\"status-log\">\n            <h3>Animation Status<\/h3>\n            <p>Click &#8220;Start Animation&#8221; to see the full key exchange process in action.<\/p>\n        <\/div>\n    <\/div>\n\n    <script>\n        const startButton = document.getElementById('start-animation');\n        const senderNode = document.getElementById('sender');\n        const receiverNode = document.getElementById('receiver');\n        const serverControllerNode = document.getElementById('server-controller');\n        const keyManagerNode = document.getElementById('key-manager');\n        const databaseNode = document.getElementById('database');\n        const graphContainer = document.getElementById('graph-container');\n        const statusLog = document.getElementById('status-log');\n\n        \/**\n         * Clears the status log and adds a new message.\n         * @param {string} message - The message to display.\n         *\/\n        function updateStatus(message) {\n            statusLog.innerHTML = `<h3>Animation Status<\/h3><p>${message}<\/p>`;\n        }\n\n        \/**\n         * Animates an object from a start node to an end node.\n         * @param {HTMLElement} startNode - The starting HTML element.\n         * @param {HTMLElement} endNode - The destination HTML element.\n         * @param {string} text - The text to display on the animated object.\n         * @param {number} duration - The duration of the animation in milliseconds.\n         * @param {number} delay - The delay before the animation starts in milliseconds.\n         * @param {function} callback - A function to call when the animation completes.\n         * @param {string} backgroundColor - Optional background color for the animated object.\n         *\/\n        function animateObject(startNode, endNode, text, duration, delay = 0, callback = null, backgroundColor = null) {\n            const animatedObject = document.createElement('div');\n            animatedObject.textContent = text;\n            animatedObject.className = 'animated-object';\n            if (backgroundColor) {\n                animatedObject.style.background = backgroundColor;\n            }\n            graphContainer.appendChild(animatedObject);\n\n            const startRect = startNode.getBoundingClientRect();\n            const endRect = endNode.getBoundingClientRect();\n            const graphRect = graphContainer.getBoundingClientRect();\n\n            \/\/ Calculate positions relative to the graph container\n            const startX = startRect.left - graphRect.left + startRect.width \/ 2;\n            const startY = startRect.top - graphRect.top + startRect.height \/ 2;\n            const endX = endRect.left - graphRect.left + endRect.width \/ 2;\n            const endY = endRect.top - graphRect.top + endRect.height \/ 2;\n\n            animatedObject.style.top = `${startY}px`;\n            animatedObject.style.left = `${startX}px`;\n            animatedObject.style.transform = `translate(-50%, -50%)`;\n\n            setTimeout(() => {\n                animatedObject.style.transition = `all ${duration}ms cubic-bezier(0.65, 0.05, 0.36, 1)`;\n                animatedObject.style.opacity = 1;\n                animatedObject.style.top = `${endY}px`;\n                animatedObject.style.left = `${endX}px`;\n\n                setTimeout(() => {\n                    animatedObject.style.opacity = 0;\n                    setTimeout(() => {\n                        animatedObject.remove();\n                        if (callback) callback();\n                    }, 500); \/\/ Wait for the fade-out transition\n                }, duration);\n            }, delay);\n        }\n\n        \/**\n         * Runs the full key exchange animation sequence.\n         *\/\n        function runFullAnimation() {\n            let currentDelay = 0;\n            const stepDuration = 2000;\n            const stepInterval = 1000;\n            const shortDuration = 1000;\n\n            \/\/ --- Part 1: Receiver mTLS Handshake & Key Registration ---\n            updateStatus('Starting the key exchange process. The **Receiver** initiates a TLS handshake with the **Server Controller**.');\n            animateObject(receiverNode, serverControllerNode, 'Client Hello + Cert', stepDuration, currentDelay, () => {\n                updateStatus('The **Server Controller** responds with its certificate to the **Receiver**.');\n                animateObject(serverControllerNode, receiverNode, 'Server Hello + Cert', stepDuration, stepInterval, () => {\n                    updateStatus('The **Receiver** and **Server Controller** authenticate each other.');\n                    animateObject(receiverNode, receiverNode, 'Server Auth', shortDuration, stepInterval, () => {\n                        animateObject(serverControllerNode, serverControllerNode, 'Receiver Auth', shortDuration, 0, () => {\n                            updateStatus('The **Receiver** sends its public key to the **Server Controller**.');\n                            animateObject(receiverNode, serverControllerNode, 'Receiver Public Key', stepDuration, stepInterval, () => {\n                                updateStatus('The **Server Controller** forwards the public key to the **Key Manager** for encryption.');\n                                animateObject(serverControllerNode, keyManagerNode, 'Forward Public Key', stepDuration, stepInterval, () => {\n                                    updateStatus('The **Key Manager** encrypts the public key for secure storage.');\n                                    animateObject(keyManagerNode, keyManagerNode, 'Encrypt Key', shortDuration, stepInterval, () => {\n                                        updateStatus('The encrypted key is securely stored in the **Database**.');\n                                        animateObject(keyManagerNode, databaseNode, 'Store Encrypted Key', stepDuration, stepInterval, () => {\n                                            \/\/ --- Part 2: Sender mTLS Handshake & Key Retrieval ---\n                                            let senderDelay = stepInterval * 3;\n                                            updateStatus('The **Sender** begins its TLS handshake with the **Server Controller**.');\n                                            animateObject(senderNode, serverControllerNode, 'Client Hello + Cert', stepDuration, senderDelay, () => {\n                                                updateStatus('The **Server Controller** sends its certificate to the **Sender**.');\n                                                animateObject(serverControllerNode, senderNode, 'Server Hello + Cert', stepDuration, stepInterval, () => {\n                                                    updateStatus('The **Sender** and **Server Controller** authenticate each other.');\n                                                    animateObject(senderNode, senderNode, 'Server Auth', shortDuration, stepInterval, () => {\n                                                        animateObject(serverControllerNode, serverControllerNode, 'Sender Auth', shortDuration, 0, () => {\n                                                            updateStatus('The **Sender** requests the **Receiver\\'s** public key from the **Server Controller**.');\n                                                            animateObject(senderNode, serverControllerNode, 'Request Public Key', stepDuration, stepInterval, () => {\n                                                                updateStatus('The **Server Controller** asks the **Key Manager** for the key.');\n                                                                animateObject(serverControllerNode, keyManagerNode, 'Request Key', stepDuration, stepInterval, () => {\n                                                                    updateStatus('The **Key Manager** retrieves the encrypted key from the **Database**.');\n                                                                    animateObject(keyManagerNode, databaseNode, 'Request from DB', stepDuration, stepInterval, () => {\n                                                                        animateObject(databaseNode, keyManagerNode, 'Encrypted Key from DB', stepDuration, stepInterval, () => {\n                                                                            updateStatus('The **Key Manager** decrypts the key.');\n                                                                            animateObject(keyManagerNode, keyManagerNode, 'Decrypt Key', shortDuration, stepInterval, () => {\n                                                                                updateStatus('The decrypted public key is sent back to the **Server Controller**.');\n                                                                                animateObject(keyManagerNode, serverControllerNode, 'Forward Decrypted Key', stepDuration, stepInterval, () => {\n                                                                                    updateStatus('The decrypted public key is sent to the **Sender**.');\n                                                                                    animateObject(serverControllerNode, senderNode, 'Decrypted Key', stepDuration, stepInterval, () => {\n                                                                                        updateStatus('The **Sender** now has the **Receiver** public key, and the exchange is complete.');\n                                                                                        animateObject(senderNode, senderNode, 'Store Key', shortDuration, stepInterval, () => {\n                                                                                            updateStatus('Animation complete. Click \"Restart Animation\" to run it again.');\n                                                                                        });\n                                                                                    });\n                                                                                }, 'linear-gradient(45deg, #f59e0b, #d97706)');\n                                                                            });\n                                                                        });\n                                                                    });\n                                                                });\n                                                            });\n                                                        });\n                                                    });\n                                                });\n                                            });\n                                        }, 'linear-gradient(45deg, #10b981, #059669)');\n                                    }); \n                                });\n                            });\n                        });\n                    });\n                });\n            }, 'linear-gradient(45deg, #10b981, #059669)');\n        }\n\n        startButton.addEventListener('click', () => {\n            startButton.disabled = true;\n            startButton.textContent = 'Running...';\n            \n            runFullAnimation();\n\n            \/\/ Total duration of the animation sequence.\n            const totalDuration = 72000;\n            setTimeout(() => {\n                startButton.disabled = false;\n                startButton.textContent = 'Restart Animation';\n            }, totalDuration);\n        });\n\n    <\/script>\n<\/body>\n<\/html>\n\n\n\n\n<p><\/p>\n","protected":false},"excerpt":{"rendered":"<p>CipherMQ Full Key Exchange Animation Sender Server Controller Receiver Key Manager Database Start Animation Animation Status Click &#8220;Start Animation&#8221; to see the full key exchange process in action.<\/p>\n","protected":false},"author":1,"featured_media":0,"parent":0,"menu_order":0,"comment_status":"closed","ping_status":"closed","template":"","meta":{"footnotes":""},"class_list":["post-24","page","type-page","status-publish","hentry"],"_links":{"self":[{"href":"https:\/\/ciphermq.com\/docs\/index.php\/wp-json\/wp\/v2\/pages\/24","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/ciphermq.com\/docs\/index.php\/wp-json\/wp\/v2\/pages"}],"about":[{"href":"https:\/\/ciphermq.com\/docs\/index.php\/wp-json\/wp\/v2\/types\/page"}],"author":[{"embeddable":true,"href":"https:\/\/ciphermq.com\/docs\/index.php\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/ciphermq.com\/docs\/index.php\/wp-json\/wp\/v2\/comments?post=24"}],"version-history":[{"count":40,"href":"https:\/\/ciphermq.com\/docs\/index.php\/wp-json\/wp\/v2\/pages\/24\/revisions"}],"predecessor-version":[{"id":70,"href":"https:\/\/ciphermq.com\/docs\/index.php\/wp-json\/wp\/v2\/pages\/24\/revisions\/70"}],"wp:attachment":[{"href":"https:\/\/ciphermq.com\/docs\/index.php\/wp-json\/wp\/v2\/media?parent=24"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}