{"id":25601,"date":"2026-01-27T22:19:06","date_gmt":"2026-01-28T06:19:06","guid":{"rendered":"https:\/\/portasftpserver.com\/?p=25601"},"modified":"2026-01-28T09:28:32","modified_gmt":"2026-01-28T17:28:32","slug":"apache-mina-sshd-data-at-rest-encryption-dare-sftp-server-implementation","status":"publish","type":"post","link":"https:\/\/portasftpserver.com\/apache-mina-sshd-data-at-rest-encryption-dare-sftp-server-implementation\/","title":{"rendered":"Apache Mina SSHD Data at Rest Encryption (DARE) SFTP Server Implementation"},"content":{"rendered":"\n<h2 class=\"sera-block-heading\">DARE w\/ Apache Mina SSHD<\/h2>\n\n\n\n<p class=\"sera-block-paragraph\">This code demonstrates Data at Rest Encryption concepts with Apache MINA SSHD and Google Tink. Before using in production (on your own discretion):<\/p>\n\n\n\n<ul class=\"sera-block-list\">\n<li><strong>Replace hardcoded master key<\/strong> with proper KMS integration<\/li>\n\n\n\n<li><strong>Implement production-grade user authentication<\/strong> (database, LDAP, or SSO)<\/li>\n\n\n\n<li><strong>Add comprehensive audit logging<\/strong> for compliance requirements<\/li>\n\n\n\n<li><strong>Conduct security audit and penetration testing<\/strong><\/li>\n\n\n\n<li><strong>Review and implement all items in the Security Considerations section<\/strong><\/li>\n<\/ul>\n\n\n\n<h2 class=\"sera-block-heading\">IMPORTANT NOTICE<\/h2>\n\n\n\n<p class=\"sera-block-paragraph\"><strong>This implementation is intended for educational, development, and testing purposes only.<\/strong><\/p>\n\n\n\n<p class=\"sera-block-paragraph\"><strong>Repository<\/strong>: <a href=\"https:\/\/github.com\/PortaSFTPServer\/MinaSSHDDataAtRestEncryptionSample\">https:\/\/github.com\/PortaSFTPServer\/MinaSSHDDataAtRestEncryptionSample<\/a><\/p>\n\n\n\n<hr class=\"sera-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h2 class=\"sera-block-heading\">Overview<\/h2>\n\n\n\n<p class=\"sera-block-paragraph\">SFTP server with transparent Data at Rest Encryption (DARE) using Apache MINA SSHD 2.17.1 and Google Tink 1.20.0. All files stored on disk are encrypted with AES-256-GCM, ensuring zero plaintext exposure at rest while maintaining full SFTP protocol compatibility.<\/p>\n\n\n\n<h3 class=\"sera-block-heading\">Key Features<\/h3>\n\n\n\n<ul class=\"sera-block-list\">\n<li><strong>Transparent Encryption<\/strong>: Files automatically encrypted on write and decrypted on read<\/li>\n\n\n\n<li><strong>Chunk-Based Processing<\/strong>: Large files processed in configurable chunks (default 64KB)<\/li>\n\n\n\n<li><strong>Streaming Architecture<\/strong>: No need to load entire files into memory<\/li>\n\n\n\n<li><strong>Random Access Support<\/strong>: Efficient seeking within encrypted files for downloads<\/li>\n\n\n\n<li><strong>Per-Chunk Authentication<\/strong>: Each chunk independently authenticated with AES-256-GCM<\/li>\n\n\n\n<li><strong>Configurable Storage Modes<\/strong>: Support for transparent or .enc extension-based storage<\/li>\n\n\n\n<li><strong>Production Security<\/strong>: PBKDF2-HMAC-SHA256 for user authentication, encrypted keyset storage<\/li>\n<\/ul>\n\n\n\n<p class=\"sera-block-paragraph\"><\/p>\n\n\n\n<h2 class=\"sera-block-heading\">Architecture<\/h2>\n\n\n\n<h3 class=\"sera-block-heading\">Component Diagram<\/h3>\n\n\n\n<div class=\"sera-block-kevinbatdorf-code-block-pro cbp-has-line-numbers\" data-code-block-pro-font-family=\"Code-Pro-JetBrains-Mono\" style=\"font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;--cbp-line-number-color:#abb2bf;--cbp-line-number-width:calc(2 * 0.6 * .875rem);line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)\"><span role=\"button\" tabindex=\"0\" style=\"color:#abb2bf;display:none\" aria-label=\"Copy\" class=\"code-block-pro-copy-button\"><pre class=\"code-block-pro-copy-button-pre\" aria-hidden=\"true\"><textarea class=\"code-block-pro-copy-button-textarea\" tabindex=\"-1\" aria-hidden=\"true\" readonly>\u250c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2510\n\u2502                        SFTP Client                              \u2502\n\u2502              (FileZilla, WinSCP, sftp CLI, etc.)                \u2502\n\u2514\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u252c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2518\n                             \u2502\n                             \u2502 SFTP Protocol (SSH File Transfer)\n                             \u2502\n\u250c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u25bc\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2510\n\u2502              Apache MINA SSHD Server (2.17.1)                   \u2502\n\u251c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2524\n\u2502  - SSH Protocol Handling &amp; Session Management                   \u2502\n\u2502  - SFTP Subsystem (File Operations)                             \u2502\n\u2502  - User Authentication (Password-based)                         \u2502\n\u2502  - Virtual File System (Per-user home directories)              \u2502\n\u2514\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u252c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2518\n                             \u2502\n                             \u2502 File I\/O Operations\n                             \u2502\n\u250c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u25bc\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2510\n\u2502          ChunkedEncryptedSftpAccessor                           \u2502\n\u251c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2524\n\u2502  - Intercepts all file open operations                          \u2502\n\u2502  - Routes to appropriate channel (read\/write)                   \u2502\n\u2502  - Manages logical vs physical file path mapping                \u2502\n\u2502  - Handles .enc extension mode if enabled                       \u2502\n\u2514\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u252c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2518\n                             \u2502\n                \u250c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2534\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2510\n                \u2502                         \u2502\n                \u25bc                         \u25bc\n\u250c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2510   \u250c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2510\n\u2502  ChunkedReadChannel   \u2502   \u2502  ChunkedWriteChannel   \u2502\n\u251c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2524   \u251c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2524\n\u2502 - Random access reads \u2502   \u2502 - Sequential writes    \u2502\n\u2502 - Chunk caching       \u2502   \u2502 - Write buffering      \u2502\n\u2502 - Seek support        \u2502   \u2502 - Auto-flush on chunk  \u2502\n\u2502 - On-demand decrypt   \u2502   \u2502 - Header management    \u2502\n\u2514\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u252c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2518   \u2514\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u252c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2518\n           \u2502                           \u2502\n           \u2514\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u252c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2518\n                      \u2502\n                      \u25bc\n\u250c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2510\n\u2502           ChunkedEncryptionService (Google Tink)                \u2502\n\u251c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2524\n\u2502  - AES-256-GCM encryption\/decryption                            \u2502\n\u2502  - Per-chunk authentication with associated data                \u2502\n\u2502  - File header creation and parsing                             \u2502\n\u2502  - Keyset management (encrypted with master key)                \u2502\n\u2502  - Random access chunk retrieval by index                       \u2502\n\u2514\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u252c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2518\n                             \u2502\n                             \u25bc\n\u250c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2510\n\u2502                    Encrypted File Storage                       \u2502\n\u251c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2524\n\u2502  Structure: &#91;HEADER&#93;&#91;CHUNK_0_SIZE&#93;&#91;CHUNK_0&#93;...                  \u2502\n\u2502  Location:  .\/sftp-storage\/&lt;username>\/                          \u2502\n\u2502  Format:    All data encrypted with AES-256-GCM                 \u2502\n\u2514\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2518\n<\/textarea><\/pre><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" style=\"width:24px;height:24px\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" stroke-width=\"2\"><path class=\"with-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M4.5 12.75l6 6 9-13.5\"><\/path><path class=\"without-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M16.5 8.25V6a2.25 2.25 0 00-2.25-2.25H6A2.25 2.25 0 003.75 6v8.25A2.25 2.25 0 006 16.5h2.25m8.25-8.25H18a2.25 2.25 0 012.25 2.25V18A2.25 2.25 0 0118 20.25h-7.5A2.25 2.25 0 018.25 18v-1.5m8.25-8.25h-6a2.25 2.25 0 00-2.25 2.25v6\"><\/path><\/svg><\/span><pre class=\"shiki one-dark-pro\" style=\"background-color: #282c34\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color: #61AFEF\">\u250c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2510<\/span><\/span>\n<span class=\"line\"><span style=\"color: #61AFEF\">\u2502<\/span><span style=\"color: #ABB2BF\">                        <\/span><span style=\"color: #98C379\">SFTP<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">Client<\/span><span style=\"color: #ABB2BF\">                              <\/span><span style=\"color: #98C379\">\u2502<\/span><\/span>\n<span class=\"line\"><span style=\"color: #61AFEF\">\u2502<\/span><span style=\"color: #ABB2BF\">              (FileZilla, <\/span><span style=\"color: #98C379\">WinSCP,<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">sftp<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">CLI,<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">etc.<\/span><span style=\"color: #ABB2BF\">)                \u2502<\/span><\/span>\n<span class=\"line\"><span style=\"color: #61AFEF\">\u2514\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u252c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2518<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">                             <\/span><span style=\"color: #61AFEF\">\u2502<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">                             <\/span><span style=\"color: #61AFEF\">\u2502<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">SFTP<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">Protocol<\/span><span style=\"color: #ABB2BF\"> (SSH <\/span><span style=\"color: #98C379\">File<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">Transfer<\/span><span style=\"color: #ABB2BF\">)<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">                             <\/span><span style=\"color: #61AFEF\">\u2502<\/span><\/span>\n<span class=\"line\"><span style=\"color: #61AFEF\">\u250c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u25bc\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2510<\/span><\/span>\n<span class=\"line\"><span style=\"color: #61AFEF\">\u2502<\/span><span style=\"color: #ABB2BF\">              <\/span><span style=\"color: #98C379\">Apache<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">MINA<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">SSHD<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">Server<\/span><span style=\"color: #ABB2BF\"> (2.17.1)                   \u2502<\/span><\/span>\n<span class=\"line\"><span style=\"color: #61AFEF\">\u251c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2524<\/span><\/span>\n<span class=\"line\"><span style=\"color: #61AFEF\">\u2502<\/span><span style=\"color: #ABB2BF\">  <\/span><span style=\"color: #98C379\">-<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">SSH<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">Protocol<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">Handling<\/span><span style=\"color: #ABB2BF\"> &amp; <\/span><span style=\"color: #61AFEF\">Session<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">Management<\/span><span style=\"color: #ABB2BF\">                   <\/span><span style=\"color: #98C379\">\u2502<\/span><\/span>\n<span class=\"line\"><span style=\"color: #61AFEF\">\u2502<\/span><span style=\"color: #ABB2BF\">  <\/span><span style=\"color: #98C379\">-<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">SFTP<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">Subsystem<\/span><span style=\"color: #ABB2BF\"> (File <\/span><span style=\"color: #98C379\">Operations<\/span><span style=\"color: #ABB2BF\">)                             \u2502<\/span><\/span>\n<span class=\"line\"><span style=\"color: #61AFEF\">\u2502<\/span><span style=\"color: #ABB2BF\">  <\/span><span style=\"color: #98C379\">-<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">User<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">Authentication<\/span><span style=\"color: #ABB2BF\"> (Password-based)                         \u2502<\/span><\/span>\n<span class=\"line\"><span style=\"color: #61AFEF\">\u2502<\/span><span style=\"color: #ABB2BF\">  <\/span><span style=\"color: #98C379\">-<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">Virtual<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">File<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">System<\/span><span style=\"color: #ABB2BF\"> (Per-user <\/span><span style=\"color: #98C379\">home<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">directories<\/span><span style=\"color: #ABB2BF\">)              \u2502<\/span><\/span>\n<span class=\"line\"><span style=\"color: #61AFEF\">\u2514\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u252c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2518<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">                             <\/span><span style=\"color: #61AFEF\">\u2502<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">                             <\/span><span style=\"color: #61AFEF\">\u2502<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">File<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">I\/O<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">Operations<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">                             <\/span><span style=\"color: #61AFEF\">\u2502<\/span><\/span>\n<span class=\"line\"><span style=\"color: #61AFEF\">\u250c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u25bc\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2510<\/span><\/span>\n<span class=\"line\"><span style=\"color: #61AFEF\">\u2502<\/span><span style=\"color: #ABB2BF\">          <\/span><span style=\"color: #98C379\">ChunkedEncryptedSftpAccessor<\/span><span style=\"color: #ABB2BF\">                           <\/span><span style=\"color: #98C379\">\u2502<\/span><\/span>\n<span class=\"line\"><span style=\"color: #61AFEF\">\u251c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2524<\/span><\/span>\n<span class=\"line\"><span style=\"color: #61AFEF\">\u2502<\/span><span style=\"color: #ABB2BF\">  <\/span><span style=\"color: #98C379\">-<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">Intercepts<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">all<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">file<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">open<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">operations<\/span><span style=\"color: #ABB2BF\">                          <\/span><span style=\"color: #98C379\">\u2502<\/span><\/span>\n<span class=\"line\"><span style=\"color: #61AFEF\">\u2502<\/span><span style=\"color: #ABB2BF\">  <\/span><span style=\"color: #98C379\">-<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">Routes<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">to<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">appropriate<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">channel<\/span><span style=\"color: #ABB2BF\"> (read\/write)                   \u2502<\/span><\/span>\n<span class=\"line\"><span style=\"color: #61AFEF\">\u2502<\/span><span style=\"color: #ABB2BF\">  <\/span><span style=\"color: #98C379\">-<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">Manages<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">logical<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">vs<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">physical<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">file<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">path<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">mapping<\/span><span style=\"color: #ABB2BF\">                <\/span><span style=\"color: #98C379\">\u2502<\/span><\/span>\n<span class=\"line\"><span style=\"color: #61AFEF\">\u2502<\/span><span style=\"color: #ABB2BF\">  <\/span><span style=\"color: #98C379\">-<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">Handles<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">.enc<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">extension<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">mode<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">if<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">enabled<\/span><span style=\"color: #ABB2BF\">                       <\/span><span style=\"color: #98C379\">\u2502<\/span><\/span>\n<span class=\"line\"><span style=\"color: #61AFEF\">\u2514\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u252c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2518<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">                             <\/span><span style=\"color: #61AFEF\">\u2502<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">                <\/span><span style=\"color: #61AFEF\">\u250c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2534\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2510<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">                <\/span><span style=\"color: #61AFEF\">\u2502<\/span><span style=\"color: #ABB2BF\">                         <\/span><span style=\"color: #98C379\">\u2502<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">                <\/span><span style=\"color: #61AFEF\">\u25bc<\/span><span style=\"color: #ABB2BF\">                         <\/span><span style=\"color: #98C379\">\u25bc<\/span><\/span>\n<span class=\"line\"><span style=\"color: #61AFEF\">\u250c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2510<\/span><span style=\"color: #ABB2BF\">   <\/span><span style=\"color: #98C379\">\u250c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2510<\/span><\/span>\n<span class=\"line\"><span style=\"color: #61AFEF\">\u2502<\/span><span style=\"color: #ABB2BF\">  <\/span><span style=\"color: #98C379\">ChunkedReadChannel<\/span><span style=\"color: #ABB2BF\">   <\/span><span style=\"color: #98C379\">\u2502<\/span><span style=\"color: #ABB2BF\">   <\/span><span style=\"color: #98C379\">\u2502<\/span><span style=\"color: #ABB2BF\">  <\/span><span style=\"color: #98C379\">ChunkedWriteChannel<\/span><span style=\"color: #ABB2BF\">   <\/span><span style=\"color: #98C379\">\u2502<\/span><\/span>\n<span class=\"line\"><span style=\"color: #61AFEF\">\u251c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2524<\/span><span style=\"color: #ABB2BF\">   <\/span><span style=\"color: #98C379\">\u251c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2524<\/span><\/span>\n<span class=\"line\"><span style=\"color: #61AFEF\">\u2502<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">-<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">Random<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">access<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">reads<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">\u2502<\/span><span style=\"color: #ABB2BF\">   <\/span><span style=\"color: #98C379\">\u2502<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">-<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">Sequential<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">writes<\/span><span style=\"color: #ABB2BF\">    <\/span><span style=\"color: #98C379\">\u2502<\/span><\/span>\n<span class=\"line\"><span style=\"color: #61AFEF\">\u2502<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">-<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">Chunk<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">caching<\/span><span style=\"color: #ABB2BF\">       <\/span><span style=\"color: #98C379\">\u2502<\/span><span style=\"color: #ABB2BF\">   <\/span><span style=\"color: #98C379\">\u2502<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">-<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">Write<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">buffering<\/span><span style=\"color: #ABB2BF\">      <\/span><span style=\"color: #98C379\">\u2502<\/span><\/span>\n<span class=\"line\"><span style=\"color: #61AFEF\">\u2502<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">-<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">Seek<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">support<\/span><span style=\"color: #ABB2BF\">        <\/span><span style=\"color: #98C379\">\u2502<\/span><span style=\"color: #ABB2BF\">   <\/span><span style=\"color: #98C379\">\u2502<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">-<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">Auto-flush<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">on<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">chunk<\/span><span style=\"color: #ABB2BF\">  <\/span><span style=\"color: #98C379\">\u2502<\/span><\/span>\n<span class=\"line\"><span style=\"color: #61AFEF\">\u2502<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">-<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">On-demand<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">decrypt<\/span><span style=\"color: #ABB2BF\">   <\/span><span style=\"color: #98C379\">\u2502<\/span><span style=\"color: #ABB2BF\">   <\/span><span style=\"color: #98C379\">\u2502<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">-<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">Header<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">management<\/span><span style=\"color: #ABB2BF\">    <\/span><span style=\"color: #98C379\">\u2502<\/span><\/span>\n<span class=\"line\"><span style=\"color: #61AFEF\">\u2514\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u252c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2518<\/span><span style=\"color: #ABB2BF\">   <\/span><span style=\"color: #98C379\">\u2514\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u252c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2518<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">           <\/span><span style=\"color: #61AFEF\">\u2502<\/span><span style=\"color: #ABB2BF\">                           <\/span><span style=\"color: #98C379\">\u2502<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">           <\/span><span style=\"color: #61AFEF\">\u2514\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u252c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2518<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">                      <\/span><span style=\"color: #61AFEF\">\u2502<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">                      <\/span><span style=\"color: #61AFEF\">\u25bc<\/span><\/span>\n<span class=\"line\"><span style=\"color: #61AFEF\">\u250c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2510<\/span><\/span>\n<span class=\"line\"><span style=\"color: #61AFEF\">\u2502<\/span><span style=\"color: #ABB2BF\">           <\/span><span style=\"color: #98C379\">ChunkedEncryptionService<\/span><span style=\"color: #ABB2BF\"> (Google <\/span><span style=\"color: #98C379\">Tink<\/span><span style=\"color: #ABB2BF\">)                \u2502<\/span><\/span>\n<span class=\"line\"><span style=\"color: #61AFEF\">\u251c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2524<\/span><\/span>\n<span class=\"line\"><span style=\"color: #61AFEF\">\u2502<\/span><span style=\"color: #ABB2BF\">  <\/span><span style=\"color: #98C379\">-<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">AES-256-GCM<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">encryption\/decryption<\/span><span style=\"color: #ABB2BF\">                            <\/span><span style=\"color: #98C379\">\u2502<\/span><\/span>\n<span class=\"line\"><span style=\"color: #61AFEF\">\u2502<\/span><span style=\"color: #ABB2BF\">  <\/span><span style=\"color: #98C379\">-<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">Per-chunk<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">authentication<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">with<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">associated<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">data<\/span><span style=\"color: #ABB2BF\">                <\/span><span style=\"color: #98C379\">\u2502<\/span><\/span>\n<span class=\"line\"><span style=\"color: #61AFEF\">\u2502<\/span><span style=\"color: #ABB2BF\">  <\/span><span style=\"color: #98C379\">-<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">File<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">header<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">creation<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">and<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">parsing<\/span><span style=\"color: #ABB2BF\">                             <\/span><span style=\"color: #98C379\">\u2502<\/span><\/span>\n<span class=\"line\"><span style=\"color: #61AFEF\">\u2502<\/span><span style=\"color: #ABB2BF\">  <\/span><span style=\"color: #98C379\">-<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">Keyset<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">management<\/span><span style=\"color: #ABB2BF\"> (encrypted <\/span><span style=\"color: #98C379\">with<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">master<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">key<\/span><span style=\"color: #ABB2BF\">)                \u2502<\/span><\/span>\n<span class=\"line\"><span style=\"color: #61AFEF\">\u2502<\/span><span style=\"color: #ABB2BF\">  <\/span><span style=\"color: #98C379\">-<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">Random<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">access<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">chunk<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">retrieval<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">by<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">index<\/span><span style=\"color: #ABB2BF\">                       <\/span><span style=\"color: #98C379\">\u2502<\/span><\/span>\n<span class=\"line\"><span style=\"color: #61AFEF\">\u2514\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u252c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2518<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">                             <\/span><span style=\"color: #61AFEF\">\u2502<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">                             <\/span><span style=\"color: #61AFEF\">\u25bc<\/span><\/span>\n<span class=\"line\"><span style=\"color: #61AFEF\">\u250c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2510<\/span><\/span>\n<span class=\"line\"><span style=\"color: #61AFEF\">\u2502<\/span><span style=\"color: #ABB2BF\">                    <\/span><span style=\"color: #98C379\">Encrypted<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">File<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">Storage<\/span><span style=\"color: #ABB2BF\">                       <\/span><span style=\"color: #98C379\">\u2502<\/span><\/span>\n<span class=\"line\"><span style=\"color: #61AFEF\">\u251c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2524<\/span><\/span>\n<span class=\"line\"><span style=\"color: #61AFEF\">\u2502<\/span><span style=\"color: #ABB2BF\">  <\/span><span style=\"color: #98C379\">Structure:<\/span><span style=\"color: #ABB2BF\"> &#91;HEADER&#93;&#91;CHUNK_0_SIZE&#93;&#91;CHUNK_0&#93;...                  \u2502<\/span><\/span>\n<span class=\"line\"><span style=\"color: #61AFEF\">\u2502<\/span><span style=\"color: #ABB2BF\">  <\/span><span style=\"color: #98C379\">Location:<\/span><span style=\"color: #ABB2BF\">  <\/span><span style=\"color: #98C379\">.\/sftp-storage\/<\/span><span style=\"color: #ABB2BF\">&lt;<\/span><span style=\"color: #98C379\">usernam<\/span><span style=\"color: #ABB2BF\">e&gt;<\/span><span style=\"color: #98C379\">\/<\/span><span style=\"color: #ABB2BF\">                          <\/span><span style=\"color: #98C379\">\u2502<\/span><\/span>\n<span class=\"line\"><span style=\"color: #61AFEF\">\u2502<\/span><span style=\"color: #ABB2BF\">  <\/span><span style=\"color: #98C379\">Format:<\/span><span style=\"color: #ABB2BF\">    <\/span><span style=\"color: #98C379\">All<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">data<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">encrypted<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">with<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">AES-256-GCM<\/span><span style=\"color: #ABB2BF\">                 <\/span><span style=\"color: #98C379\">\u2502<\/span><\/span>\n<span class=\"line\"><span style=\"color: #61AFEF\">\u2514\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2518<\/span><\/span>\n<span class=\"line\"><\/span><\/code><\/pre><\/div>\n\n\n\n<h2 class=\"sera-block-heading\">Data Flow<\/h2>\n\n\n\n<h3 class=\"sera-block-heading\">Upload (Write) Flow<\/h3>\n\n\n\n<div class=\"sera-block-kevinbatdorf-code-block-pro cbp-has-line-numbers\" data-code-block-pro-font-family=\"Code-Pro-JetBrains-Mono\" style=\"font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;--cbp-line-number-color:#abb2bf;--cbp-line-number-width:calc(2 * 0.6 * .875rem);line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)\"><span role=\"button\" tabindex=\"0\" style=\"color:#abb2bf;display:none\" aria-label=\"Copy\" class=\"code-block-pro-copy-button\"><pre class=\"code-block-pro-copy-button-pre\" aria-hidden=\"true\"><textarea class=\"code-block-pro-copy-button-textarea\" tabindex=\"-1\" aria-hidden=\"true\" readonly>1. Client sends file via SFTP PUT\n2. SSHD routes to ChunkedEncryptedSftpAccessor\n3. Accessor creates ChunkedWriteChannel\n4. Channel buffers incoming plaintext data\n5. When buffer reaches chunk size:\n   a. Encrypt chunk with AES-256-GCM\n   b. Write &#91;chunk_size&#93;&#91;encrypted_data&#93; to disk\n   c. Clear buffer\n6. On close: flush partial chunk, update header\n<\/textarea><\/pre><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" style=\"width:24px;height:24px\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" stroke-width=\"2\"><path class=\"with-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M4.5 12.75l6 6 9-13.5\"><\/path><path class=\"without-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M16.5 8.25V6a2.25 2.25 0 00-2.25-2.25H6A2.25 2.25 0 003.75 6v8.25A2.25 2.25 0 006 16.5h2.25m8.25-8.25H18a2.25 2.25 0 012.25 2.25V18A2.25 2.25 0 0118 20.25h-7.5A2.25 2.25 0 018.25 18v-1.5m8.25-8.25h-6a2.25 2.25 0 00-2.25 2.25v6\"><\/path><\/svg><\/span><pre class=\"shiki one-dark-pro\" style=\"background-color: #282c34\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color: #61AFEF\">1.<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">Client<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">sends<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">file<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">via<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">SFTP<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">PUT<\/span><\/span>\n<span class=\"line\"><span style=\"color: #61AFEF\">2.<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">SSHD<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">routes<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">to<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">ChunkedEncryptedSftpAccessor<\/span><\/span>\n<span class=\"line\"><span style=\"color: #61AFEF\">3.<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">Accessor<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">creates<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">ChunkedWriteChannel<\/span><\/span>\n<span class=\"line\"><span style=\"color: #61AFEF\">4.<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">Channel<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">buffers<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">incoming<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">plaintext<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">data<\/span><\/span>\n<span class=\"line\"><span style=\"color: #61AFEF\">5.<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">When<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">buffer<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">reaches<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">chunk<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">size:<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">   <\/span><span style=\"color: #61AFEF\">a.<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">Encrypt<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">chunk<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">with<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">AES-256-GCM<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">   <\/span><span style=\"color: #61AFEF\">b.<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">Write<\/span><span style=\"color: #ABB2BF\"> &#91;chunk_size&#93;&#91;encrypted_data&#93; to disk<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">   <\/span><span style=\"color: #61AFEF\">c.<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">Clear<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">buffer<\/span><\/span>\n<span class=\"line\"><span style=\"color: #61AFEF\">6.<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">On<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">close:<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">flush<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">partial<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">chunk,<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">update<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">header<\/span><\/span>\n<span class=\"line\"><\/span><\/code><\/pre><\/div>\n\n\n\n<h3 class=\"sera-block-heading\">Download (Read) Flow<\/h3>\n\n\n\n<div class=\"sera-block-kevinbatdorf-code-block-pro cbp-has-line-numbers\" data-code-block-pro-font-family=\"Code-Pro-JetBrains-Mono\" style=\"font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;--cbp-line-number-color:#abb2bf;--cbp-line-number-width:calc(2 * 0.6 * .875rem);line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)\"><span role=\"button\" tabindex=\"0\" style=\"color:#abb2bf;display:none\" aria-label=\"Copy\" class=\"code-block-pro-copy-button\"><pre class=\"code-block-pro-copy-button-pre\" aria-hidden=\"true\"><textarea class=\"code-block-pro-copy-button-textarea\" tabindex=\"-1\" aria-hidden=\"true\" readonly>1. Client sends file via SFTP GET\n2. SSHD routes to ChunkedEncryptedSftpAccessor\n3. Accessor creates ChunkedReadChannel\n4. Channel reads file header for metadata\n5. For each read request:\n   a. Calculate chunk index from position\n   b. If not cached, decrypt chunk from disk\n   c. Copy plaintext data from chunk to client\n   d. Update position\n6. Return -1 on EOF (critical for SSHD compatibility)\n<\/textarea><\/pre><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" style=\"width:24px;height:24px\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" stroke-width=\"2\"><path class=\"with-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M4.5 12.75l6 6 9-13.5\"><\/path><path class=\"without-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M16.5 8.25V6a2.25 2.25 0 00-2.25-2.25H6A2.25 2.25 0 003.75 6v8.25A2.25 2.25 0 006 16.5h2.25m8.25-8.25H18a2.25 2.25 0 012.25 2.25V18A2.25 2.25 0 0118 20.25h-7.5A2.25 2.25 0 018.25 18v-1.5m8.25-8.25h-6a2.25 2.25 0 00-2.25 2.25v6\"><\/path><\/svg><\/span><pre class=\"shiki one-dark-pro\" style=\"background-color: #282c34\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color: #61AFEF\">1.<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">Client<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">sends<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">file<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">via<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">SFTP<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">GET<\/span><\/span>\n<span class=\"line\"><span style=\"color: #61AFEF\">2.<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">SSHD<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">routes<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">to<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">ChunkedEncryptedSftpAccessor<\/span><\/span>\n<span class=\"line\"><span style=\"color: #61AFEF\">3.<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">Accessor<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">creates<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">ChunkedReadChannel<\/span><\/span>\n<span class=\"line\"><span style=\"color: #61AFEF\">4.<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">Channel<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">reads<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">file<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">header<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">for<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">metadata<\/span><\/span>\n<span class=\"line\"><span style=\"color: #61AFEF\">5.<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">For<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">each<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">read<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">request:<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">   <\/span><span style=\"color: #61AFEF\">a.<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">Calculate<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">chunk<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">index<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">from<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">position<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">   <\/span><span style=\"color: #61AFEF\">b.<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">If<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">not<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">cached,<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">decrypt<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">chunk<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">from<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">disk<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">   <\/span><span style=\"color: #61AFEF\">c.<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">Copy<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">plaintext<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">data<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">from<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">chunk<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">to<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">client<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">   <\/span><span style=\"color: #61AFEF\">d.<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">Update<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">position<\/span><\/span>\n<span class=\"line\"><span style=\"color: #61AFEF\">6.<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">Return<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #D19A66\">-1<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">on<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">EOF<\/span><span style=\"color: #ABB2BF\"> (critical <\/span><span style=\"color: #98C379\">for<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">SSHD<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">compatibility<\/span><span style=\"color: #ABB2BF\">)<\/span><\/span>\n<span class=\"line\"><\/span><\/code><\/pre><\/div>\n\n\n\n<hr class=\"sera-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h2 class=\"sera-block-heading\">Technology Stack<\/h2>\n\n\n\n<h3 class=\"sera-block-heading\">Core Dependencies<\/h3>\n\n\n\n<div class=\"sera-block-kevinbatdorf-code-block-pro cbp-has-line-numbers\" data-code-block-pro-font-family=\"Code-Pro-JetBrains-Mono\" style=\"font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;--cbp-line-number-color:#abb2bf;--cbp-line-number-width:calc(2 * 0.6 * .875rem);line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)\"><span role=\"button\" tabindex=\"0\" style=\"color:#abb2bf;display:none\" aria-label=\"Copy\" class=\"code-block-pro-copy-button\"><pre class=\"code-block-pro-copy-button-pre\" aria-hidden=\"true\"><textarea class=\"code-block-pro-copy-button-textarea\" tabindex=\"-1\" aria-hidden=\"true\" readonly>&lt;dependencies>\n    &lt;!-- Apache MINA SSHD -->\n    &lt;dependency>\n        &lt;groupId>org.apache.sshd&lt;\/groupId>\n        &lt;artifactId>sshd-core&lt;\/artifactId>\n        &lt;version>2.17.1&lt;\/version>\n    &lt;\/dependency>\n    \n    &lt;dependency>\n        &lt;groupId>org.apache.sshd&lt;\/groupId>\n        &lt;artifactId>sshd-sftp&lt;\/artifactId>\n        &lt;version>2.17.1&lt;\/version>\n    &lt;\/dependency>\n    \n    &lt;dependency>\n        &lt;groupId>org.apache.sshd&lt;\/groupId>\n        &lt;artifactId>sshd-common&lt;\/artifactId>\n        &lt;version>2.17.1&lt;\/version>\n    &lt;\/dependency>\n    \n    &lt;!-- Google Tink Cryptography -->\n    &lt;dependency>\n        &lt;groupId>com.google.crypto.tink&lt;\/groupId>\n        &lt;artifactId>tink&lt;\/artifactId>\n        &lt;version>1.20.0&lt;\/version>\n    &lt;\/dependency>\n    \n    &lt;!-- Logging -->\n    &lt;dependency>\n        &lt;groupId>org.slf4j&lt;\/groupId>\n        &lt;artifactId>slf4j-api&lt;\/artifactId>\n        &lt;version>2.0.13&lt;\/version>\n    &lt;\/dependency>\n    \n    &lt;dependency>\n        &lt;groupId>ch.qos.logback&lt;\/groupId>\n        &lt;artifactId>logback-classic&lt;\/artifactId>\n        &lt;version>1.5.6&lt;\/version>\n    &lt;\/dependency>\n&lt;\/dependencies>\n<\/textarea><\/pre><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" style=\"width:24px;height:24px\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" stroke-width=\"2\"><path class=\"with-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M4.5 12.75l6 6 9-13.5\"><\/path><path class=\"without-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M16.5 8.25V6a2.25 2.25 0 00-2.25-2.25H6A2.25 2.25 0 003.75 6v8.25A2.25 2.25 0 006 16.5h2.25m8.25-8.25H18a2.25 2.25 0 012.25 2.25V18A2.25 2.25 0 0118 20.25h-7.5A2.25 2.25 0 018.25 18v-1.5m8.25-8.25h-6a2.25 2.25 0 00-2.25 2.25v6\"><\/path><\/svg><\/span><pre class=\"shiki one-dark-pro\" style=\"background-color: #282c34\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color: #ABB2BF\">&lt;dependencies&gt;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">    &lt;!<\/span><span style=\"color: #61AFEF\">--<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">Apache<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">MINA<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">SSHD<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #D19A66\">--<\/span><span style=\"color: #ABB2BF\">&gt;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">    &lt;<\/span><span style=\"color: #61AFEF\">dependency&gt;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">        &lt;<\/span><span style=\"color: #61AFEF\">groupId&gt;org.apache.sshd&lt;\/groupId&gt;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">        &lt;<\/span><span style=\"color: #61AFEF\">artifactId&gt;sshd-core&lt;\/artifactId&gt;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">        &lt;<\/span><span style=\"color: #61AFEF\">version&gt;2.17.1&lt;\/version&gt;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">    &lt;<\/span><span style=\"color: #61AFEF\">\/dependency&gt;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">    <\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">    &lt;<\/span><span style=\"color: #61AFEF\">dependency&gt;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">        &lt;<\/span><span style=\"color: #61AFEF\">groupId&gt;org.apache.sshd&lt;\/groupId&gt;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">        &lt;<\/span><span style=\"color: #61AFEF\">artifactId&gt;sshd-sftp&lt;\/artifactId&gt;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">        &lt;<\/span><span style=\"color: #61AFEF\">version&gt;2.17.1&lt;\/version&gt;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">    &lt;<\/span><span style=\"color: #61AFEF\">\/dependency&gt;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">    <\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">    &lt;<\/span><span style=\"color: #61AFEF\">dependency&gt;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">        &lt;<\/span><span style=\"color: #61AFEF\">groupId&gt;org.apache.sshd&lt;\/groupId&gt;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">        &lt;<\/span><span style=\"color: #61AFEF\">artifactId&gt;sshd-common&lt;\/artifactId&gt;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">        &lt;<\/span><span style=\"color: #61AFEF\">version&gt;2.17.1&lt;\/version&gt;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">    &lt;<\/span><span style=\"color: #61AFEF\">\/dependency&gt;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">    <\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">    &lt;!<\/span><span style=\"color: #61AFEF\">--<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">Google<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">Tink<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">Cryptography<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #D19A66\">--<\/span><span style=\"color: #ABB2BF\">&gt;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">    &lt;<\/span><span style=\"color: #61AFEF\">dependency&gt;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">        &lt;<\/span><span style=\"color: #61AFEF\">groupId&gt;com.google.crypto.tink&lt;\/groupId&gt;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">        &lt;<\/span><span style=\"color: #61AFEF\">artifactId&gt;tink&lt;\/artifactId&gt;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">        &lt;<\/span><span style=\"color: #61AFEF\">version&gt;1.20.0&lt;\/version&gt;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">    &lt;<\/span><span style=\"color: #61AFEF\">\/dependency&gt;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">    <\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">    &lt;!<\/span><span style=\"color: #61AFEF\">--<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">Logging<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #D19A66\">--<\/span><span style=\"color: #ABB2BF\">&gt;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">    &lt;<\/span><span style=\"color: #61AFEF\">dependency&gt;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">        &lt;<\/span><span style=\"color: #61AFEF\">groupId&gt;org.slf4j&lt;\/groupId&gt;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">        &lt;<\/span><span style=\"color: #61AFEF\">artifactId&gt;slf4j-api&lt;\/artifactId&gt;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">        &lt;<\/span><span style=\"color: #61AFEF\">version&gt;2.0.13&lt;\/version&gt;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">    &lt;<\/span><span style=\"color: #61AFEF\">\/dependency&gt;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">    <\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">    &lt;<\/span><span style=\"color: #61AFEF\">dependency&gt;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">        &lt;<\/span><span style=\"color: #61AFEF\">groupId&gt;ch.qos.logback&lt;\/groupId&gt;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">        &lt;<\/span><span style=\"color: #61AFEF\">artifactId&gt;logback-classic&lt;\/artifactId&gt;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">        &lt;<\/span><span style=\"color: #61AFEF\">version&gt;1.5.6&lt;\/version&gt;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">    &lt;<\/span><span style=\"color: #61AFEF\">\/dependency&gt;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">&lt;\/dependencies&gt;<\/span><\/span>\n<span class=\"line\"><\/span><\/code><\/pre><\/div>\n\n\n\n<h3 class=\"sera-block-heading\">Runtime Requirements<\/h3>\n\n\n\n<ul class=\"sera-block-list\">\n<li><strong>Java<\/strong>: 11 or higher (compiled with Java 11 target)<\/li>\n\n\n\n<li><strong>Memory<\/strong>: Minimum 512MB RAM (recommended 1GB+)<\/li>\n\n\n\n<li><strong>Disk<\/strong>: Depends on storage needs (encrypted files ~1-2% larger than plaintext)<\/li>\n\n\n\n<li><strong>Network<\/strong>: Port 2222 (default, configurable)<\/li>\n<\/ul>\n\n\n\n<hr class=\"sera-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h2 class=\"sera-block-heading\">File Format Specification<\/h2>\n\n\n\n<h3 class=\"sera-block-heading\">Encrypted File Structure<\/h3>\n\n\n\n<div class=\"sera-block-kevinbatdorf-code-block-pro cbp-has-line-numbers\" data-code-block-pro-font-family=\"Code-Pro-JetBrains-Mono\" style=\"font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;--cbp-line-number-color:#abb2bf;--cbp-line-number-width:calc(2 * 0.6 * .875rem);line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)\"><span role=\"button\" tabindex=\"0\" style=\"color:#abb2bf;display:none\" aria-label=\"Copy\" class=\"code-block-pro-copy-button\"><pre class=\"code-block-pro-copy-button-pre\" aria-hidden=\"true\"><textarea class=\"code-block-pro-copy-button-textarea\" tabindex=\"-1\" aria-hidden=\"true\" readonly>\u250c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2510\n\u2502                      FILE HEADER (32 bytes)                  \u2502\n\u251c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2524\n\u2502  Offset  \u2502 Size \u2502 Field            \u2502 Description             \u2502\n\u251c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2524\n\u2502  0       \u2502  4   \u2502 Magic            \u2502 \"CENC\" (0x43454E43)     \u2502\n\u2502  4       \u2502  2   \u2502 Version          \u2502 0x0001                  \u2502\n\u2502  6       \u2502  4   \u2502 Chunk Size       \u2502 Default: 65536 bytes    \u2502\n\u2502  10      \u2502  8   \u2502 Original Size    \u2502 Plaintext file size     \u2502\n\u2502  18      \u2502  14  \u2502 Reserved         \u2502 Random padding          \u2502\n\u2514\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2518\n\n\u250c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2510\n\u2502                    CHUNK 0 (Variable Size)                   \u2502\n\u251c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2524\n\u2502  Chunk Size (4 bytes)    \u2502 Encrypted size (plaintext + tag)  \u2502\n\u2502  Encrypted Data (N bytes)\u2502 AES-256-GCM ciphertext            \u2502\n\u2514\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2518\n\n\u250c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2510\n\u2502                    CHUNK 1 (Variable Size)                   \u2502\n\u251c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2524\n\u2502  Chunk Size (4 bytes)    \u2502 Encrypted size                    \u2502\n\u2502  Encrypted Data (M bytes)\u2502 AES-256-GCM ciphertext            \u2502\n\u2514\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2518\n\n... (additional chunks as needed)\n<\/textarea><\/pre><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" style=\"width:24px;height:24px\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" stroke-width=\"2\"><path class=\"with-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M4.5 12.75l6 6 9-13.5\"><\/path><path class=\"without-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M16.5 8.25V6a2.25 2.25 0 00-2.25-2.25H6A2.25 2.25 0 003.75 6v8.25A2.25 2.25 0 006 16.5h2.25m8.25-8.25H18a2.25 2.25 0 012.25 2.25V18A2.25 2.25 0 0118 20.25h-7.5A2.25 2.25 0 018.25 18v-1.5m8.25-8.25h-6a2.25 2.25 0 00-2.25 2.25v6\"><\/path><\/svg><\/span><pre class=\"shiki one-dark-pro\" style=\"background-color: #282c34\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color: #61AFEF\">\u250c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2510<\/span><\/span>\n<span class=\"line\"><span style=\"color: #61AFEF\">\u2502<\/span><span style=\"color: #ABB2BF\">                      <\/span><span style=\"color: #98C379\">FILE<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">HEADER<\/span><span style=\"color: #ABB2BF\"> (32 <\/span><span style=\"color: #98C379\">bytes<\/span><span style=\"color: #ABB2BF\">)                  \u2502<\/span><\/span>\n<span class=\"line\"><span style=\"color: #61AFEF\">\u251c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2524<\/span><\/span>\n<span class=\"line\"><span style=\"color: #61AFEF\">\u2502<\/span><span style=\"color: #ABB2BF\">  <\/span><span style=\"color: #98C379\">Offset<\/span><span style=\"color: #ABB2BF\">  <\/span><span style=\"color: #98C379\">\u2502<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">Size<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">\u2502<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">Field<\/span><span style=\"color: #ABB2BF\">            <\/span><span style=\"color: #98C379\">\u2502<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">Description<\/span><span style=\"color: #ABB2BF\">             <\/span><span style=\"color: #98C379\">\u2502<\/span><\/span>\n<span class=\"line\"><span style=\"color: #61AFEF\">\u251c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2524<\/span><\/span>\n<span class=\"line\"><span style=\"color: #61AFEF\">\u2502<\/span><span style=\"color: #ABB2BF\">  <\/span><span style=\"color: #D19A66\">0<\/span><span style=\"color: #ABB2BF\">       <\/span><span style=\"color: #98C379\">\u2502<\/span><span style=\"color: #ABB2BF\">  <\/span><span style=\"color: #D19A66\">4<\/span><span style=\"color: #ABB2BF\">   <\/span><span style=\"color: #98C379\">\u2502<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">Magic<\/span><span style=\"color: #ABB2BF\">            <\/span><span style=\"color: #98C379\">\u2502<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">&quot;CENC&quot;<\/span><span style=\"color: #ABB2BF\"> (0x43454E43)     \u2502<\/span><\/span>\n<span class=\"line\"><span style=\"color: #61AFEF\">\u2502<\/span><span style=\"color: #ABB2BF\">  <\/span><span style=\"color: #D19A66\">4<\/span><span style=\"color: #ABB2BF\">       <\/span><span style=\"color: #98C379\">\u2502<\/span><span style=\"color: #ABB2BF\">  <\/span><span style=\"color: #D19A66\">2<\/span><span style=\"color: #ABB2BF\">   <\/span><span style=\"color: #98C379\">\u2502<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">Version<\/span><span style=\"color: #ABB2BF\">          <\/span><span style=\"color: #98C379\">\u2502<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #D19A66\">0x0001<\/span><span style=\"color: #ABB2BF\">                  <\/span><span style=\"color: #98C379\">\u2502<\/span><\/span>\n<span class=\"line\"><span style=\"color: #61AFEF\">\u2502<\/span><span style=\"color: #ABB2BF\">  <\/span><span style=\"color: #D19A66\">6<\/span><span style=\"color: #ABB2BF\">       <\/span><span style=\"color: #98C379\">\u2502<\/span><span style=\"color: #ABB2BF\">  <\/span><span style=\"color: #D19A66\">4<\/span><span style=\"color: #ABB2BF\">   <\/span><span style=\"color: #98C379\">\u2502<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">Chunk<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">Size<\/span><span style=\"color: #ABB2BF\">       <\/span><span style=\"color: #98C379\">\u2502<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">Default:<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #D19A66\">65536<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">bytes<\/span><span style=\"color: #ABB2BF\">    <\/span><span style=\"color: #98C379\">\u2502<\/span><\/span>\n<span class=\"line\"><span style=\"color: #61AFEF\">\u2502<\/span><span style=\"color: #ABB2BF\">  <\/span><span style=\"color: #D19A66\">10<\/span><span style=\"color: #ABB2BF\">      <\/span><span style=\"color: #98C379\">\u2502<\/span><span style=\"color: #ABB2BF\">  <\/span><span style=\"color: #D19A66\">8<\/span><span style=\"color: #ABB2BF\">   <\/span><span style=\"color: #98C379\">\u2502<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">Original<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">Size<\/span><span style=\"color: #ABB2BF\">    <\/span><span style=\"color: #98C379\">\u2502<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">Plaintext<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">file<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">size<\/span><span style=\"color: #ABB2BF\">     <\/span><span style=\"color: #98C379\">\u2502<\/span><\/span>\n<span class=\"line\"><span style=\"color: #61AFEF\">\u2502<\/span><span style=\"color: #ABB2BF\">  <\/span><span style=\"color: #D19A66\">18<\/span><span style=\"color: #ABB2BF\">      <\/span><span style=\"color: #98C379\">\u2502<\/span><span style=\"color: #ABB2BF\">  <\/span><span style=\"color: #D19A66\">14<\/span><span style=\"color: #ABB2BF\">  <\/span><span style=\"color: #98C379\">\u2502<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">Reserved<\/span><span style=\"color: #ABB2BF\">         <\/span><span style=\"color: #98C379\">\u2502<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">Random<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">padding<\/span><span style=\"color: #ABB2BF\">          <\/span><span style=\"color: #98C379\">\u2502<\/span><\/span>\n<span class=\"line\"><span style=\"color: #61AFEF\">\u2514\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2518<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #61AFEF\">\u250c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2510<\/span><\/span>\n<span class=\"line\"><span style=\"color: #61AFEF\">\u2502<\/span><span style=\"color: #ABB2BF\">                    <\/span><span style=\"color: #98C379\">CHUNK<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #D19A66\">0<\/span><span style=\"color: #ABB2BF\"> (Variable <\/span><span style=\"color: #98C379\">Size<\/span><span style=\"color: #ABB2BF\">)                   \u2502<\/span><\/span>\n<span class=\"line\"><span style=\"color: #61AFEF\">\u251c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2524<\/span><\/span>\n<span class=\"line\"><span style=\"color: #61AFEF\">\u2502<\/span><span style=\"color: #ABB2BF\">  <\/span><span style=\"color: #98C379\">Chunk<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">Size<\/span><span style=\"color: #ABB2BF\"> (4 <\/span><span style=\"color: #98C379\">bytes<\/span><span style=\"color: #ABB2BF\">)    \u2502 Encrypted size (<\/span><span style=\"color: #61AFEF\">plaintext<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">+<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">tag<\/span><span style=\"color: #ABB2BF\">)  \u2502<\/span><\/span>\n<span class=\"line\"><span style=\"color: #61AFEF\">\u2502<\/span><span style=\"color: #ABB2BF\">  <\/span><span style=\"color: #98C379\">Encrypted<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">Data<\/span><span style=\"color: #ABB2BF\"> (N <\/span><span style=\"color: #98C379\">bytes<\/span><span style=\"color: #ABB2BF\">)\u2502 AES-256-GCM ciphertext            \u2502<\/span><\/span>\n<span class=\"line\"><span style=\"color: #61AFEF\">\u2514\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2518<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #61AFEF\">\u250c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2510<\/span><\/span>\n<span class=\"line\"><span style=\"color: #61AFEF\">\u2502<\/span><span style=\"color: #ABB2BF\">                    <\/span><span style=\"color: #98C379\">CHUNK<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #D19A66\">1<\/span><span style=\"color: #ABB2BF\"> (Variable <\/span><span style=\"color: #98C379\">Size<\/span><span style=\"color: #ABB2BF\">)                   \u2502<\/span><\/span>\n<span class=\"line\"><span style=\"color: #61AFEF\">\u251c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2524<\/span><\/span>\n<span class=\"line\"><span style=\"color: #61AFEF\">\u2502<\/span><span style=\"color: #ABB2BF\">  <\/span><span style=\"color: #98C379\">Chunk<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">Size<\/span><span style=\"color: #ABB2BF\"> (4 <\/span><span style=\"color: #98C379\">bytes<\/span><span style=\"color: #ABB2BF\">)    \u2502 Encrypted size                    \u2502<\/span><\/span>\n<span class=\"line\"><span style=\"color: #61AFEF\">\u2502<\/span><span style=\"color: #ABB2BF\">  <\/span><span style=\"color: #98C379\">Encrypted<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">Data<\/span><span style=\"color: #ABB2BF\"> (M <\/span><span style=\"color: #98C379\">bytes<\/span><span style=\"color: #ABB2BF\">)\u2502 AES-256-GCM ciphertext            \u2502<\/span><\/span>\n<span class=\"line\"><span style=\"color: #61AFEF\">\u2514\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2518<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #56B6C2\">...<\/span><span style=\"color: #ABB2BF\"> (additional <\/span><span style=\"color: #98C379\">chunks<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">as<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">needed<\/span><span style=\"color: #ABB2BF\">)<\/span><\/span>\n<span class=\"line\"><\/span><\/code><\/pre><\/div>\n\n\n\n<h3 class=\"sera-block-heading\">Encryption Specification<\/h3>\n\n\n\n<h3 class=\"sera-block-heading\">Algorithm Details<\/h3>\n\n\n\n<ul class=\"sera-block-list\">\n<li><strong>Cipher<\/strong>: AES-256-GCM (Galois\/Counter Mode)<\/li>\n\n\n\n<li><strong>Key Size<\/strong>: 256 bits<\/li>\n\n\n\n<li><strong>IV\/Nonce<\/strong>: 96 bits (automatically generated per chunk by Tink)<\/li>\n\n\n\n<li><strong>Authentication Tag<\/strong>: 128 bits (16 bytes) per chunk<\/li>\n\n\n\n<li><strong>Associated Data<\/strong>: &#8220;&lt;filename&gt;:chunk:&lt;index&gt;&#8221; (e.g., &#8220;report.pdf:chunk:0&#8221;)<\/li>\n<\/ul>\n\n\n\n<h4 class=\"sera-block-heading\">Per-Chunk Encryption<\/h4>\n\n\n\n<p class=\"sera-block-paragraph\">Each chunk is encrypted independently:<\/p>\n\n\n\n<div class=\"sera-block-kevinbatdorf-code-block-pro cbp-has-line-numbers\" data-code-block-pro-font-family=\"Code-Pro-JetBrains-Mono\" style=\"font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;--cbp-line-number-color:#abb2bf;--cbp-line-number-width:calc(1 * 0.6 * .875rem);line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)\"><span role=\"button\" tabindex=\"0\" style=\"color:#abb2bf;display:none\" aria-label=\"Copy\" class=\"code-block-pro-copy-button\"><pre class=\"code-block-pro-copy-button-pre\" aria-hidden=\"true\"><textarea class=\"code-block-pro-copy-button-textarea\" tabindex=\"-1\" aria-hidden=\"true\" readonly>Input:  plaintext_chunk (up to 64KB)\nAAD:    \"filename:chunk:N\"\nOutput: ciphertext || authentication_tag\n<\/textarea><\/pre><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" style=\"width:24px;height:24px\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" stroke-width=\"2\"><path class=\"with-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M4.5 12.75l6 6 9-13.5\"><\/path><path class=\"without-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M16.5 8.25V6a2.25 2.25 0 00-2.25-2.25H6A2.25 2.25 0 003.75 6v8.25A2.25 2.25 0 006 16.5h2.25m8.25-8.25H18a2.25 2.25 0 012.25 2.25V18A2.25 2.25 0 0118 20.25h-7.5A2.25 2.25 0 018.25 18v-1.5m8.25-8.25h-6a2.25 2.25 0 00-2.25 2.25v6\"><\/path><\/svg><\/span><pre class=\"shiki one-dark-pro\" style=\"background-color: #282c34\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color: #61AFEF\">Input:<\/span><span style=\"color: #ABB2BF\">  <\/span><span style=\"color: #98C379\">plaintext_chunk<\/span><span style=\"color: #ABB2BF\"> (up <\/span><span style=\"color: #98C379\">to<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #D19A66\">64<\/span><span style=\"color: #98C379\">KB<\/span><span style=\"color: #ABB2BF\">)<\/span><\/span>\n<span class=\"line\"><span style=\"color: #61AFEF\">AAD:<\/span><span style=\"color: #ABB2BF\">    <\/span><span style=\"color: #98C379\">&quot;filename:chunk:N&quot;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #61AFEF\">Output:<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">ciphertext<\/span><span style=\"color: #ABB2BF\"> || <\/span><span style=\"color: #61AFEF\">authentication_tag<\/span><\/span>\n<span class=\"line\"><\/span><\/code><\/pre><\/div>\n\n\n\n<p class=\"sera-block-paragraph\"><\/p>\n\n\n\n<p class=\"sera-block-paragraph\">Benefits:<\/p>\n\n\n\n<ul class=\"sera-block-list\">\n<li><strong>Random Access<\/strong>: Decrypt only needed chunks<\/li>\n\n\n\n<li><strong>Integrity<\/strong>: Each chunk authenticated independently<\/li>\n\n\n\n<li><strong>Corruption Isolation<\/strong>: Bad chunk doesn&#8217;t affect others<\/li>\n\n\n\n<li><strong>Parallelization<\/strong>: Chunks can be decrypted in parallel (future enhancement)<\/li>\n<\/ul>\n\n\n\n<h4 class=\"sera-block-heading\">Associated Data Purpose<\/h4>\n\n\n\n<div class=\"sera-block-kevinbatdorf-code-block-pro cbp-has-line-numbers\" data-code-block-pro-font-family=\"Code-Pro-JetBrains-Mono\" style=\"font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;--cbp-line-number-color:#abb2bf;--cbp-line-number-width:calc(2 * 0.6 * .875rem);line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)\"><span role=\"button\" tabindex=\"0\" style=\"color:#abb2bf;display:none\" aria-label=\"Copy\" class=\"code-block-pro-copy-button\"><pre class=\"code-block-pro-copy-button-pre\" aria-hidden=\"true\"><textarea class=\"code-block-pro-copy-button-textarea\" tabindex=\"-1\" aria-hidden=\"true\" readonly>Format: \"&lt;filename>:chunk:&lt;index>\"\nExamples:\n  - \"document.pdf:chunk:0\"\n  - \"document.pdf:chunk:1\"\n  - \"archive.zip:chunk:42\"\n\nPurpose:\n  1. Binds encrypted data to specific file\n  2. Binds encrypted data to specific position\n  3. Prevents chunk reordering attacks\n  4. Prevents chunk substitution attacks\n<\/textarea><\/pre><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" style=\"width:24px;height:24px\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" stroke-width=\"2\"><path class=\"with-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M4.5 12.75l6 6 9-13.5\"><\/path><path class=\"without-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M16.5 8.25V6a2.25 2.25 0 00-2.25-2.25H6A2.25 2.25 0 003.75 6v8.25A2.25 2.25 0 006 16.5h2.25m8.25-8.25H18a2.25 2.25 0 012.25 2.25V18A2.25 2.25 0 0118 20.25h-7.5A2.25 2.25 0 018.25 18v-1.5m8.25-8.25h-6a2.25 2.25 0 00-2.25 2.25v6\"><\/path><\/svg><\/span><pre class=\"shiki one-dark-pro\" style=\"background-color: #282c34\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color: #61AFEF\">Format:<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">&quot;&lt;filename&gt;:chunk:&lt;index&gt;&quot;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #61AFEF\">Examples:<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">  <\/span><span style=\"color: #61AFEF\">-<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">&quot;document.pdf:chunk:0&quot;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">  <\/span><span style=\"color: #61AFEF\">-<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">&quot;document.pdf:chunk:1&quot;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">  <\/span><span style=\"color: #61AFEF\">-<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">&quot;archive.zip:chunk:42&quot;<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #61AFEF\">Purpose:<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">  <\/span><span style=\"color: #61AFEF\">1.<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">Binds<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">encrypted<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">data<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">to<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">specific<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">file<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">  <\/span><span style=\"color: #61AFEF\">2.<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">Binds<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">encrypted<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">data<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">to<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">specific<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">position<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">  <\/span><span style=\"color: #61AFEF\">3.<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">Prevents<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">chunk<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">reordering<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">attacks<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">  <\/span><span style=\"color: #61AFEF\">4.<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">Prevents<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">chunk<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">substitution<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">attacks<\/span><\/span>\n<span class=\"line\"><\/span><\/code><\/pre><\/div>\n\n\n\n<hr class=\"sera-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h2 class=\"sera-block-heading\">Core Components<\/h2>\n\n\n\n<h3 class=\"sera-block-heading\">1. ChunkedEncryptedSftpServer<\/h3>\n\n\n\n<p class=\"sera-block-paragraph\"><strong>Location<\/strong>: ChunkedEncryptedSftpServer.java<\/p>\n\n\n\n<p class=\"sera-block-paragraph\"><strong>Purpose<\/strong>: Main entry point &#8211; initializes and manages SFTP server lifecycle<\/p>\n\n\n\n<p class=\"sera-block-paragraph\"><strong>Key Responsibilities<\/strong>:<\/p>\n\n\n\n<ul class=\"sera-block-list\">\n<li>SSH\/SFTP server initialization and configuration<\/li>\n\n\n\n<li>User authentication setup (PBKDF2)<\/li>\n\n\n\n<li>Virtual file system configuration (per-user directories)<\/li>\n\n\n\n<li>Encryption service initialization<\/li>\n\n\n\n<li>Event listener registration for logging<\/li>\n\n\n\n<li>Graceful shutdown handling<\/li>\n<\/ul>\n\n\n\n<p class=\"sera-block-paragraph\"><strong>Configuration Parameters<\/strong>:<\/p>\n\n\n\n<figure class=\"sera-block-table\"><table class=\"has-fixed-layout\"><thead><tr><th>Parameter<\/th><th>Default<\/th><th>Description<\/th><\/tr><\/thead><tbody><tr><td>sftp.port <\/td><td>2222<\/td><td>Server listening port<\/td><\/tr><tr><td>sftp.storage <\/td><td>.\/sftp-storage<\/td><td>Root storage directory<\/td><\/tr><tr><td>sftp.keyset <\/td><td>.\/keyset.json<\/td><td>Encryption keyset path<\/td><\/tr><tr><td>sftp.chunk.size <\/td><td>65536<\/td><td>Chunk size in bytes (64KB)<\/td><\/tr><tr><td>sftp.use.enc.extension <\/td><td>false<\/td><td>Add .enc suffix to encrypted files<\/td><\/tr><tr><td><\/td><td><\/td><td><\/td><\/tr><\/tbody><\/table><\/figure>\n\n\n\n<p class=\"sera-block-paragraph\"><\/p>\n\n\n\n<p class=\"sera-block-paragraph\"><strong>Usage<\/strong>:<\/p>\n\n\n\n<div class=\"sera-block-kevinbatdorf-code-block-pro cbp-has-line-numbers\" data-code-block-pro-font-family=\"Code-Pro-JetBrains-Mono\" style=\"font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;--cbp-line-number-color:#abb2bf;--cbp-line-number-width:calc(2 * 0.6 * .875rem);line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)\"><span role=\"button\" tabindex=\"0\" style=\"color:#abb2bf;display:none\" aria-label=\"Copy\" class=\"code-block-pro-copy-button\"><pre class=\"code-block-pro-copy-button-pre\" aria-hidden=\"true\"><textarea class=\"code-block-pro-copy-button-textarea\" tabindex=\"-1\" aria-hidden=\"true\" readonly>\/\/ Programmatic\nChunkedEncryptedSftpServer server = new ChunkedEncryptedSftpServer(\n    2222,                          \/\/ port\n    Paths.get(\".\/sftp-storage\"),   \/\/ storage root\n    Paths.get(\".\/keyset.json\"),    \/\/ keyset path\n    false,                         \/\/ useEncExtension\n    64 * 1024                      \/\/ chunkSize\n);\nserver.start();\n\n\/\/ System properties\njava -Dsftp.port=2222 \\\n     -Dsftp.storage=\/data\/sftp \\\n     -Dsftp.keyset=\/keys\/keyset.json \\\n     -Dsftp.chunk.size=131072 \\\n     -jar sftp-server.jar\n<\/textarea><\/pre><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" style=\"width:24px;height:24px\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" stroke-width=\"2\"><path class=\"with-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M4.5 12.75l6 6 9-13.5\"><\/path><path class=\"without-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M16.5 8.25V6a2.25 2.25 0 00-2.25-2.25H6A2.25 2.25 0 003.75 6v8.25A2.25 2.25 0 006 16.5h2.25m8.25-8.25H18a2.25 2.25 0 012.25 2.25V18A2.25 2.25 0 0118 20.25h-7.5A2.25 2.25 0 018.25 18v-1.5m8.25-8.25h-6a2.25 2.25 0 00-2.25 2.25v6\"><\/path><\/svg><\/span><pre class=\"shiki one-dark-pro\" style=\"background-color: #282c34\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color: #61AFEF\">\/\/<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">Programmatic<\/span><\/span>\n<span class=\"line\"><span style=\"color: #61AFEF\">ChunkedEncryptedSftpServer<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">server<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">=<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">new<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">ChunkedEncryptedSftpServer<\/span><span style=\"color: #ABB2BF\">(<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">    <\/span><span style=\"color: #61AFEF\">2222,<\/span><span style=\"color: #ABB2BF\">                          <\/span><span style=\"color: #98C379\">\/\/<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">port<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">    <\/span><span style=\"color: #61AFEF\">Paths.get(<\/span><span style=\"color: #61AFEF\">&quot;.\/sftp-storage&quot;<\/span><span style=\"color: #ABB2BF\">)<\/span><span style=\"color: #98C379\">,<\/span><span style=\"color: #ABB2BF\">   <\/span><span style=\"color: #98C379\">\/\/<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">storage<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">root<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">    <\/span><span style=\"color: #61AFEF\">Paths.get(<\/span><span style=\"color: #61AFEF\">&quot;.\/keyset.json&quot;<\/span><span style=\"color: #ABB2BF\">),    \/\/ keyset path<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">    <\/span><span style=\"color: #56B6C2\">false<\/span><span style=\"color: #ABB2BF\">,                         <\/span><span style=\"color: #98C379\">\/\/<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">useEncExtension<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">    <\/span><span style=\"color: #61AFEF\">64<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #E5C07B\">*<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #D19A66\">1024<\/span><span style=\"color: #ABB2BF\">                      <\/span><span style=\"color: #98C379\">\/\/<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">chunkSize<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">);<\/span><\/span>\n<span class=\"line\"><span style=\"color: #61AFEF\">server.start<\/span><span style=\"color: #ABB2BF\">();<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #61AFEF\">\/\/<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">System<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">properties<\/span><\/span>\n<span class=\"line\"><span style=\"color: #61AFEF\">java<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #D19A66\">-Dsftp.port=2222<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #56B6C2\">\\<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">     <\/span><span style=\"color: #D19A66\">-Dsftp.storage=\/data\/sftp<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #56B6C2\">\\<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">     <\/span><span style=\"color: #D19A66\">-Dsftp.keyset=\/keys\/keyset.json<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #56B6C2\">\\<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">     <\/span><span style=\"color: #D19A66\">-Dsftp.chunk.size=131072<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #56B6C2\">\\<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">     <\/span><span style=\"color: #D19A66\">-jar<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">sftp-server.jar<\/span><\/span>\n<span class=\"line\"><\/span><\/code><\/pre><\/div>\n\n\n\n<p class=\"sera-block-paragraph\"><\/p>\n\n\n\n<p class=\"sera-block-paragraph\"><strong>Server Output Example<\/strong>:<\/p>\n\n\n\n<div class=\"sera-block-kevinbatdorf-code-block-pro cbp-has-line-numbers\" data-code-block-pro-font-family=\"Code-Pro-JetBrains-Mono\" style=\"font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;--cbp-line-number-color:#abb2bf;--cbp-line-number-width:calc(2 * 0.6 * .875rem);line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)\"><span role=\"button\" tabindex=\"0\" style=\"color:#abb2bf;display:none\" aria-label=\"Copy\" class=\"code-block-pro-copy-button\"><pre class=\"code-block-pro-copy-button-pre\" aria-hidden=\"true\"><textarea class=\"code-block-pro-copy-button-textarea\" tabindex=\"-1\" aria-hidden=\"true\" readonly>======================================================================\n  CHUNKED ENCRYPTED SFTP SERVER\n======================================================================\nStack:\n  - Apache MINA SSHD 2.17.1\n  - Google Tink 1.20.0 (AES-256-GCM)\n\nConfiguration:\n  - Port: 2222\n  - Storage: \/home\/user\/sftp-storage\n  - Chunk size: 64 KB\n  - Extension mode: no suffix\n\nSecurity:\n  - Encryption: AES-256-GCM (per-chunk authentication)\n  - Mode: Streaming (zero plaintext on disk)\n  - Memory usage: ~128 KB per transfer\n======================================================================\n<\/textarea><\/pre><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" style=\"width:24px;height:24px\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" stroke-width=\"2\"><path class=\"with-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M4.5 12.75l6 6 9-13.5\"><\/path><path class=\"without-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M16.5 8.25V6a2.25 2.25 0 00-2.25-2.25H6A2.25 2.25 0 003.75 6v8.25A2.25 2.25 0 006 16.5h2.25m8.25-8.25H18a2.25 2.25 0 012.25 2.25V18A2.25 2.25 0 0118 20.25h-7.5A2.25 2.25 0 018.25 18v-1.5m8.25-8.25h-6a2.25 2.25 0 00-2.25 2.25v6\"><\/path><\/svg><\/span><pre class=\"shiki one-dark-pro\" style=\"background-color: #282c34\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color: #ABB2BF\">======================================================================<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">  <\/span><span style=\"color: #61AFEF\">CHUNKED<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">ENCRYPTED<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">SFTP<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">SERVER<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">======================================================================<\/span><\/span>\n<span class=\"line\"><span style=\"color: #61AFEF\">Stack:<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">  <\/span><span style=\"color: #61AFEF\">-<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">Apache<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">MINA<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">SSHD<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #D19A66\">2.17<\/span><span style=\"color: #98C379\">.1<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">  <\/span><span style=\"color: #61AFEF\">-<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">Google<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">Tink<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #D19A66\">1.20<\/span><span style=\"color: #98C379\">.0<\/span><span style=\"color: #ABB2BF\"> (AES-256-GCM)<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #61AFEF\">Configuration:<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">  <\/span><span style=\"color: #61AFEF\">-<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">Port:<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #D19A66\">2222<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">  <\/span><span style=\"color: #61AFEF\">-<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">Storage:<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">\/home\/user\/sftp-storage<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">  <\/span><span style=\"color: #61AFEF\">-<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">Chunk<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">size:<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #D19A66\">64<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">KB<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">  <\/span><span style=\"color: #61AFEF\">-<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">Extension<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">mode:<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">no<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">suffix<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #61AFEF\">Security:<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">  <\/span><span style=\"color: #61AFEF\">-<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">Encryption:<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">AES-256-GCM<\/span><span style=\"color: #ABB2BF\"> (per-chunk <\/span><span style=\"color: #98C379\">authentication<\/span><span style=\"color: #ABB2BF\">)<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">  <\/span><span style=\"color: #61AFEF\">-<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">Mode:<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">Streaming<\/span><span style=\"color: #ABB2BF\"> (zero <\/span><span style=\"color: #98C379\">plaintext<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">on<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">disk<\/span><span style=\"color: #ABB2BF\">)<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">  <\/span><span style=\"color: #61AFEF\">-<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">Memory<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">usage:<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">~128<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">KB<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">per<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">transfer<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">======================================================================<\/span><\/span>\n<span class=\"line\"><\/span><\/code><\/pre><\/div>\n\n\n\n<hr class=\"sera-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h3 class=\"sera-block-heading\">2. ChunkedEncryptedSftpAccessor<\/h3>\n\n\n\n<p class=\"sera-block-paragraph\"><strong>Location<\/strong>: ChunkedEncryptedSftpAccessor.java<\/p>\n\n\n\n<p class=\"sera-block-paragraph\"><strong>Purpose<\/strong>: Intercepts SFTP file operations and routes through encryption channels<\/p>\n\n\n\n<p class=\"sera-block-paragraph\"><strong>Interface<\/strong>: Implements SftpFileSystemAccessor from Apache MINA SSHD<\/p>\n\n\n\n<p class=\"sera-block-paragraph\"><strong>Key Method<\/strong>:<\/p>\n\n\n\n<div class=\"sera-block-kevinbatdorf-code-block-pro cbp-has-line-numbers\" data-code-block-pro-font-family=\"Code-Pro-JetBrains-Mono\" style=\"font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;--cbp-line-number-color:#abb2bf;--cbp-line-number-width:calc(2 * 0.6 * .875rem);line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)\"><span role=\"button\" tabindex=\"0\" style=\"color:#abb2bf;display:none\" aria-label=\"Copy\" class=\"code-block-pro-copy-button\"><pre class=\"code-block-pro-copy-button-pre\" aria-hidden=\"true\"><textarea class=\"code-block-pro-copy-button-textarea\" tabindex=\"-1\" aria-hidden=\"true\" readonly>@Override\npublic SeekableByteChannel openFile(\n    SftpSubsystemProxy subsystem,\n    FileHandle fileHandle,\n    Path file,\n    String handle,\n    Set&lt;? extends OpenOption> options,\n    FileAttribute&lt;?>[] attrs\n) throws IOException\n<\/textarea><\/pre><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" style=\"width:24px;height:24px\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" stroke-width=\"2\"><path class=\"with-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M4.5 12.75l6 6 9-13.5\"><\/path><path class=\"without-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M16.5 8.25V6a2.25 2.25 0 00-2.25-2.25H6A2.25 2.25 0 003.75 6v8.25A2.25 2.25 0 006 16.5h2.25m8.25-8.25H18a2.25 2.25 0 012.25 2.25V18A2.25 2.25 0 0118 20.25h-7.5A2.25 2.25 0 018.25 18v-1.5m8.25-8.25h-6a2.25 2.25 0 00-2.25 2.25v6\"><\/path><\/svg><\/span><pre class=\"shiki one-dark-pro\" style=\"background-color: #282c34\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color: #61AFEF\">@Override<\/span><\/span>\n<span class=\"line\"><span style=\"color: #61AFEF\">public<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">SeekableByteChannel<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">openFile<\/span><span style=\"color: #ABB2BF\">(<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">    <\/span><span style=\"color: #61AFEF\">SftpSubsystemProxy<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">subsystem,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">    <\/span><span style=\"color: #61AFEF\">FileHandle<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">fileHandle,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">    <\/span><span style=\"color: #61AFEF\">Path<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">file,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">    <\/span><span style=\"color: #61AFEF\">String<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">handle,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">    <\/span><span style=\"color: #61AFEF\">Set&lt;?<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">extends<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">OpenOptio<\/span><span style=\"color: #ABB2BF\">n&gt; <\/span><span style=\"color: #98C379\">options,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">    <\/span><span style=\"color: #61AFEF\">FileAttribute&lt;?&gt;[]<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">attrs<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">) <\/span><span style=\"color: #98C379\">throws<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">IOException<\/span><\/span>\n<span class=\"line\"><\/span><\/code><\/pre><\/div>\n\n\n\n<p class=\"sera-block-paragraph\"><strong>Operation Logic<\/strong>:<\/p>\n\n\n\n<div class=\"sera-block-kevinbatdorf-code-block-pro cbp-has-line-numbers\" data-code-block-pro-font-family=\"Code-Pro-JetBrains-Mono\" style=\"font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;--cbp-line-number-color:#abb2bf;--cbp-line-number-width:calc(2 * 0.6 * .875rem);line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)\"><span role=\"button\" tabindex=\"0\" style=\"color:#abb2bf;display:none\" aria-label=\"Copy\" class=\"code-block-pro-copy-button\"><pre class=\"code-block-pro-copy-button-pre\" aria-hidden=\"true\"><textarea class=\"code-block-pro-copy-button-textarea\" tabindex=\"-1\" aria-hidden=\"true\" readonly>1. Extract filename from path\n2. Determine operation mode:\n   - READ flag set \u2192 read operation\n   - WRITE\/CREATE flags set \u2192 write operation\n   - Both set \u2192 determine from file existence\n3. Map logical filename to physical path:\n   - No extension mode: filename.txt \u2192 filename.txt (encrypted)\n   - Extension mode: filename.txt \u2192 filename.txt.enc\n4. Return appropriate channel:\n   - ChunkedReadChannel for reads\n   - ChunkedWriteChannel for writes\n<\/textarea><\/pre><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" style=\"width:24px;height:24px\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" stroke-width=\"2\"><path class=\"with-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M4.5 12.75l6 6 9-13.5\"><\/path><path class=\"without-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M16.5 8.25V6a2.25 2.25 0 00-2.25-2.25H6A2.25 2.25 0 003.75 6v8.25A2.25 2.25 0 006 16.5h2.25m8.25-8.25H18a2.25 2.25 0 012.25 2.25V18A2.25 2.25 0 0118 20.25h-7.5A2.25 2.25 0 018.25 18v-1.5m8.25-8.25h-6a2.25 2.25 0 00-2.25 2.25v6\"><\/path><\/svg><\/span><pre class=\"shiki one-dark-pro\" style=\"background-color: #282c34\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color: #61AFEF\">1.<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">Extract<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">filename<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">from<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">path<\/span><\/span>\n<span class=\"line\"><span style=\"color: #61AFEF\">2.<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">Determine<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">operation<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">mode:<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">   <\/span><span style=\"color: #61AFEF\">-<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">READ<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">flag<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">set<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">\u2192<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">read<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">operation<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">   <\/span><span style=\"color: #61AFEF\">-<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">WRITE\/CREATE<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">flags<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">set<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">\u2192<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">write<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">operation<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">   <\/span><span style=\"color: #61AFEF\">-<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">Both<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">set<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">\u2192<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">determine<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">from<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">file<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">existence<\/span><\/span>\n<span class=\"line\"><span style=\"color: #61AFEF\">3.<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">Map<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">logical<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">filename<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">to<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">physical<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">path:<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">   <\/span><span style=\"color: #61AFEF\">-<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">No<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">extension<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">mode:<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">filename.txt<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">\u2192<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">filename.txt<\/span><span style=\"color: #ABB2BF\"> (encrypted)<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">   <\/span><span style=\"color: #61AFEF\">-<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">Extension<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">mode:<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">filename.txt<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">\u2192<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">filename.txt.enc<\/span><\/span>\n<span class=\"line\"><span style=\"color: #61AFEF\">4.<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">Return<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">appropriate<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">channel:<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">   <\/span><span style=\"color: #61AFEF\">-<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">ChunkedReadChannel<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">for<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">reads<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">   <\/span><span style=\"color: #61AFEF\">-<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">ChunkedWriteChannel<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">for<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">writes<\/span><\/span>\n<span class=\"line\"><\/span><\/code><\/pre><\/div>\n\n\n\n<p class=\"sera-block-paragraph\"><\/p>\n\n\n\n<p class=\"sera-block-paragraph\"><strong>Extension Modes<\/strong>:<\/p>\n\n\n\n<h3 class=\"sera-block-heading\">Mode 1: No Extension (Recommended)<\/h3>\n\n\n\n<div class=\"sera-block-kevinbatdorf-code-block-pro cbp-has-line-numbers\" data-code-block-pro-font-family=\"Code-Pro-JetBrains-Mono\" style=\"font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;--cbp-line-number-color:#abb2bf;--cbp-line-number-width:calc(2 * 0.6 * .875rem);line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)\"><span role=\"button\" tabindex=\"0\" style=\"color:#abb2bf;display:none\" aria-label=\"Copy\" class=\"code-block-pro-copy-button\"><pre class=\"code-block-pro-copy-button-pre\" aria-hidden=\"true\"><textarea class=\"code-block-pro-copy-button-textarea\" tabindex=\"-1\" aria-hidden=\"true\" readonly>Client View:     report.pdf\nPhysical Disk:   report.pdf (encrypted content)\n\nAdvantages:\n  - Clean directory listings\n  - Transparent to client\n  - No filename modifications\n\nDirectory Listing:\n  drwxr-xr-x  2 admin admin 4096 Jan 27 10:00 .\n  drwxr-xr-x  3 admin admin 4096 Jan 27 09:00 ..\n  -rw-r--r--  1 admin admin 1024 Jan 27 10:15 report.pdf\n  -rw-r--r--  1 admin admin 2048 Jan 27 10:20 data.csv\n<\/textarea><\/pre><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" style=\"width:24px;height:24px\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" stroke-width=\"2\"><path class=\"with-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M4.5 12.75l6 6 9-13.5\"><\/path><path class=\"without-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M16.5 8.25V6a2.25 2.25 0 00-2.25-2.25H6A2.25 2.25 0 003.75 6v8.25A2.25 2.25 0 006 16.5h2.25m8.25-8.25H18a2.25 2.25 0 012.25 2.25V18A2.25 2.25 0 0118 20.25h-7.5A2.25 2.25 0 018.25 18v-1.5m8.25-8.25h-6a2.25 2.25 0 00-2.25 2.25v6\"><\/path><\/svg><\/span><pre class=\"shiki one-dark-pro\" style=\"background-color: #282c34\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color: #61AFEF\">Client<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">View:<\/span><span style=\"color: #ABB2BF\">     <\/span><span style=\"color: #98C379\">report.pdf<\/span><\/span>\n<span class=\"line\"><span style=\"color: #61AFEF\">Physical<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">Disk:<\/span><span style=\"color: #ABB2BF\">   <\/span><span style=\"color: #98C379\">report.pdf<\/span><span style=\"color: #ABB2BF\"> (encrypted <\/span><span style=\"color: #98C379\">content<\/span><span style=\"color: #ABB2BF\">)<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #61AFEF\">Advantages:<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">  <\/span><span style=\"color: #61AFEF\">-<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">Clean<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">directory<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">listings<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">  <\/span><span style=\"color: #61AFEF\">-<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">Transparent<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">to<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">client<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">  <\/span><span style=\"color: #61AFEF\">-<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">No<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">filename<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">modifications<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #61AFEF\">Directory<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">Listing:<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">  <\/span><span style=\"color: #61AFEF\">drwxr-xr-x<\/span><span style=\"color: #ABB2BF\">  <\/span><span style=\"color: #D19A66\">2<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">admin<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">admin<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #D19A66\">4096<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">Jan<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #D19A66\">27<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #D19A66\">10<\/span><span style=\"color: #98C379\">:00<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">.<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">  <\/span><span style=\"color: #61AFEF\">drwxr-xr-x<\/span><span style=\"color: #ABB2BF\">  <\/span><span style=\"color: #D19A66\">3<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">admin<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">admin<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #D19A66\">4096<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">Jan<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #D19A66\">27<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #D19A66\">09<\/span><span style=\"color: #98C379\">:00<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">..<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">  <\/span><span style=\"color: #61AFEF\">-rw-r--r--<\/span><span style=\"color: #ABB2BF\">  <\/span><span style=\"color: #D19A66\">1<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">admin<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">admin<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #D19A66\">1024<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">Jan<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #D19A66\">27<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #D19A66\">10<\/span><span style=\"color: #98C379\">:15<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">report.pdf<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">  <\/span><span style=\"color: #61AFEF\">-rw-r--r--<\/span><span style=\"color: #ABB2BF\">  <\/span><span style=\"color: #D19A66\">1<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">admin<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">admin<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #D19A66\">2048<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">Jan<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #D19A66\">27<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #D19A66\">10<\/span><span style=\"color: #98C379\">:20<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">data.csv<\/span><\/span>\n<span class=\"line\"><\/span><\/code><\/pre><\/div>\n\n\n\n<h3 class=\"sera-block-heading\">Mode 2: With .enc Extension<\/h3>\n\n\n\n<div class=\"sera-block-kevinbatdorf-code-block-pro cbp-has-line-numbers\" data-code-block-pro-font-family=\"Code-Pro-JetBrains-Mono\" style=\"font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;--cbp-line-number-color:#abb2bf;--cbp-line-number-width:calc(2 * 0.6 * .875rem);line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)\"><span role=\"button\" tabindex=\"0\" style=\"color:#abb2bf;display:none\" aria-label=\"Copy\" class=\"code-block-pro-copy-button\"><pre class=\"code-block-pro-copy-button-pre\" aria-hidden=\"true\"><textarea class=\"code-block-pro-copy-button-textarea\" tabindex=\"-1\" aria-hidden=\"true\" readonly>Client View:     report.pdf.enc\nPhysical Disk:   report.pdf.enc (encrypted content)\n\nAdvantages:\n  - Explicit encryption indication\n  - Easy to identify encrypted files\n\nDisadvantages:\n  - Visible .enc suffix\n  - Cannot be hidden in MINA SSHD 2.17.1\n\nDirectory Listing:\n  drwxr-xr-x  2 admin admin 4096 Jan 27 10:00 .\n  drwxr-xr-x  3 admin admin 4096 Jan 27 09:00 ..\n  -rw-r--r--  1 admin admin 1024 Jan 27 10:15 report.pdf.enc\n  -rw-r--r--  1 admin admin 2048 Jan 27 10:20 data.csv.enc\n<\/textarea><\/pre><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" style=\"width:24px;height:24px\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" stroke-width=\"2\"><path class=\"with-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M4.5 12.75l6 6 9-13.5\"><\/path><path class=\"without-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M16.5 8.25V6a2.25 2.25 0 00-2.25-2.25H6A2.25 2.25 0 003.75 6v8.25A2.25 2.25 0 006 16.5h2.25m8.25-8.25H18a2.25 2.25 0 012.25 2.25V18A2.25 2.25 0 0118 20.25h-7.5A2.25 2.25 0 018.25 18v-1.5m8.25-8.25h-6a2.25 2.25 0 00-2.25 2.25v6\"><\/path><\/svg><\/span><pre class=\"shiki one-dark-pro\" style=\"background-color: #282c34\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color: #61AFEF\">Client<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">View:<\/span><span style=\"color: #ABB2BF\">     <\/span><span style=\"color: #98C379\">report.pdf.enc<\/span><\/span>\n<span class=\"line\"><span style=\"color: #61AFEF\">Physical<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">Disk:<\/span><span style=\"color: #ABB2BF\">   <\/span><span style=\"color: #98C379\">report.pdf.enc<\/span><span style=\"color: #ABB2BF\"> (encrypted <\/span><span style=\"color: #98C379\">content<\/span><span style=\"color: #ABB2BF\">)<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #61AFEF\">Advantages:<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">  <\/span><span style=\"color: #61AFEF\">-<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">Explicit<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">encryption<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">indication<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">  <\/span><span style=\"color: #61AFEF\">-<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">Easy<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">to<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">identify<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">encrypted<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">files<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #61AFEF\">Disadvantages:<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">  <\/span><span style=\"color: #61AFEF\">-<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">Visible<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">.enc<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">suffix<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">  <\/span><span style=\"color: #61AFEF\">-<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">Cannot<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">be<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">hidden<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">in<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">MINA<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">SSHD<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #D19A66\">2.17<\/span><span style=\"color: #98C379\">.1<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #61AFEF\">Directory<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">Listing:<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">  <\/span><span style=\"color: #61AFEF\">drwxr-xr-x<\/span><span style=\"color: #ABB2BF\">  <\/span><span style=\"color: #D19A66\">2<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">admin<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">admin<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #D19A66\">4096<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">Jan<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #D19A66\">27<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #D19A66\">10<\/span><span style=\"color: #98C379\">:00<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">.<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">  <\/span><span style=\"color: #61AFEF\">drwxr-xr-x<\/span><span style=\"color: #ABB2BF\">  <\/span><span style=\"color: #D19A66\">3<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">admin<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">admin<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #D19A66\">4096<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">Jan<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #D19A66\">27<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #D19A66\">09<\/span><span style=\"color: #98C379\">:00<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">..<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">  <\/span><span style=\"color: #61AFEF\">-rw-r--r--<\/span><span style=\"color: #ABB2BF\">  <\/span><span style=\"color: #D19A66\">1<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">admin<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">admin<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #D19A66\">1024<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">Jan<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #D19A66\">27<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #D19A66\">10<\/span><span style=\"color: #98C379\">:15<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">report.pdf.enc<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">  <\/span><span style=\"color: #61AFEF\">-rw-r--r--<\/span><span style=\"color: #ABB2BF\">  <\/span><span style=\"color: #D19A66\">1<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">admin<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">admin<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #D19A66\">2048<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">Jan<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #D19A66\">27<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #D19A66\">10<\/span><span style=\"color: #98C379\">:20<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">data.csv.enc<\/span><\/span>\n<span class=\"line\"><\/span><\/code><\/pre><\/div>\n\n\n\n<hr class=\"sera-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h3 class=\"sera-block-heading\">3. ChunkedEncryptionService<\/h3>\n\n\n\n<p class=\"sera-block-paragraph\"><strong>Location<\/strong>: <code>ChunkedEncryptionService.java<\/code><\/p>\n\n\n\n<p class=\"sera-block-paragraph\"><strong>Purpose<\/strong>: Core encryption\/decryption engine using Google Tink<\/p>\n\n\n\n<p class=\"sera-block-paragraph\"><strong>Key Features<\/strong>:<\/p>\n\n\n\n<ul class=\"sera-block-list\">\n<li>AES-256-GCM encryption with Google Tink<\/li>\n\n\n\n<li>Keyset management (encrypted storage with master key)<\/li>\n\n\n\n<li>Header creation and parsing<\/li>\n\n\n\n<li>Chunk-level encryption\/decryption<\/li>\n\n\n\n<li>Random access chunk retrieval by index<\/li>\n<\/ul>\n\n\n\n<p class=\"sera-block-paragraph\"><strong>Constructor<\/strong>:<\/p>\n\n\n\n<div class=\"sera-block-kevinbatdorf-code-block-pro cbp-has-line-numbers\" data-code-block-pro-font-family=\"Code-Pro-JetBrains-Mono\" style=\"font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;--cbp-line-number-color:#abb2bf;--cbp-line-number-width:calc(1 * 0.6 * .875rem);line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)\"><span role=\"button\" tabindex=\"0\" style=\"color:#abb2bf;display:none\" aria-label=\"Copy\" class=\"code-block-pro-copy-button\"><pre class=\"code-block-pro-copy-button-pre\" aria-hidden=\"true\"><textarea class=\"code-block-pro-copy-button-textarea\" tabindex=\"-1\" aria-hidden=\"true\" readonly>public ChunkedEncryptionService(Path keysetPath, int chunkSize) \n    throws GeneralSecurityException, IOException\n<\/textarea><\/pre><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" style=\"width:24px;height:24px\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" stroke-width=\"2\"><path class=\"with-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M4.5 12.75l6 6 9-13.5\"><\/path><path class=\"without-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M16.5 8.25V6a2.25 2.25 0 00-2.25-2.25H6A2.25 2.25 0 003.75 6v8.25A2.25 2.25 0 006 16.5h2.25m8.25-8.25H18a2.25 2.25 0 012.25 2.25V18A2.25 2.25 0 0118 20.25h-7.5A2.25 2.25 0 018.25 18v-1.5m8.25-8.25h-6a2.25 2.25 0 00-2.25 2.25v6\"><\/path><\/svg><\/span><pre class=\"shiki one-dark-pro\" style=\"background-color: #282c34\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color: #61AFEF\">public<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">ChunkedEncryptionService<\/span><span style=\"color: #ABB2BF\">(<\/span><span style=\"color: #61AFEF\">Path<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">keysetPath,<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">int<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">chunkSize<\/span><span style=\"color: #ABB2BF\">) <\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">    <\/span><span style=\"color: #61AFEF\">throws<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">GeneralSecurityException,<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">IOException<\/span><\/span>\n<span class=\"line\"><\/span><\/code><\/pre><\/div>\n\n\n\n<p class=\"sera-block-paragraph\"><\/p>\n\n\n\n<p class=\"sera-block-paragraph\"><strong>Core Methods<\/strong>:<\/p>\n\n\n\n<div class=\"sera-block-kevinbatdorf-code-block-pro cbp-has-line-numbers\" data-code-block-pro-font-family=\"Code-Pro-JetBrains-Mono\" style=\"font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;--cbp-line-number-color:#abb2bf;--cbp-line-number-width:calc(2 * 0.6 * .875rem);line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)\"><span role=\"button\" tabindex=\"0\" style=\"color:#abb2bf;display:none\" aria-label=\"Copy\" class=\"code-block-pro-copy-button\"><pre class=\"code-block-pro-copy-button-pre\" aria-hidden=\"true\"><textarea class=\"code-block-pro-copy-button-textarea\" tabindex=\"-1\" aria-hidden=\"true\" readonly>\/\/ Encrypt entire stream\npublic void encryptStream(byte[] plaintext, String filename, OutputStream output)\n\n\/\/ Decrypt entire stream\npublic byte[] decryptStream(InputStream input, String filename)\n\n\/\/ Get file metadata\npublic FileHeader getFileHeader(InputStream input)\n\n\/\/ Random access decryption\npublic byte[] decryptChunkByIndex(RandomAccessFile input, String filename, int chunkIndex)\n\n\/\/ Single chunk operations\npublic byte[] encryptChunk(byte[] chunk, String filename, int chunkIndex)\npublic byte[] decryptChunk(byte[] encryptedChunk, String filename, int chunkIndex)\n<\/textarea><\/pre><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" style=\"width:24px;height:24px\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" stroke-width=\"2\"><path class=\"with-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M4.5 12.75l6 6 9-13.5\"><\/path><path class=\"without-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M16.5 8.25V6a2.25 2.25 0 00-2.25-2.25H6A2.25 2.25 0 003.75 6v8.25A2.25 2.25 0 006 16.5h2.25m8.25-8.25H18a2.25 2.25 0 012.25 2.25V18A2.25 2.25 0 0118 20.25h-7.5A2.25 2.25 0 018.25 18v-1.5m8.25-8.25h-6a2.25 2.25 0 00-2.25 2.25v6\"><\/path><\/svg><\/span><pre class=\"shiki one-dark-pro\" style=\"background-color: #282c34\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color: #61AFEF\">\/\/<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">Encrypt<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">entire<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">stream<\/span><\/span>\n<span class=\"line\"><span style=\"color: #61AFEF\">public<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">void<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">encryptStream<\/span><span style=\"color: #ABB2BF\">(<\/span><span style=\"color: #61AFEF\">byte[]<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">plaintext,<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">String<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">filename,<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">OutputStream<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">output<\/span><span style=\"color: #ABB2BF\">)<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #61AFEF\">\/\/<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">Decrypt<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">entire<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">stream<\/span><\/span>\n<span class=\"line\"><span style=\"color: #61AFEF\">public<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">byte[]<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">decryptStream<\/span><span style=\"color: #ABB2BF\">(<\/span><span style=\"color: #61AFEF\">InputStream<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">input,<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">String<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">filename<\/span><span style=\"color: #ABB2BF\">)<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #61AFEF\">\/\/<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">Get<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">file<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">metadata<\/span><\/span>\n<span class=\"line\"><span style=\"color: #61AFEF\">public<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">FileHeader<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">getFileHeader<\/span><span style=\"color: #ABB2BF\">(<\/span><span style=\"color: #61AFEF\">InputStream<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">input<\/span><span style=\"color: #ABB2BF\">)<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #61AFEF\">\/\/<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">Random<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">access<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">decryption<\/span><\/span>\n<span class=\"line\"><span style=\"color: #61AFEF\">public<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">byte[]<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">decryptChunkByIndex<\/span><span style=\"color: #ABB2BF\">(<\/span><span style=\"color: #61AFEF\">RandomAccessFile<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">input,<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">String<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">filename,<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">int<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">chunkIndex<\/span><span style=\"color: #ABB2BF\">)<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #61AFEF\">\/\/<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">Single<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">chunk<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">operations<\/span><\/span>\n<span class=\"line\"><span style=\"color: #61AFEF\">public<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">byte[]<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">encryptChunk<\/span><span style=\"color: #ABB2BF\">(<\/span><span style=\"color: #61AFEF\">byte[]<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">chunk,<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">String<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">filename,<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">int<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">chunkIndex<\/span><span style=\"color: #ABB2BF\">)<\/span><\/span>\n<span class=\"line\"><span style=\"color: #61AFEF\">public<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">byte[]<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">decryptChunk<\/span><span style=\"color: #ABB2BF\">(<\/span><span style=\"color: #61AFEF\">byte[]<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">encryptedChunk,<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">String<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">filename,<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">int<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">chunkIndex<\/span><span style=\"color: #ABB2BF\">)<\/span><\/span>\n<span class=\"line\"><\/span><\/code><\/pre><\/div>\n\n\n\n<p class=\"sera-block-paragraph\"><\/p>\n\n\n\n<p class=\"sera-block-paragraph\"><strong>Keyset Management<\/strong>:<\/p>\n\n\n\n<p class=\"sera-block-paragraph\">The service manages encryption keys using Google Tink&#8217;s keyset format:<\/p>\n\n\n\n<div class=\"sera-block-kevinbatdorf-code-block-pro cbp-has-line-numbers\" data-code-block-pro-font-family=\"Code-Pro-JetBrains-Mono\" style=\"font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;--cbp-line-number-color:#abb2bf;--cbp-line-number-width:calc(1 * 0.6 * .875rem);line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)\"><span role=\"button\" tabindex=\"0\" style=\"color:#abb2bf;display:none\" aria-label=\"Copy\" class=\"code-block-pro-copy-button\"><pre class=\"code-block-pro-copy-button-pre\" aria-hidden=\"true\"><textarea class=\"code-block-pro-copy-button-textarea\" tabindex=\"-1\" aria-hidden=\"true\" readonly>\/\/ Keyset storage (encrypted with master key)\n{\n  \"encryptedKeyset\": \"...\",  \/\/ Base64-encoded encrypted keyset\n  \"keysetInfo\": {\n    \"primaryKeyId\": 123456789,\n    \"keyInfo\": &#91;...&#93;\n  }\n}\n<\/textarea><\/pre><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" style=\"width:24px;height:24px\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" stroke-width=\"2\"><path class=\"with-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M4.5 12.75l6 6 9-13.5\"><\/path><path class=\"without-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M16.5 8.25V6a2.25 2.25 0 00-2.25-2.25H6A2.25 2.25 0 003.75 6v8.25A2.25 2.25 0 006 16.5h2.25m8.25-8.25H18a2.25 2.25 0 012.25 2.25V18A2.25 2.25 0 0118 20.25h-7.5A2.25 2.25 0 018.25 18v-1.5m8.25-8.25h-6a2.25 2.25 0 00-2.25 2.25v6\"><\/path><\/svg><\/span><pre class=\"shiki one-dark-pro\" style=\"background-color: #282c34\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color: #61AFEF\">\/\/<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">Keyset<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">storage<\/span><span style=\"color: #ABB2BF\"> (encrypted <\/span><span style=\"color: #98C379\">with<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">master<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">key<\/span><span style=\"color: #ABB2BF\">)<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">{<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">  <\/span><span style=\"color: #61AFEF\">&quot;encryptedKeyset&quot;<\/span><span style=\"color: #56B6C2\">:<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">&quot;...&quot;,<\/span><span style=\"color: #ABB2BF\">  <\/span><span style=\"color: #98C379\">\/\/<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">Base64-encoded<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">encrypted<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">keyset<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">  <\/span><span style=\"color: #61AFEF\">&quot;keysetInfo&quot;<\/span><span style=\"color: #56B6C2\">:<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">{<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">    <\/span><span style=\"color: #61AFEF\">&quot;primaryKeyId&quot;<\/span><span style=\"color: #56B6C2\">:<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #D19A66\">123456789<\/span><span style=\"color: #98C379\">,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">    <\/span><span style=\"color: #61AFEF\">&quot;keyInfo&quot;<\/span><span style=\"color: #56B6C2\">:<\/span><span style=\"color: #ABB2BF\"> &#91;...&#93;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">  }<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">}<\/span><\/span>\n<span class=\"line\"><\/span><\/code><\/pre><\/div>\n\n\n\n<p class=\"sera-block-paragraph\"><strong>IMPORTANT SECURITY NOTE<\/strong> (Educational Implementation):<\/p>\n\n\n\n<p class=\"sera-block-paragraph\">The current implementation uses a hardcoded master key for demonstration purposes:<\/p>\n\n\n\n<div class=\"sera-block-kevinbatdorf-code-block-pro cbp-has-line-numbers\" data-code-block-pro-font-family=\"Code-Pro-JetBrains-Mono\" style=\"font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;--cbp-line-number-color:#abb2bf;--cbp-line-number-width:calc(1 * 0.6 * .875rem);line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)\"><span role=\"button\" tabindex=\"0\" style=\"color:#abb2bf;display:none\" aria-label=\"Copy\" class=\"code-block-pro-copy-button\"><pre class=\"code-block-pro-copy-button-pre\" aria-hidden=\"true\"><textarea class=\"code-block-pro-copy-button-textarea\" tabindex=\"-1\" aria-hidden=\"true\" readonly>\/\/ \u26a0\ufe0f EDUCATIONAL\/TESTING ONLY - NOT FOR PRODUCTION \u26a0\ufe0f\nbyte[] masterKeyBytes = Arrays.copyOf(\n    \"your-plaintext-password-here\".getBytes(StandardCharsets.UTF_8),\n    32\n);\n<\/textarea><\/pre><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" style=\"width:24px;height:24px\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" stroke-width=\"2\"><path class=\"with-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M4.5 12.75l6 6 9-13.5\"><\/path><path class=\"without-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M16.5 8.25V6a2.25 2.25 0 00-2.25-2.25H6A2.25 2.25 0 003.75 6v8.25A2.25 2.25 0 006 16.5h2.25m8.25-8.25H18a2.25 2.25 0 012.25 2.25V18A2.25 2.25 0 0118 20.25h-7.5A2.25 2.25 0 018.25 18v-1.5m8.25-8.25h-6a2.25 2.25 0 00-2.25 2.25v6\"><\/path><\/svg><\/span><pre class=\"shiki one-dark-pro\" style=\"background-color: #282c34\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color: #61AFEF\">\/\/<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">\u26a0\ufe0f<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">EDUCATIONAL\/TESTING<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">ONLY<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">-<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">NOT<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">FOR<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">PRODUCTION<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">\u26a0\ufe0f<\/span><\/span>\n<span class=\"line\"><span style=\"color: #61AFEF\">byte[]<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">masterKeyBytes<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">=<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">Arrays.copyOf<\/span><span style=\"color: #ABB2BF\">(<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">    <\/span><span style=\"color: #61AFEF\">&quot;your-plaintext-password-here&quot;<\/span><span style=\"color: #61AFEF\">.getBytes(StandardCharsets.UTF_8<\/span><span style=\"color: #ABB2BF\">)<\/span><span style=\"color: #98C379\">,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">    <\/span><span style=\"color: #61AFEF\">32<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">);<\/span><\/span>\n<span class=\"line\"><\/span><\/code><\/pre><\/div>\n\n\n\n<p class=\"sera-block-paragraph\"><strong>This is intentionally insecure to simplify the educational example.<\/strong><\/p>\n\n\n\n<p class=\"sera-block-paragraph\"><strong>For ANY deployment beyond local testing, you MUST<\/strong>:<\/p>\n\n\n\n<ol class=\"sera-block-list\">\n<li>Replace with KMS-based key management<\/li>\n\n\n\n<li>Use environment variables or secure vault for master key<\/li>\n\n\n\n<li>Implement proper key rotation<\/li>\n\n\n\n<li>Add salt to master key derivation<\/li>\n<\/ol>\n\n\n\n<p class=\"sera-block-paragraph\">Example production approach:<\/p>\n\n\n\n<div class=\"sera-block-kevinbatdorf-code-block-pro cbp-has-line-numbers\" data-code-block-pro-font-family=\"Code-Pro-JetBrains-Mono\" style=\"font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;--cbp-line-number-color:#abb2bf;--cbp-line-number-width:calc(2 * 0.6 * .875rem);line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)\"><span role=\"button\" tabindex=\"0\" style=\"color:#abb2bf;display:none\" aria-label=\"Copy\" class=\"code-block-pro-copy-button\"><pre class=\"code-block-pro-copy-button-pre\" aria-hidden=\"true\"><textarea class=\"code-block-pro-copy-button-textarea\" tabindex=\"-1\" aria-hidden=\"true\" readonly>\/\/ Production approach\nString masterKey = System.getenv(\"ENCRYPTION_MASTER_KEY\");\nif (masterKey == null) {\n    throw new IllegalStateException(\"ENCRYPTION_MASTER_KEY not set\");\n}\n\n\/\/ Derive key with salt (from KMS or secure storage)\nbyte[] salt = loadSaltFromSecureStorage();\nbyte[] masterKeyBytes = deriveKeyWithPBKDF2(masterKey, salt);\nAead masterKeyAead = new AesGcmJce(masterKeyBytes);\n<\/textarea><\/pre><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" style=\"width:24px;height:24px\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" stroke-width=\"2\"><path class=\"with-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M4.5 12.75l6 6 9-13.5\"><\/path><path class=\"without-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M16.5 8.25V6a2.25 2.25 0 00-2.25-2.25H6A2.25 2.25 0 003.75 6v8.25A2.25 2.25 0 006 16.5h2.25m8.25-8.25H18a2.25 2.25 0 012.25 2.25V18A2.25 2.25 0 0118 20.25h-7.5A2.25 2.25 0 018.25 18v-1.5m8.25-8.25h-6a2.25 2.25 0 00-2.25 2.25v6\"><\/path><\/svg><\/span><pre class=\"shiki one-dark-pro\" style=\"background-color: #282c34\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color: #61AFEF\">\/\/<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">Production<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">approach<\/span><\/span>\n<span class=\"line\"><span style=\"color: #61AFEF\">String<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">masterKey<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">=<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">System.getenv<\/span><span style=\"color: #ABB2BF\">(<\/span><span style=\"color: #61AFEF\">&quot;ENCRYPTION_MASTER_KEY&quot;<\/span><span style=\"color: #ABB2BF\">);<\/span><\/span>\n<span class=\"line\"><span style=\"color: #C678DD\">if<\/span><span style=\"color: #ABB2BF\"> (<\/span><span style=\"color: #61AFEF\">masterKey<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">==<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">null<\/span><span style=\"color: #ABB2BF\">) {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">    <\/span><span style=\"color: #61AFEF\">throw<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">new<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">IllegalStateException<\/span><span style=\"color: #ABB2BF\">(<\/span><span style=\"color: #61AFEF\">&quot;ENCRYPTION_MASTER_KEY not set&quot;<\/span><span style=\"color: #ABB2BF\">);<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">}<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #61AFEF\">\/\/<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">Derive<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">key<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">with<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">salt<\/span><span style=\"color: #ABB2BF\"> (from <\/span><span style=\"color: #98C379\">KMS<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">or<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">secure<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">storage<\/span><span style=\"color: #ABB2BF\">)<\/span><\/span>\n<span class=\"line\"><span style=\"color: #61AFEF\">byte[]<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">salt<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">=<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">loadSaltFromSecureStorage<\/span><span style=\"color: #ABB2BF\">();<\/span><\/span>\n<span class=\"line\"><span style=\"color: #61AFEF\">byte[]<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">masterKeyBytes<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">=<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">deriveKeyWithPBKDF2<\/span><span style=\"color: #ABB2BF\">(<\/span><span style=\"color: #61AFEF\">masterKey,<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">salt<\/span><span style=\"color: #ABB2BF\">);<\/span><\/span>\n<span class=\"line\"><span style=\"color: #61AFEF\">Aead<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">masterKeyAead<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">=<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">new<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">AesGcmJce<\/span><span style=\"color: #ABB2BF\">(<\/span><span style=\"color: #61AFEF\">masterKeyBytes<\/span><span style=\"color: #ABB2BF\">);<\/span><\/span>\n<span class=\"line\"><\/span><\/code><\/pre><\/div>\n\n\n\n<p class=\"sera-block-paragraph\"><\/p>\n\n\n\n<p class=\"sera-block-paragraph\"><strong>File Header Class<\/strong>:<\/p>\n\n\n\n<div class=\"sera-block-kevinbatdorf-code-block-pro cbp-has-line-numbers\" data-code-block-pro-font-family=\"Code-Pro-JetBrains-Mono\" style=\"font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;--cbp-line-number-color:#abb2bf;--cbp-line-number-width:calc(2 * 0.6 * .875rem);line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)\"><span role=\"button\" tabindex=\"0\" style=\"color:#abb2bf;display:none\" aria-label=\"Copy\" class=\"code-block-pro-copy-button\"><pre class=\"code-block-pro-copy-button-pre\" aria-hidden=\"true\"><textarea class=\"code-block-pro-copy-button-textarea\" tabindex=\"-1\" aria-hidden=\"true\" readonly>public static class FileHeader {\n    public final short version;      \/\/ Format version\n    public final int chunkSize;      \/\/ Chunk size in bytes\n    public final long originalSize;  \/\/ Original file size\n    \n    public int getTotalChunks() {\n        return (int) Math.ceil((double) originalSize \/ chunkSize);\n    }\n}\n<\/textarea><\/pre><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" style=\"width:24px;height:24px\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" stroke-width=\"2\"><path class=\"with-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M4.5 12.75l6 6 9-13.5\"><\/path><path class=\"without-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M16.5 8.25V6a2.25 2.25 0 00-2.25-2.25H6A2.25 2.25 0 003.75 6v8.25A2.25 2.25 0 006 16.5h2.25m8.25-8.25H18a2.25 2.25 0 012.25 2.25V18A2.25 2.25 0 0118 20.25h-7.5A2.25 2.25 0 018.25 18v-1.5m8.25-8.25h-6a2.25 2.25 0 00-2.25 2.25v6\"><\/path><\/svg><\/span><pre class=\"shiki one-dark-pro\" style=\"background-color: #282c34\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color: #61AFEF\">public<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">static<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">class<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">FileHeader<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">{<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">    <\/span><span style=\"color: #61AFEF\">public<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">final<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">short<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">version<\/span><span style=\"color: #ABB2BF\">;      <\/span><span style=\"color: #61AFEF\">\/\/<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">Format<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">version<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">    <\/span><span style=\"color: #61AFEF\">public<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">final<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">int<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">chunkSize<\/span><span style=\"color: #ABB2BF\">;      <\/span><span style=\"color: #61AFEF\">\/\/<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">Chunk<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">size<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">in<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">bytes<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">    <\/span><span style=\"color: #61AFEF\">public<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">final<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">long<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">originalSize<\/span><span style=\"color: #ABB2BF\">;  <\/span><span style=\"color: #61AFEF\">\/\/<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">Original<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">file<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">size<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">    <\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">    <\/span><span style=\"color: #61AFEF\">public<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">int<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">getTotalChunks<\/span><span style=\"color: #ABB2BF\">() <\/span><span style=\"color: #98C379\">{<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">        <\/span><span style=\"color: #C678DD\">return<\/span><span style=\"color: #ABB2BF\"> (int) Math.ceil((double) originalSize <\/span><span style=\"color: #56B6C2\">\/<\/span><span style=\"color: #ABB2BF\"> chunkSize);<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">    }<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">}<\/span><\/span>\n<span class=\"line\"><\/span><\/code><\/pre><\/div>\n\n\n\n<hr class=\"sera-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h3 class=\"sera-block-heading\">4. ChunkedEncryptedChannels<\/h3>\n\n\n\n<p class=\"sera-block-paragraph\"><strong>Location<\/strong>: ChunkedEncryptedChannels.java<\/p>\n\n\n\n<p class=\"sera-block-paragraph\">Contains two specialized SeekableByteChannel implementations:<\/p>\n\n\n\n<h3 class=\"sera-block-heading\">4.1. ChunkedReadChannel<\/h3>\n\n\n\n<p class=\"sera-block-paragraph\"><strong>Purpose<\/strong>: Random-access read operations with on-demand chunk decryption<\/p>\n\n\n\n<p class=\"sera-block-paragraph\"><strong>Features<\/strong>:<\/p>\n\n\n\n<ul class=\"sera-block-list\">\n<li>Single-chunk caching (current chunk kept in memory)<\/li>\n\n\n\n<li>Full seek support (position to any offset in file)<\/li>\n\n\n\n<li>Proper EOF handling (returns -1, not 0)<\/li>\n\n\n\n<li>Efficient for large files (only decrypts needed chunks)<\/li>\n\n\n\n<li>Memory efficient (~64KB overhead per open file)<\/li>\n<\/ul>\n\n\n\n<p class=\"sera-block-paragraph\"><strong>Read Algorithm<\/strong>:<\/p>\n\n\n\n<div class=\"sera-block-kevinbatdorf-code-block-pro cbp-has-line-numbers\" data-code-block-pro-font-family=\"Code-Pro-JetBrains-Mono\" style=\"font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;--cbp-line-number-color:#abb2bf;--cbp-line-number-width:calc(2 * 0.6 * .875rem);line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)\"><span role=\"button\" tabindex=\"0\" style=\"color:#abb2bf;display:none\" aria-label=\"Copy\" class=\"code-block-pro-copy-button\"><pre class=\"code-block-pro-copy-button-pre\" aria-hidden=\"true\"><textarea class=\"code-block-pro-copy-button-textarea\" tabindex=\"-1\" aria-hidden=\"true\" readonly>public int read(ByteBuffer dst) {\n    \/\/ 1. EOF check\n    if (position >= fileSize) return -1;\n    \n    \/\/ 2. Calculate chunk and offset\n    int chunkIndex = position \/ chunkSize;\n    int offsetInChunk = position % chunkSize;\n    \n    \/\/ 3. Load chunk if not cached\n    if (chunkIndex != currentChunkIndex) {\n        decryptAndCacheChunk(chunkIndex);\n    }\n    \n    \/\/ 4. Copy data from chunk to destination\n    int toRead = min(dst.remaining(), chunkData.length - offsetInChunk);\n    dst.put(chunkData, offsetInChunk, toRead);\n    \n    \/\/ 5. Update position\n    position += toRead;\n    \n    return toRead;\n}\n<\/textarea><\/pre><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" style=\"width:24px;height:24px\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" stroke-width=\"2\"><path class=\"with-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M4.5 12.75l6 6 9-13.5\"><\/path><path class=\"without-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M16.5 8.25V6a2.25 2.25 0 00-2.25-2.25H6A2.25 2.25 0 003.75 6v8.25A2.25 2.25 0 006 16.5h2.25m8.25-8.25H18a2.25 2.25 0 012.25 2.25V18A2.25 2.25 0 0118 20.25h-7.5A2.25 2.25 0 018.25 18v-1.5m8.25-8.25h-6a2.25 2.25 0 00-2.25 2.25v6\"><\/path><\/svg><\/span><pre class=\"shiki one-dark-pro\" style=\"background-color: #282c34\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color: #61AFEF\">public<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">int<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">read<\/span><span style=\"color: #ABB2BF\">(<\/span><span style=\"color: #61AFEF\">ByteBuffer<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">dst<\/span><span style=\"color: #ABB2BF\">) <\/span><span style=\"color: #98C379\">{<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">    <\/span><span style=\"color: #61AFEF\">\/\/<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #D19A66\">1<\/span><span style=\"color: #98C379\">.<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">EOF<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">check<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">    <\/span><span style=\"color: #C678DD\">if<\/span><span style=\"color: #ABB2BF\"> (<\/span><span style=\"color: #61AFEF\">position<\/span><span style=\"color: #ABB2BF\"> &gt;<\/span><span style=\"color: #98C379\">=<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">fileSize<\/span><span style=\"color: #ABB2BF\">) <\/span><span style=\"color: #C678DD\">return<\/span><span style=\"color: #ABB2BF\"> -1;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">    <\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">    <\/span><span style=\"color: #61AFEF\">\/\/<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #D19A66\">2<\/span><span style=\"color: #98C379\">.<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">Calculate<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">chunk<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">and<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">offset<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">    <\/span><span style=\"color: #61AFEF\">int<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">chunkIndex<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">=<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">position<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">\/<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">chunkSize<\/span><span style=\"color: #ABB2BF\">;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">    <\/span><span style=\"color: #61AFEF\">int<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">offsetInChunk<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">=<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">position<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">%<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">chunkSize<\/span><span style=\"color: #ABB2BF\">;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">    <\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">    <\/span><span style=\"color: #61AFEF\">\/\/<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #D19A66\">3<\/span><span style=\"color: #98C379\">.<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">Load<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">chunk<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">if<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">not<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">cached<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">    <\/span><span style=\"color: #C678DD\">if<\/span><span style=\"color: #ABB2BF\"> (<\/span><span style=\"color: #61AFEF\">chunkIndex<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">!=<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">currentChunkIndex<\/span><span style=\"color: #ABB2BF\">) {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">        <\/span><span style=\"color: #61AFEF\">decryptAndCacheChunk(chunkIndex<\/span><span style=\"color: #ABB2BF\">);<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">    }<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">    <\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">    <\/span><span style=\"color: #61AFEF\">\/\/<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #D19A66\">4<\/span><span style=\"color: #98C379\">.<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">Copy<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">data<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">from<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">chunk<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">to<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">destination<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">    <\/span><span style=\"color: #61AFEF\">int<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">toRead<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">=<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">min<\/span><span style=\"color: #ABB2BF\">(<\/span><span style=\"color: #61AFEF\">dst.remaining<\/span><span style=\"color: #ABB2BF\">(), chunkData.length - offsetInChunk);<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">    <\/span><span style=\"color: #61AFEF\">dst.put(chunkData,<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">offsetInChunk,<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">toRead<\/span><span style=\"color: #ABB2BF\">);<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">    <\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">    <\/span><span style=\"color: #61AFEF\">\/\/<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #D19A66\">5<\/span><span style=\"color: #98C379\">.<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">Update<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">position<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">    <\/span><span style=\"color: #61AFEF\">position<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">+=<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">toRead<\/span><span style=\"color: #ABB2BF\">;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">    <\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">    <\/span><span style=\"color: #C678DD\">return<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">toRead<\/span><span style=\"color: #ABB2BF\">;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">}<\/span><\/span>\n<span class=\"line\"><\/span><\/code><\/pre><\/div>\n\n\n\n<p class=\"sera-block-paragraph\"><\/p>\n\n\n\n<p class=\"sera-block-paragraph\"><strong>Seek Implementation<\/strong>:<\/p>\n\n\n\n<div class=\"sera-block-kevinbatdorf-code-block-pro cbp-has-line-numbers\" data-code-block-pro-font-family=\"Code-Pro-JetBrains-Mono\" style=\"font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;--cbp-line-number-color:#abb2bf;--cbp-line-number-width:calc(1 * 0.6 * .875rem);line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)\"><span role=\"button\" tabindex=\"0\" style=\"color:#abb2bf;display:none\" aria-label=\"Copy\" class=\"code-block-pro-copy-button\"><pre class=\"code-block-pro-copy-button-pre\" aria-hidden=\"true\"><textarea class=\"code-block-pro-copy-button-textarea\" tabindex=\"-1\" aria-hidden=\"true\" readonly>public SeekableByteChannel position(long newPosition) {\n    if (newPosition &lt; 0 || newPosition > fileSize) {\n        throw new IllegalArgumentException(\"Invalid position\");\n    }\n    position = newPosition;\n    return this;\n}\n<\/textarea><\/pre><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" style=\"width:24px;height:24px\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" stroke-width=\"2\"><path class=\"with-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M4.5 12.75l6 6 9-13.5\"><\/path><path class=\"without-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M16.5 8.25V6a2.25 2.25 0 00-2.25-2.25H6A2.25 2.25 0 003.75 6v8.25A2.25 2.25 0 006 16.5h2.25m8.25-8.25H18a2.25 2.25 0 012.25 2.25V18A2.25 2.25 0 0118 20.25h-7.5A2.25 2.25 0 018.25 18v-1.5m8.25-8.25h-6a2.25 2.25 0 00-2.25 2.25v6\"><\/path><\/svg><\/span><pre class=\"shiki one-dark-pro\" style=\"background-color: #282c34\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color: #61AFEF\">public<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">SeekableByteChannel<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">position<\/span><span style=\"color: #ABB2BF\">(<\/span><span style=\"color: #61AFEF\">long<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">newPosition<\/span><span style=\"color: #ABB2BF\">) <\/span><span style=\"color: #98C379\">{<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">    <\/span><span style=\"color: #C678DD\">if<\/span><span style=\"color: #ABB2BF\"> (<\/span><span style=\"color: #61AFEF\">newPosition<\/span><span style=\"color: #ABB2BF\"> &lt; <\/span><span style=\"color: #D19A66\">0<\/span><span style=\"color: #ABB2BF\"> || <\/span><span style=\"color: #61AFEF\">newPosition<\/span><span style=\"color: #ABB2BF\"> &gt; <\/span><span style=\"color: #98C379\">fileSize<\/span><span style=\"color: #ABB2BF\">) {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">        <\/span><span style=\"color: #61AFEF\">throw<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">new<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">IllegalArgumentException<\/span><span style=\"color: #ABB2BF\">(<\/span><span style=\"color: #61AFEF\">&quot;Invalid position&quot;<\/span><span style=\"color: #ABB2BF\">);<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">    }<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">    <\/span><span style=\"color: #61AFEF\">position<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">=<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">newPosition<\/span><span style=\"color: #ABB2BF\">;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">    <\/span><span style=\"color: #C678DD\">return<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">this<\/span><span style=\"color: #ABB2BF\">;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">}<\/span><\/span>\n<span class=\"line\"><\/span><\/code><\/pre><\/div>\n\n\n\n<p class=\"sera-block-paragraph\"><\/p>\n\n\n\n<p class=\"sera-block-paragraph\"><strong>Critical EOF Handling<\/strong>:<\/p>\n\n\n\n<div class=\"sera-block-kevinbatdorf-code-block-pro cbp-has-line-numbers\" data-code-block-pro-font-family=\"Code-Pro-JetBrains-Mono\" style=\"font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;--cbp-line-number-color:#abb2bf;--cbp-line-number-width:calc(1 * 0.6 * .875rem);line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)\"><span role=\"button\" tabindex=\"0\" style=\"color:#abb2bf;display:none\" aria-label=\"Copy\" class=\"code-block-pro-copy-button\"><pre class=\"code-block-pro-copy-button-pre\" aria-hidden=\"true\"><textarea class=\"code-block-pro-copy-button-textarea\" tabindex=\"-1\" aria-hidden=\"true\" readonly>\/\/ CRITICAL: Return -1 (not 0) when at EOF\n\/\/ SSHD interprets:\n\/\/   0  = \"try again later\" (leads to infinite loop)\n\/\/   -1 = \"end of stream\" (correct termination)\n\nif (position >= fileSize) {\n    return -1;  \/\/ Proper EOF signal\n}\n<\/textarea><\/pre><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" style=\"width:24px;height:24px\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" stroke-width=\"2\"><path class=\"with-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M4.5 12.75l6 6 9-13.5\"><\/path><path class=\"without-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M16.5 8.25V6a2.25 2.25 0 00-2.25-2.25H6A2.25 2.25 0 003.75 6v8.25A2.25 2.25 0 006 16.5h2.25m8.25-8.25H18a2.25 2.25 0 012.25 2.25V18A2.25 2.25 0 0118 20.25h-7.5A2.25 2.25 0 018.25 18v-1.5m8.25-8.25h-6a2.25 2.25 0 00-2.25 2.25v6\"><\/path><\/svg><\/span><pre class=\"shiki one-dark-pro\" style=\"background-color: #282c34\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color: #61AFEF\">\/\/<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">CRITICAL:<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">Return<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #D19A66\">-1<\/span><span style=\"color: #ABB2BF\"> (not <\/span><span style=\"color: #D19A66\">0<\/span><span style=\"color: #ABB2BF\">) when at EOF<\/span><\/span>\n<span class=\"line\"><span style=\"color: #61AFEF\">\/\/<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">SSHD<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">interprets:<\/span><\/span>\n<span class=\"line\"><span style=\"color: #61AFEF\">\/\/<\/span><span style=\"color: #ABB2BF\">   <\/span><span style=\"color: #D19A66\">0<\/span><span style=\"color: #ABB2BF\">  <\/span><span style=\"color: #98C379\">=<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">&quot;try again later&quot;<\/span><span style=\"color: #ABB2BF\"> (leads <\/span><span style=\"color: #98C379\">to<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">infinite<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">loop<\/span><span style=\"color: #ABB2BF\">)<\/span><\/span>\n<span class=\"line\"><span style=\"color: #61AFEF\">\/\/<\/span><span style=\"color: #ABB2BF\">   <\/span><span style=\"color: #D19A66\">-1<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">=<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">&quot;end of stream&quot;<\/span><span style=\"color: #ABB2BF\"> (correct <\/span><span style=\"color: #98C379\">termination<\/span><span style=\"color: #ABB2BF\">)<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #C678DD\">if<\/span><span style=\"color: #ABB2BF\"> (<\/span><span style=\"color: #61AFEF\">position<\/span><span style=\"color: #ABB2BF\"> &gt;<\/span><span style=\"color: #98C379\">=<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">fileSize<\/span><span style=\"color: #ABB2BF\">) {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">    <\/span><span style=\"color: #C678DD\">return<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #D19A66\">-1<\/span><span style=\"color: #ABB2BF\">;  <\/span><span style=\"color: #61AFEF\">\/\/<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">Proper<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">EOF<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">signal<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">}<\/span><\/span>\n<span class=\"line\"><\/span><\/code><\/pre><\/div>\n\n\n\n<p class=\"sera-block-paragraph\"><\/p>\n\n\n\n<p class=\"sera-block-paragraph\"><strong>Example Usage Pattern<\/strong> (internal):<\/p>\n\n\n\n<div class=\"sera-block-kevinbatdorf-code-block-pro cbp-has-line-numbers\" data-code-block-pro-font-family=\"Code-Pro-JetBrains-Mono\" style=\"font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;--cbp-line-number-color:#abb2bf;--cbp-line-number-width:calc(2 * 0.6 * .875rem);line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)\"><span role=\"button\" tabindex=\"0\" style=\"color:#abb2bf;display:none\" aria-label=\"Copy\" class=\"code-block-pro-copy-button\"><pre class=\"code-block-pro-copy-button-pre\" aria-hidden=\"true\"><textarea class=\"code-block-pro-copy-button-textarea\" tabindex=\"-1\" aria-hidden=\"true\" readonly>ChunkedReadChannel channel = new ChunkedReadChannel(\n    encryptedFile, \n    \"document.pdf\", \n    cryptoService\n);\n\nByteBuffer buffer = ByteBuffer.allocate(8192);\nwhile (channel.read(buffer) != -1) {\n    buffer.flip();\n    \/\/ Process data\n    buffer.clear();\n}\nchannel.close();\n<\/textarea><\/pre><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" style=\"width:24px;height:24px\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" stroke-width=\"2\"><path class=\"with-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M4.5 12.75l6 6 9-13.5\"><\/path><path class=\"without-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M16.5 8.25V6a2.25 2.25 0 00-2.25-2.25H6A2.25 2.25 0 003.75 6v8.25A2.25 2.25 0 006 16.5h2.25m8.25-8.25H18a2.25 2.25 0 012.25 2.25V18A2.25 2.25 0 0118 20.25h-7.5A2.25 2.25 0 018.25 18v-1.5m8.25-8.25h-6a2.25 2.25 0 00-2.25 2.25v6\"><\/path><\/svg><\/span><pre class=\"shiki one-dark-pro\" style=\"background-color: #282c34\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color: #61AFEF\">ChunkedReadChannel<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">channel<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">=<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">new<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">ChunkedReadChannel<\/span><span style=\"color: #ABB2BF\">(<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">    <\/span><span style=\"color: #61AFEF\">encryptedFile,<\/span><span style=\"color: #ABB2BF\"> <\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">    <\/span><span style=\"color: #61AFEF\">&quot;document.pdf&quot;<\/span><span style=\"color: #61AFEF\">,<\/span><span style=\"color: #ABB2BF\"> <\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">    <\/span><span style=\"color: #61AFEF\">cryptoService<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">);<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #61AFEF\">ByteBuffer<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">buffer<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">=<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">ByteBuffer.allocate<\/span><span style=\"color: #ABB2BF\">(<\/span><span style=\"color: #61AFEF\">8192<\/span><span style=\"color: #ABB2BF\">);<\/span><\/span>\n<span class=\"line\"><span style=\"color: #C678DD\">while<\/span><span style=\"color: #ABB2BF\"> (<\/span><span style=\"color: #61AFEF\">channel.read(buffer<\/span><span style=\"color: #ABB2BF\">) != <\/span><span style=\"color: #D19A66\">-1<\/span><span style=\"color: #ABB2BF\">) {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">    <\/span><span style=\"color: #61AFEF\">buffer.flip<\/span><span style=\"color: #ABB2BF\">();<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">    <\/span><span style=\"color: #61AFEF\">\/\/<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">Process<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">data<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">    <\/span><span style=\"color: #61AFEF\">buffer.clear<\/span><span style=\"color: #ABB2BF\">();<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">}<\/span><\/span>\n<span class=\"line\"><span style=\"color: #61AFEF\">channel.close<\/span><span style=\"color: #ABB2BF\">();<\/span><\/span>\n<span class=\"line\"><\/span><\/code><\/pre><\/div>\n\n\n\n<h3 class=\"sera-block-heading\">4.2. ChunkedWriteChannel<\/h3>\n\n\n\n<p class=\"sera-block-paragraph\"><strong>Purpose<\/strong>: Sequential write operations with automatic chunk encryption<\/p>\n\n\n\n<p class=\"sera-block-paragraph\"><strong>Features<\/strong>:<\/p>\n\n\n\n<ul class=\"sera-block-list\">\n<li>Write buffering (accumulates data until chunk size)<\/li>\n\n\n\n<li>Automatic flush on chunk boundary<\/li>\n\n\n\n<li>Header creation and updates<\/li>\n\n\n\n<li>Sequential write only (no backward seeking)<\/li>\n\n\n\n<li>Efficient memory usage<\/li>\n<\/ul>\n\n\n\n<p class=\"sera-block-paragraph\"><strong>Write Algorithm<\/strong>:<\/p>\n\n\n\n<div class=\"sera-block-kevinbatdorf-code-block-pro cbp-has-line-numbers\" data-code-block-pro-font-family=\"Code-Pro-JetBrains-Mono\" style=\"font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;--cbp-line-number-color:#abb2bf;--cbp-line-number-width:calc(2 * 0.6 * .875rem);line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)\"><span role=\"button\" tabindex=\"0\" style=\"color:#abb2bf;display:none\" aria-label=\"Copy\" class=\"code-block-pro-copy-button\"><pre class=\"code-block-pro-copy-button-pre\" aria-hidden=\"true\"><textarea class=\"code-block-pro-copy-button-textarea\" tabindex=\"-1\" aria-hidden=\"true\" readonly>public int write(ByteBuffer src) {\n    int totalWritten = 0;\n    \n    while (src.hasRemaining()) {\n        \/\/ 1. Copy to buffer\n        int toBuffer = min(src.remaining(), chunkSize - buffer.size());\n        buffer.write(src, toBuffer);\n        totalWritten += toBuffer;\n        \n        \/\/ 2. Flush if buffer full\n        if (buffer.size() >= chunkSize) {\n            encryptAndFlushChunk(false);\n        }\n    }\n    \n    return totalWritten;\n}\n<\/textarea><\/pre><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" style=\"width:24px;height:24px\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" stroke-width=\"2\"><path class=\"with-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M4.5 12.75l6 6 9-13.5\"><\/path><path class=\"without-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M16.5 8.25V6a2.25 2.25 0 00-2.25-2.25H6A2.25 2.25 0 003.75 6v8.25A2.25 2.25 0 006 16.5h2.25m8.25-8.25H18a2.25 2.25 0 012.25 2.25V18A2.25 2.25 0 0118 20.25h-7.5A2.25 2.25 0 018.25 18v-1.5m8.25-8.25h-6a2.25 2.25 0 00-2.25 2.25v6\"><\/path><\/svg><\/span><pre class=\"shiki one-dark-pro\" style=\"background-color: #282c34\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color: #61AFEF\">public<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">int<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">write<\/span><span style=\"color: #ABB2BF\">(<\/span><span style=\"color: #61AFEF\">ByteBuffer<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">src<\/span><span style=\"color: #ABB2BF\">) <\/span><span style=\"color: #98C379\">{<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">    <\/span><span style=\"color: #61AFEF\">int<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">totalWritten<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">=<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #D19A66\">0<\/span><span style=\"color: #ABB2BF\">;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">    <\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">    <\/span><span style=\"color: #C678DD\">while<\/span><span style=\"color: #ABB2BF\"> (<\/span><span style=\"color: #61AFEF\">src.hasRemaining<\/span><span style=\"color: #ABB2BF\">()) {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">        <\/span><span style=\"color: #61AFEF\">\/\/<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #D19A66\">1<\/span><span style=\"color: #98C379\">.<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">Copy<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">to<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">buffer<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">        <\/span><span style=\"color: #61AFEF\">int<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">toBuffer<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">=<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">min<\/span><span style=\"color: #ABB2BF\">(<\/span><span style=\"color: #61AFEF\">src.remaining<\/span><span style=\"color: #ABB2BF\">(), chunkSize - <\/span><span style=\"color: #61AFEF\">buffer.size<\/span><span style=\"color: #ABB2BF\">());<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">        <\/span><span style=\"color: #61AFEF\">buffer.write(src,<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">toBuffer<\/span><span style=\"color: #ABB2BF\">);<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">        <\/span><span style=\"color: #61AFEF\">totalWritten<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">+=<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">toBuffer<\/span><span style=\"color: #ABB2BF\">;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">        <\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">        <\/span><span style=\"color: #61AFEF\">\/\/<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #D19A66\">2<\/span><span style=\"color: #98C379\">.<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">Flush<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">if<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">buffer<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">full<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">        <\/span><span style=\"color: #C678DD\">if<\/span><span style=\"color: #ABB2BF\"> (<\/span><span style=\"color: #61AFEF\">buffer.size<\/span><span style=\"color: #ABB2BF\">() &gt;= chunkSize) {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">            <\/span><span style=\"color: #61AFEF\">encryptAndFlushChunk(false<\/span><span style=\"color: #ABB2BF\">);<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">        }<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">    }<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">    <\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">    <\/span><span style=\"color: #C678DD\">return<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">totalWritten<\/span><span style=\"color: #ABB2BF\">;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">}<\/span><\/span>\n<span class=\"line\"><\/span><\/code><\/pre><\/div>\n\n\n\n<p class=\"sera-block-paragraph\"><\/p>\n\n\n\n<p class=\"sera-block-paragraph\"><\/p>\n\n\n\n<p class=\"sera-block-paragraph\"><strong>Chunk Flush Process<\/strong>:<\/p>\n\n\n\n<div class=\"sera-block-kevinbatdorf-code-block-pro cbp-has-line-numbers\" data-code-block-pro-font-family=\"Code-Pro-JetBrains-Mono\" style=\"font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;--cbp-line-number-color:#abb2bf;--cbp-line-number-width:calc(2 * 0.6 * .875rem);line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)\"><span role=\"button\" tabindex=\"0\" style=\"color:#abb2bf;display:none\" aria-label=\"Copy\" class=\"code-block-pro-copy-button\"><pre class=\"code-block-pro-copy-button-pre\" aria-hidden=\"true\"><textarea class=\"code-block-pro-copy-button-textarea\" tabindex=\"-1\" aria-hidden=\"true\" readonly>private void flushChunk(boolean isFinal) {\n    \/\/ 1. Get buffered data\n    byte[] plaintext = buffer.toByteArray();\n    \n    \/\/ 2. Encrypt chunk\n    String aad = filename + \":chunk:\" + chunkIndex;\n    byte[] encrypted = crypto.encryptChunk(plaintext, filename, chunkIndex);\n    \n    \/\/ 3. Write to disk: &#91;size&#93;&#91;data&#93;\n    writeInt(output, encrypted.length);\n    output.write(encrypted);\n    \n    \/\/ 4. Reset buffer\n    buffer.reset();\n    chunkIndex++;\n}\n<\/textarea><\/pre><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" style=\"width:24px;height:24px\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" stroke-width=\"2\"><path class=\"with-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M4.5 12.75l6 6 9-13.5\"><\/path><path class=\"without-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M16.5 8.25V6a2.25 2.25 0 00-2.25-2.25H6A2.25 2.25 0 003.75 6v8.25A2.25 2.25 0 006 16.5h2.25m8.25-8.25H18a2.25 2.25 0 012.25 2.25V18A2.25 2.25 0 0118 20.25h-7.5A2.25 2.25 0 018.25 18v-1.5m8.25-8.25h-6a2.25 2.25 0 00-2.25 2.25v6\"><\/path><\/svg><\/span><pre class=\"shiki one-dark-pro\" style=\"background-color: #282c34\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color: #61AFEF\">private<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">void<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">flushChunk<\/span><span style=\"color: #ABB2BF\">(<\/span><span style=\"color: #61AFEF\">boolean<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">isFinal<\/span><span style=\"color: #ABB2BF\">) <\/span><span style=\"color: #98C379\">{<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">    <\/span><span style=\"color: #61AFEF\">\/\/<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #D19A66\">1<\/span><span style=\"color: #98C379\">.<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">Get<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">buffered<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">data<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">    <\/span><span style=\"color: #61AFEF\">byte[]<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">plaintext<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">=<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">buffer.toByteArray<\/span><span style=\"color: #ABB2BF\">();<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">    <\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">    <\/span><span style=\"color: #61AFEF\">\/\/<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #D19A66\">2<\/span><span style=\"color: #98C379\">.<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">Encrypt<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">chunk<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">    <\/span><span style=\"color: #61AFEF\">String<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">aad<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">=<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">filename<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">+<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">&quot;:chunk:&quot;<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">+<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">chunkIndex<\/span><span style=\"color: #ABB2BF\">;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">    <\/span><span style=\"color: #61AFEF\">byte[]<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">encrypted<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">=<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">crypto.encryptChunk<\/span><span style=\"color: #ABB2BF\">(<\/span><span style=\"color: #61AFEF\">plaintext,<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">filename,<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">chunkIndex<\/span><span style=\"color: #ABB2BF\">);<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">    <\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">    <\/span><span style=\"color: #61AFEF\">\/\/<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #D19A66\">3<\/span><span style=\"color: #98C379\">.<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">Write<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">to<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">disk:<\/span><span style=\"color: #ABB2BF\"> &#91;size&#93;&#91;data&#93;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">    <\/span><span style=\"color: #61AFEF\">writeInt(output,<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">encrypted.length<\/span><span style=\"color: #ABB2BF\">);<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">    <\/span><span style=\"color: #61AFEF\">output.write(encrypted<\/span><span style=\"color: #ABB2BF\">);<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">    <\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">    <\/span><span style=\"color: #61AFEF\">\/\/<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #D19A66\">4<\/span><span style=\"color: #98C379\">.<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">Reset<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">buffer<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">    <\/span><span style=\"color: #61AFEF\">buffer.reset<\/span><span style=\"color: #ABB2BF\">();<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">    <\/span><span style=\"color: #61AFEF\">chunkIndex++<\/span><span style=\"color: #ABB2BF\">;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">}<\/span><\/span>\n<span class=\"line\"><\/span><\/code><\/pre><\/div>\n\n\n\n<p class=\"sera-block-paragraph\"><\/p>\n\n\n\n<p class=\"sera-block-paragraph\"><strong>Position Management<\/strong>:<\/p>\n\n\n\n<div class=\"sera-block-kevinbatdorf-code-block-pro cbp-has-line-numbers\" data-code-block-pro-font-family=\"Code-Pro-JetBrains-Mono\" style=\"font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;--cbp-line-number-color:#abb2bf;--cbp-line-number-width:calc(2 * 0.6 * .875rem);line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)\"><span role=\"button\" tabindex=\"0\" style=\"color:#abb2bf;display:none\" aria-label=\"Copy\" class=\"code-block-pro-copy-button\"><pre class=\"code-block-pro-copy-button-pre\" aria-hidden=\"true\"><textarea class=\"code-block-pro-copy-button-textarea\" tabindex=\"-1\" aria-hidden=\"true\" readonly>public SeekableByteChannel position(long newPosition) {\n    if (newPosition == totalBytesWritten) {\n        return this;  \/\/ No-op\n    }\n    \n    if (newPosition &lt; totalBytesWritten) {\n        throw new IOException(\"Cannot seek backwards in write channel\");\n    }\n    \n    \/\/ Forward seek: fill with zeros\n    long gap = newPosition - totalBytesWritten;\n    byte[] zeros = new byte&#91;(int) min(gap, 8192)&#93;;\n    ByteBuffer zeroBuf = ByteBuffer.wrap(zeros);\n    while (gap > 0) {\n        int toWrite = (int) min(gap, zeros.length);\n        zeroBuf.limit(toWrite);\n        write(zeroBuf);\n        gap -= toWrite;\n        zeroBuf.clear();\n    }\n    \n    return this;\n}\n<\/textarea><\/pre><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" style=\"width:24px;height:24px\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" stroke-width=\"2\"><path class=\"with-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M4.5 12.75l6 6 9-13.5\"><\/path><path class=\"without-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M16.5 8.25V6a2.25 2.25 0 00-2.25-2.25H6A2.25 2.25 0 003.75 6v8.25A2.25 2.25 0 006 16.5h2.25m8.25-8.25H18a2.25 2.25 0 012.25 2.25V18A2.25 2.25 0 0118 20.25h-7.5A2.25 2.25 0 018.25 18v-1.5m8.25-8.25h-6a2.25 2.25 0 00-2.25 2.25v6\"><\/path><\/svg><\/span><pre class=\"shiki one-dark-pro\" style=\"background-color: #282c34\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color: #61AFEF\">public<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">SeekableByteChannel<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">position<\/span><span style=\"color: #ABB2BF\">(<\/span><span style=\"color: #61AFEF\">long<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">newPosition<\/span><span style=\"color: #ABB2BF\">) <\/span><span style=\"color: #98C379\">{<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">    <\/span><span style=\"color: #C678DD\">if<\/span><span style=\"color: #ABB2BF\"> (<\/span><span style=\"color: #61AFEF\">newPosition<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">==<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">totalBytesWritten<\/span><span style=\"color: #ABB2BF\">) {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">        <\/span><span style=\"color: #C678DD\">return<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">this<\/span><span style=\"color: #ABB2BF\">;  <\/span><span style=\"color: #61AFEF\">\/\/<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">No-op<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">    }<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">    <\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">    <\/span><span style=\"color: #C678DD\">if<\/span><span style=\"color: #ABB2BF\"> (<\/span><span style=\"color: #61AFEF\">newPosition<\/span><span style=\"color: #ABB2BF\"> &lt; <\/span><span style=\"color: #98C379\">totalBytesWritten<\/span><span style=\"color: #ABB2BF\">) {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">        <\/span><span style=\"color: #61AFEF\">throw<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">new<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">IOException<\/span><span style=\"color: #ABB2BF\">(<\/span><span style=\"color: #61AFEF\">&quot;Cannot seek backwards in write channel&quot;<\/span><span style=\"color: #ABB2BF\">);<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">    }<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">    <\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">    <\/span><span style=\"color: #61AFEF\">\/\/<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">Forward<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">seek:<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">fill<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">with<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">zeros<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">    <\/span><span style=\"color: #61AFEF\">long<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">gap<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">=<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">newPosition<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">-<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">totalBytesWritten<\/span><span style=\"color: #ABB2BF\">;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">    <\/span><span style=\"color: #61AFEF\">byte[]<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">zeros<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">=<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">new<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">byte&#91;<\/span><span style=\"color: #ABB2BF\">(<\/span><span style=\"color: #61AFEF\">int<\/span><span style=\"color: #ABB2BF\">) <\/span><span style=\"color: #98C379\">min<\/span><span style=\"color: #ABB2BF\">(<\/span><span style=\"color: #61AFEF\">gap,<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #D19A66\">8192<\/span><span style=\"color: #ABB2BF\">)<\/span><span style=\"color: #98C379\">&#93;<\/span><span style=\"color: #ABB2BF\">;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">    <\/span><span style=\"color: #61AFEF\">ByteBuffer<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">zeroBuf<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">=<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">ByteBuffer.wrap<\/span><span style=\"color: #ABB2BF\">(<\/span><span style=\"color: #61AFEF\">zeros<\/span><span style=\"color: #ABB2BF\">);<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">    <\/span><span style=\"color: #C678DD\">while<\/span><span style=\"color: #ABB2BF\"> (<\/span><span style=\"color: #61AFEF\">gap<\/span><span style=\"color: #ABB2BF\"> &gt; <\/span><span style=\"color: #D19A66\">0<\/span><span style=\"color: #ABB2BF\">) {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">        <\/span><span style=\"color: #61AFEF\">int<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">toWrite<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">=<\/span><span style=\"color: #ABB2BF\"> (int) min(<\/span><span style=\"color: #61AFEF\">gap,<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">zeros.length<\/span><span style=\"color: #ABB2BF\">);<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">        <\/span><span style=\"color: #61AFEF\">zeroBuf.limit(toWrite<\/span><span style=\"color: #ABB2BF\">);<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">        <\/span><span style=\"color: #61AFEF\">write(zeroBuf<\/span><span style=\"color: #ABB2BF\">);<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">        <\/span><span style=\"color: #61AFEF\">gap<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #D19A66\">-=<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">toWrite<\/span><span style=\"color: #ABB2BF\">;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">        <\/span><span style=\"color: #61AFEF\">zeroBuf.clear<\/span><span style=\"color: #ABB2BF\">();<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">    }<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">    <\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">    <\/span><span style=\"color: #C678DD\">return<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">this<\/span><span style=\"color: #ABB2BF\">;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">}<\/span><\/span>\n<span class=\"line\"><\/span><\/code><\/pre><\/div>\n\n\n\n<p class=\"sera-block-paragraph\"><\/p>\n\n\n\n<p class=\"sera-block-paragraph\"><strong>Close and Finalization<\/strong>:<\/p>\n\n\n\n<div class=\"sera-block-kevinbatdorf-code-block-pro cbp-has-line-numbers\" data-code-block-pro-font-family=\"Code-Pro-JetBrains-Mono\" style=\"font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;--cbp-line-number-color:#abb2bf;--cbp-line-number-width:calc(2 * 0.6 * .875rem);line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)\"><span role=\"button\" tabindex=\"0\" style=\"color:#abb2bf;display:none\" aria-label=\"Copy\" class=\"code-block-pro-copy-button\"><pre class=\"code-block-pro-copy-button-pre\" aria-hidden=\"true\"><textarea class=\"code-block-pro-copy-button-textarea\" tabindex=\"-1\" aria-hidden=\"true\" readonly>public void close() {\n    \/\/ 1. Flush any remaining data\n    flushChunk(true);\n    \n    \/\/ 2. Update header with final file size\n    updateHeaderSize();\n    \n    \/\/ 3. Close underlying file\n    fileOutput.close();\n}\n\nprivate void updateHeaderSize() {\n    \/\/ Seek to size field in header (offset 10)\n    RandomAccessFile raf = new RandomAccessFile(file, \"rw\");\n    raf.seek(10);\n    writeLong(raf, totalBytesWritten);\n    raf.close();\n}\n<\/textarea><\/pre><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" style=\"width:24px;height:24px\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" stroke-width=\"2\"><path class=\"with-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M4.5 12.75l6 6 9-13.5\"><\/path><path class=\"without-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M16.5 8.25V6a2.25 2.25 0 00-2.25-2.25H6A2.25 2.25 0 003.75 6v8.25A2.25 2.25 0 006 16.5h2.25m8.25-8.25H18a2.25 2.25 0 012.25 2.25V18A2.25 2.25 0 0118 20.25h-7.5A2.25 2.25 0 018.25 18v-1.5m8.25-8.25h-6a2.25 2.25 0 00-2.25 2.25v6\"><\/path><\/svg><\/span><pre class=\"shiki one-dark-pro\" style=\"background-color: #282c34\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color: #61AFEF\">public<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">void<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">close<\/span><span style=\"color: #ABB2BF\">() <\/span><span style=\"color: #98C379\">{<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">    <\/span><span style=\"color: #61AFEF\">\/\/<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #D19A66\">1<\/span><span style=\"color: #98C379\">.<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">Flush<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">any<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">remaining<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">data<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">    <\/span><span style=\"color: #61AFEF\">flushChunk(true<\/span><span style=\"color: #ABB2BF\">);<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">    <\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">    <\/span><span style=\"color: #61AFEF\">\/\/<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #D19A66\">2<\/span><span style=\"color: #98C379\">.<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">Update<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">header<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">with<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">final<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">file<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">size<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">    <\/span><span style=\"color: #61AFEF\">updateHeaderSize<\/span><span style=\"color: #ABB2BF\">();<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">    <\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">    <\/span><span style=\"color: #61AFEF\">\/\/<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #D19A66\">3<\/span><span style=\"color: #98C379\">.<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">Close<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">underlying<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">file<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">    <\/span><span style=\"color: #61AFEF\">fileOutput.close<\/span><span style=\"color: #ABB2BF\">();<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">}<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #61AFEF\">private<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">void<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">updateHeaderSize<\/span><span style=\"color: #ABB2BF\">() <\/span><span style=\"color: #98C379\">{<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">    <\/span><span style=\"color: #61AFEF\">\/\/<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">Seek<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">to<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">size<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">field<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">in<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">header<\/span><span style=\"color: #ABB2BF\"> (offset <\/span><span style=\"color: #D19A66\">10<\/span><span style=\"color: #ABB2BF\">)<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">    <\/span><span style=\"color: #61AFEF\">RandomAccessFile<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">raf<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">=<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">new<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">RandomAccessFile<\/span><span style=\"color: #ABB2BF\">(<\/span><span style=\"color: #61AFEF\">file,<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">&quot;rw&quot;<\/span><span style=\"color: #ABB2BF\">);<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">    <\/span><span style=\"color: #61AFEF\">raf.seek(10<\/span><span style=\"color: #ABB2BF\">);<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">    <\/span><span style=\"color: #61AFEF\">writeLong(raf,<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">totalBytesWritten<\/span><span style=\"color: #ABB2BF\">);<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">    <\/span><span style=\"color: #61AFEF\">raf.close<\/span><span style=\"color: #ABB2BF\">();<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">}<\/span><\/span>\n<span class=\"line\"><\/span><\/code><\/pre><\/div>\n\n\n\n<hr class=\"sera-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h3 class=\"sera-block-heading\">5. EncryptedSftpEventListener<\/h3>\n\n\n\n<p class=\"sera-block-paragraph\"><strong>Location<\/strong>: <code>EncryptedSftpEventListener.java<\/code><\/p>\n\n\n\n<p class=\"sera-block-paragraph\"><strong>Purpose<\/strong>: User-friendly logging and event monitoring<\/p>\n\n\n\n<p class=\"sera-block-paragraph\"><strong>Interface<\/strong>: Implements <code>SftpEventListener<\/code> from Apache MINA SSHD<\/p>\n\n\n\n<p class=\"sera-block-paragraph\"><strong>Events Tracked<\/strong>:<\/p>\n\n\n\n<figure class=\"sera-block-table\"><table class=\"has-fixed-layout\"><thead><tr><th>Event<\/th><th>Description<\/th><th>Example Log<\/th><\/tr><\/thead><tbody><tr><td>opening<\/td><td>File opened<\/td><td>[SFTP-OPEN] admin opened: report.pdf (1.5 MB)<\/td><\/tr><tr><td>read<\/td><td>Data read<\/td><td>[SFTP-READ] report.pdf: 750 KB \/ 1.5 MB (50%)<\/td><\/tr><tr><td>written<\/td><td>Data written<\/td><td>[SFTP-WRITE] upload.zip: 10.0 MB uploaded<\/td><\/tr><tr><td>closed<\/td><td>File closed<\/td><td>[SFTP-CLOSE] report.pdf closed (total: 1.5 MB)<\/td><\/tr><tr><td>removing<\/td><td>File deleted<\/td><td>[SFTP-DELETE] admin deleted: old_file.txt<\/td><\/tr><tr><td>moving<\/td><td>File renamed\/moved<\/td><td>[SFTP-MOVE] admin moved: old.txt -&gt; new.txt<\/td><\/tr><tr><td><\/td><td><\/td><td><\/td><\/tr><\/tbody><\/table><\/figure>\n\n\n\n<p class=\"sera-block-paragraph\"><strong>EOF Exception Handling<\/strong>:<\/p>\n\n\n\n<p class=\"sera-block-paragraph\">Apache MINA SSHD internally throws EOFException during normal read completion. This listener replaces scary stack traces with friendly messages:<\/p>\n\n\n\n<div class=\"sera-block-kevinbatdorf-code-block-pro cbp-has-line-numbers\" data-code-block-pro-font-family=\"Code-Pro-JetBrains-Mono\" style=\"font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;--cbp-line-number-color:#abb2bf;--cbp-line-number-width:calc(2 * 0.6 * .875rem);line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)\"><span role=\"button\" tabindex=\"0\" style=\"color:#abb2bf;display:none\" aria-label=\"Copy\" class=\"code-block-pro-copy-button\"><pre class=\"code-block-pro-copy-button-pre\" aria-hidden=\"true\"><textarea class=\"code-block-pro-copy-button-textarea\" tabindex=\"-1\" aria-hidden=\"true\" readonly>@Override\npublic void read(..., Throwable thrown) {\n    if (thrown instanceof EOFException) {\n        \/\/ Normal EOF - replace with friendly message\n        System.out.println(\"&#91;SFTP-READ&#93; \" + filename + \n            \": End of file reached (download complete)\");\n    } else {\n        \/\/ Actual error\n        System.err.println(\"&#91;SFTP-ERROR&#93; \" + filename + \n            \" read failed: \" + thrown.getMessage());\n    }\n}\n<\/textarea><\/pre><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" style=\"width:24px;height:24px\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" stroke-width=\"2\"><path class=\"with-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M4.5 12.75l6 6 9-13.5\"><\/path><path class=\"without-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M16.5 8.25V6a2.25 2.25 0 00-2.25-2.25H6A2.25 2.25 0 003.75 6v8.25A2.25 2.25 0 006 16.5h2.25m8.25-8.25H18a2.25 2.25 0 012.25 2.25V18A2.25 2.25 0 0118 20.25h-7.5A2.25 2.25 0 018.25 18v-1.5m8.25-8.25h-6a2.25 2.25 0 00-2.25 2.25v6\"><\/path><\/svg><\/span><pre class=\"shiki one-dark-pro\" style=\"background-color: #282c34\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color: #61AFEF\">@Override<\/span><\/span>\n<span class=\"line\"><span style=\"color: #61AFEF\">public<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">void<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">read<\/span><span style=\"color: #ABB2BF\">(<\/span><span style=\"color: #56B6C2\">...<\/span><span style=\"color: #ABB2BF\">, <\/span><span style=\"color: #98C379\">Throwable<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">thrown<\/span><span style=\"color: #ABB2BF\">) <\/span><span style=\"color: #98C379\">{<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">    <\/span><span style=\"color: #C678DD\">if<\/span><span style=\"color: #ABB2BF\"> (<\/span><span style=\"color: #61AFEF\">thrown<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">instanceof<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">EOFException<\/span><span style=\"color: #ABB2BF\">) {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">        <\/span><span style=\"color: #61AFEF\">\/\/<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">Normal<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">EOF<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">-<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">replace<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">with<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">friendly<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">message<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">        <\/span><span style=\"color: #61AFEF\">System.out.println(<\/span><span style=\"color: #61AFEF\">&quot;&#91;SFTP-READ&#93; &quot;<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">+<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">filename<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">+<\/span><span style=\"color: #ABB2BF\"> <\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">            <\/span><span style=\"color: #61AFEF\">&quot;: End of file reached (download complete)&quot;<\/span><span style=\"color: #ABB2BF\">);<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">    } <\/span><span style=\"color: #C678DD\">else<\/span><span style=\"color: #ABB2BF\"> {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">        <\/span><span style=\"color: #61AFEF\">\/\/<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">Actual<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">error<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">        <\/span><span style=\"color: #61AFEF\">System.err.println(<\/span><span style=\"color: #61AFEF\">&quot;&#91;SFTP-ERROR&#93; &quot;<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">+<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">filename<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">+<\/span><span style=\"color: #ABB2BF\"> <\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">            <\/span><span style=\"color: #61AFEF\">&quot; read failed: &quot;<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">+<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">thrown.getMessage<\/span><span style=\"color: #ABB2BF\">());<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">    }<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">}<\/span><\/span>\n<span class=\"line\"><\/span><\/code><\/pre><\/div>\n\n\n\n<p class=\"sera-block-paragraph\"><\/p>\n\n\n\n<p class=\"sera-block-paragraph\"><strong>Before<\/strong>:<\/p>\n\n\n\n<div class=\"sera-block-kevinbatdorf-code-block-pro cbp-has-line-numbers\" data-code-block-pro-font-family=\"Code-Pro-JetBrains-Mono\" style=\"font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;--cbp-line-number-color:#abb2bf;--cbp-line-number-width:calc(1 * 0.6 * .875rem);line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)\"><span role=\"button\" tabindex=\"0\" style=\"color:#abb2bf;display:none\" aria-label=\"Copy\" class=\"code-block-pro-copy-button\"><pre class=\"code-block-pro-copy-button-pre\" aria-hidden=\"true\"><textarea class=\"code-block-pro-copy-button-textarea\" tabindex=\"-1\" aria-hidden=\"true\" readonly>java.io.EOFException\n    at org.apache.sshd.sftp.server.SftpSubsystem.read(...)\n    at org.apache.sshd.sftp.server.SftpSubsystem.process(...)\n    ...\n<\/textarea><\/pre><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" style=\"width:24px;height:24px\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" stroke-width=\"2\"><path class=\"with-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M4.5 12.75l6 6 9-13.5\"><\/path><path class=\"without-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M16.5 8.25V6a2.25 2.25 0 00-2.25-2.25H6A2.25 2.25 0 003.75 6v8.25A2.25 2.25 0 006 16.5h2.25m8.25-8.25H18a2.25 2.25 0 012.25 2.25V18A2.25 2.25 0 0118 20.25h-7.5A2.25 2.25 0 018.25 18v-1.5m8.25-8.25h-6a2.25 2.25 0 00-2.25 2.25v6\"><\/path><\/svg><\/span><pre class=\"shiki one-dark-pro\" style=\"background-color: #282c34\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color: #61AFEF\">java.io.EOFException<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">    <\/span><span style=\"color: #61AFEF\">at<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">org.apache.sshd.sftp.server.SftpSubsystem.read<\/span><span style=\"color: #ABB2BF\">(<\/span><span style=\"color: #56B6C2\">...<\/span><span style=\"color: #ABB2BF\">)<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">    <\/span><span style=\"color: #61AFEF\">at<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">org.apache.sshd.sftp.server.SftpSubsystem.process<\/span><span style=\"color: #ABB2BF\">(<\/span><span style=\"color: #56B6C2\">...<\/span><span style=\"color: #ABB2BF\">)<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">    <\/span><span style=\"color: #56B6C2\">...<\/span><\/span>\n<span class=\"line\"><\/span><\/code><\/pre><\/div>\n\n\n\n<p class=\"sera-block-paragraph\"><\/p>\n\n\n\n<p class=\"sera-block-paragraph\"><strong>After<\/strong>:<\/p>\n\n\n\n<div class=\"sera-block-kevinbatdorf-code-block-pro cbp-has-line-numbers\" data-code-block-pro-font-family=\"Code-Pro-JetBrains-Mono\" style=\"font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;--cbp-line-number-color:#abb2bf;--cbp-line-number-width:calc(1 * 0.6 * .875rem);line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)\"><span role=\"button\" tabindex=\"0\" style=\"color:#abb2bf;display:none\" aria-label=\"Copy\" class=\"code-block-pro-copy-button\"><pre class=\"code-block-pro-copy-button-pre\" aria-hidden=\"true\"><textarea class=\"code-block-pro-copy-button-textarea\" tabindex=\"-1\" aria-hidden=\"true\" readonly>&#91;SFTP-READ&#93; document.pdf: End of file reached (download complete)\n<\/textarea><\/pre><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" style=\"width:24px;height:24px\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" stroke-width=\"2\"><path class=\"with-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M4.5 12.75l6 6 9-13.5\"><\/path><path class=\"without-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M16.5 8.25V6a2.25 2.25 0 00-2.25-2.25H6A2.25 2.25 0 003.75 6v8.25A2.25 2.25 0 006 16.5h2.25m8.25-8.25H18a2.25 2.25 0 012.25 2.25V18A2.25 2.25 0 0118 20.25h-7.5A2.25 2.25 0 018.25 18v-1.5m8.25-8.25h-6a2.25 2.25 0 00-2.25 2.25v6\"><\/path><\/svg><\/span><pre class=\"shiki one-dark-pro\" style=\"background-color: #282c34\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color: #ABB2BF\">&#91;SFTP-READ&#93; document.pdf: End of file reached (<\/span><span style=\"color: #61AFEF\">download<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">complete<\/span><span style=\"color: #ABB2BF\">)<\/span><\/span>\n<span class=\"line\"><\/span><\/code><\/pre><\/div>\n\n\n\n<p class=\"sera-block-paragraph\"><\/p>\n\n\n\n<p class=\"sera-block-paragraph\"><strong>Progress Logging<\/strong>:<\/p>\n\n\n\n<p class=\"sera-block-paragraph\">Logs progress at strategic points to avoid spam:<\/p>\n\n\n\n<div class=\"sera-block-kevinbatdorf-code-block-pro cbp-has-line-numbers\" data-code-block-pro-font-family=\"Code-Pro-JetBrains-Mono\" style=\"font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;--cbp-line-number-color:#abb2bf;--cbp-line-number-width:calc(2 * 0.6 * .875rem);line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)\"><span role=\"button\" tabindex=\"0\" style=\"color:#abb2bf;display:none\" aria-label=\"Copy\" class=\"code-block-pro-copy-button\"><pre class=\"code-block-pro-copy-button-pre\" aria-hidden=\"true\"><textarea class=\"code-block-pro-copy-button-textarea\" tabindex=\"-1\" aria-hidden=\"true\" readonly>private boolean shouldLogProgress(long prev, long curr, long total) {\n    \/\/ Log every 10MB\n    if (prev \/ 10MB != curr \/ 10MB) return true;\n    \n    \/\/ Log at 25%, 50%, 75% milestones\n    int prevPct = (int)((prev * 100) \/ total);\n    int currPct = (int)((curr * 100) \/ total);\n    \n    return (prevPct &lt; 25 &amp;&amp; currPct >= 25) ||\n           (prevPct &lt; 50 &amp;&amp; currPct >= 50) ||\n           (prevPct &lt; 75 &amp;&amp; currPct >= 75);\n}\n<\/textarea><\/pre><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" style=\"width:24px;height:24px\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" stroke-width=\"2\"><path class=\"with-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M4.5 12.75l6 6 9-13.5\"><\/path><path class=\"without-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M16.5 8.25V6a2.25 2.25 0 00-2.25-2.25H6A2.25 2.25 0 003.75 6v8.25A2.25 2.25 0 006 16.5h2.25m8.25-8.25H18a2.25 2.25 0 012.25 2.25V18A2.25 2.25 0 0118 20.25h-7.5A2.25 2.25 0 018.25 18v-1.5m8.25-8.25h-6a2.25 2.25 0 00-2.25 2.25v6\"><\/path><\/svg><\/span><pre class=\"shiki one-dark-pro\" style=\"background-color: #282c34\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color: #61AFEF\">private<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">boolean<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">shouldLogProgress<\/span><span style=\"color: #ABB2BF\">(<\/span><span style=\"color: #61AFEF\">long<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">prev,<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">long<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">curr,<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">long<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">total<\/span><span style=\"color: #ABB2BF\">) <\/span><span style=\"color: #98C379\">{<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">    <\/span><span style=\"color: #61AFEF\">\/\/<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">Log<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">every<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #D19A66\">10<\/span><span style=\"color: #98C379\">MB<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">    <\/span><span style=\"color: #C678DD\">if<\/span><span style=\"color: #ABB2BF\"> (<\/span><span style=\"color: #61AFEF\">prev<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">\/<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #D19A66\">10<\/span><span style=\"color: #98C379\">MB<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">!=<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">curr<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">\/<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #D19A66\">10<\/span><span style=\"color: #98C379\">MB<\/span><span style=\"color: #ABB2BF\">) <\/span><span style=\"color: #C678DD\">return<\/span><span style=\"color: #ABB2BF\"> true;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">    <\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">    <\/span><span style=\"color: #61AFEF\">\/\/<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">Log<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">at<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #D19A66\">25<\/span><span style=\"color: #98C379\">%,<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #D19A66\">50<\/span><span style=\"color: #98C379\">%,<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #D19A66\">75<\/span><span style=\"color: #98C379\">%<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">milestones<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">    <\/span><span style=\"color: #61AFEF\">int<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">prevPct<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">=<\/span><span style=\"color: #ABB2BF\"> (int)((prev <\/span><span style=\"color: #56B6C2\">*<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #D19A66\">100<\/span><span style=\"color: #ABB2BF\">) <\/span><span style=\"color: #56B6C2\">\/<\/span><span style=\"color: #ABB2BF\"> total);<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">    int currPct = (int)((curr * 100) \/ total);<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">    <\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">    <\/span><span style=\"color: #C678DD\">return<\/span><span style=\"color: #ABB2BF\"> (prevPct &lt; <\/span><span style=\"color: #D19A66\">25<\/span><span style=\"color: #ABB2BF\"> &amp;&amp; <\/span><span style=\"color: #61AFEF\">currPct<\/span><span style=\"color: #ABB2BF\"> &gt;<\/span><span style=\"color: #98C379\">=<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #D19A66\">25<\/span><span style=\"color: #ABB2BF\">) ||<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">           (<\/span><span style=\"color: #61AFEF\">prevPct<\/span><span style=\"color: #ABB2BF\"> &lt; <\/span><span style=\"color: #D19A66\">50<\/span><span style=\"color: #ABB2BF\"> &amp;&amp; <\/span><span style=\"color: #61AFEF\">currPct<\/span><span style=\"color: #ABB2BF\"> &gt;<\/span><span style=\"color: #98C379\">=<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #D19A66\">50<\/span><span style=\"color: #ABB2BF\">) ||<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">           (<\/span><span style=\"color: #61AFEF\">prevPct<\/span><span style=\"color: #ABB2BF\"> &lt; <\/span><span style=\"color: #D19A66\">75<\/span><span style=\"color: #ABB2BF\"> &amp;&amp; <\/span><span style=\"color: #61AFEF\">currPct<\/span><span style=\"color: #ABB2BF\"> &gt;<\/span><span style=\"color: #98C379\">=<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #D19A66\">75<\/span><span style=\"color: #ABB2BF\">);<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">}<\/span><\/span>\n<span class=\"line\"><\/span><\/code><\/pre><\/div>\n\n\n\n<p class=\"sera-block-paragraph\"><\/p>\n\n\n\n<p class=\"sera-block-paragraph\"><strong>Example Log Sequence<\/strong>:<\/p>\n\n\n\n<div class=\"sera-block-kevinbatdorf-code-block-pro cbp-has-line-numbers\" data-code-block-pro-font-family=\"Code-Pro-JetBrains-Mono\" style=\"font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;--cbp-line-number-color:#abb2bf;--cbp-line-number-width:calc(1 * 0.6 * .875rem);line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)\"><span role=\"button\" tabindex=\"0\" style=\"color:#abb2bf;display:none\" aria-label=\"Copy\" class=\"code-block-pro-copy-button\"><pre class=\"code-block-pro-copy-button-pre\" aria-hidden=\"true\"><textarea class=\"code-block-pro-copy-button-textarea\" tabindex=\"-1\" aria-hidden=\"true\" readonly>&#91;SFTP-OPEN&#93; admin opened: largefile.zip (100.0 MB)\n&#91;SFTP-READ&#93; largefile.zip: 10.0 MB \/ 100.0 MB (10%)\n&#91;SFTP-READ&#93; largefile.zip: 20.0 MB \/ 100.0 MB (20%)\n&#91;SFTP-READ&#93; largefile.zip: 25.0 MB \/ 100.0 MB (25%)\n&#91;SFTP-READ&#93; largefile.zip: 50.0 MB \/ 100.0 MB (50%)\n&#91;SFTP-READ&#93; largefile.zip: 75.0 MB \/ 100.0 MB (75%)\n&#91;SFTP-READ&#93; largefile.zip: End of file reached (download complete)\n&#91;SFTP-CLOSE&#93; largefile.zip closed (total: 100.0 MB)\n<\/textarea><\/pre><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" style=\"width:24px;height:24px\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" stroke-width=\"2\"><path class=\"with-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M4.5 12.75l6 6 9-13.5\"><\/path><path class=\"without-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M16.5 8.25V6a2.25 2.25 0 00-2.25-2.25H6A2.25 2.25 0 003.75 6v8.25A2.25 2.25 0 006 16.5h2.25m8.25-8.25H18a2.25 2.25 0 012.25 2.25V18A2.25 2.25 0 0118 20.25h-7.5A2.25 2.25 0 018.25 18v-1.5m8.25-8.25h-6a2.25 2.25 0 00-2.25 2.25v6\"><\/path><\/svg><\/span><pre class=\"shiki one-dark-pro\" style=\"background-color: #282c34\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color: #ABB2BF\">&#91;SFTP-OPEN&#93; admin opened: largefile.zip (<\/span><span style=\"color: #61AFEF\">100.0<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">MB<\/span><span style=\"color: #ABB2BF\">)<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">&#91;SFTP-READ&#93; largefile.zip: 10.0 MB \/ 100.0 MB (<\/span><span style=\"color: #61AFEF\">10%<\/span><span style=\"color: #ABB2BF\">)<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">&#91;SFTP-READ&#93; largefile.zip: 20.0 MB \/ 100.0 MB (<\/span><span style=\"color: #61AFEF\">20%<\/span><span style=\"color: #ABB2BF\">)<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">&#91;SFTP-READ&#93; largefile.zip: 25.0 MB \/ 100.0 MB (<\/span><span style=\"color: #61AFEF\">25%<\/span><span style=\"color: #ABB2BF\">)<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">&#91;SFTP-READ&#93; largefile.zip: 50.0 MB \/ 100.0 MB (<\/span><span style=\"color: #61AFEF\">50%<\/span><span style=\"color: #ABB2BF\">)<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">&#91;SFTP-READ&#93; largefile.zip: 75.0 MB \/ 100.0 MB (<\/span><span style=\"color: #61AFEF\">75%<\/span><span style=\"color: #ABB2BF\">)<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">&#91;SFTP-READ&#93; largefile.zip: End of file reached (<\/span><span style=\"color: #61AFEF\">download<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">complete<\/span><span style=\"color: #ABB2BF\">)<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">&#91;SFTP-CLOSE&#93; largefile.zip closed (<\/span><span style=\"color: #61AFEF\">total:<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #D19A66\">100.0<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">MB<\/span><span style=\"color: #ABB2BF\">)<\/span><\/span>\n<span class=\"line\"><\/span><\/code><\/pre><\/div>\n\n\n\n<hr class=\"sera-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h3 class=\"sera-block-heading\">6. UserAuthenticationService<\/h3>\n\n\n\n<p class=\"sera-block-paragraph\"><strong>Location<\/strong>: UserAuthenticationService.java<\/p>\n\n\n\n<p class=\"sera-block-paragraph\"><strong>Purpose<\/strong>: Secure password-based user authentication<\/p>\n\n\n\n<p class=\"sera-block-paragraph\"><strong>Security Implementation<\/strong>:<\/p>\n\n\n\n<div class=\"sera-block-kevinbatdorf-code-block-pro cbp-has-line-numbers\" data-code-block-pro-font-family=\"Code-Pro-JetBrains-Mono\" style=\"font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;--cbp-line-number-color:#abb2bf;--cbp-line-number-width:calc(1 * 0.6 * .875rem);line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)\"><span role=\"button\" tabindex=\"0\" style=\"color:#abb2bf;display:none\" aria-label=\"Copy\" class=\"code-block-pro-copy-button\"><pre class=\"code-block-pro-copy-button-pre\" aria-hidden=\"true\"><textarea class=\"code-block-pro-copy-button-textarea\" tabindex=\"-1\" aria-hidden=\"true\" readonly>Algorithm:   PBKDF2-HMAC-SHA256\nIterations:  100,000 (OWASP recommendation for 2024)\nSalt:        32 bytes (cryptographically random)\nKey Length:  256 bits\nStorage:     In-memory (ConcurrentHashMap)\n<\/textarea><\/pre><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" style=\"width:24px;height:24px\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" stroke-width=\"2\"><path class=\"with-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M4.5 12.75l6 6 9-13.5\"><\/path><path class=\"without-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M16.5 8.25V6a2.25 2.25 0 00-2.25-2.25H6A2.25 2.25 0 003.75 6v8.25A2.25 2.25 0 006 16.5h2.25m8.25-8.25H18a2.25 2.25 0 012.25 2.25V18A2.25 2.25 0 0118 20.25h-7.5A2.25 2.25 0 018.25 18v-1.5m8.25-8.25h-6a2.25 2.25 0 00-2.25 2.25v6\"><\/path><\/svg><\/span><pre class=\"shiki one-dark-pro\" style=\"background-color: #282c34\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color: #61AFEF\">Algorithm:<\/span><span style=\"color: #ABB2BF\">   <\/span><span style=\"color: #98C379\">PBKDF2-HMAC-SHA256<\/span><\/span>\n<span class=\"line\"><span style=\"color: #61AFEF\">Iterations:<\/span><span style=\"color: #ABB2BF\">  <\/span><span style=\"color: #D19A66\">100<\/span><span style=\"color: #98C379\">,000<\/span><span style=\"color: #ABB2BF\"> (OWASP <\/span><span style=\"color: #98C379\">recommendation<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">for<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #D19A66\">2024<\/span><span style=\"color: #ABB2BF\">)<\/span><\/span>\n<span class=\"line\"><span style=\"color: #61AFEF\">Salt:<\/span><span style=\"color: #ABB2BF\">        <\/span><span style=\"color: #D19A66\">32<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">bytes<\/span><span style=\"color: #ABB2BF\"> (cryptographically <\/span><span style=\"color: #98C379\">random<\/span><span style=\"color: #ABB2BF\">)<\/span><\/span>\n<span class=\"line\"><span style=\"color: #61AFEF\">Key<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">Length:<\/span><span style=\"color: #ABB2BF\">  <\/span><span style=\"color: #D19A66\">256<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">bits<\/span><\/span>\n<span class=\"line\"><span style=\"color: #61AFEF\">Storage:<\/span><span style=\"color: #ABB2BF\">     <\/span><span style=\"color: #98C379\">In-memory<\/span><span style=\"color: #ABB2BF\"> (ConcurrentHashMap)<\/span><\/span>\n<span class=\"line\"><\/span><\/code><\/pre><\/div>\n\n\n\n<p class=\"sera-block-paragraph\"><\/p>\n\n\n\n<p class=\"sera-block-paragraph\"><strong>Security Features<\/strong>:<\/p>\n\n\n\n<ol class=\"sera-block-list\">\n<li><strong>Password Hashing<\/strong> (PBKDF2):<\/li>\n<\/ol>\n\n\n\n<div class=\"sera-block-kevinbatdorf-code-block-pro cbp-has-line-numbers\" data-code-block-pro-font-family=\"Code-Pro-JetBrains-Mono\" style=\"font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;--cbp-line-number-color:#abb2bf;--cbp-line-number-width:calc(2 * 0.6 * .875rem);line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)\"><span role=\"button\" tabindex=\"0\" style=\"color:#abb2bf;display:none\" aria-label=\"Copy\" class=\"code-block-pro-copy-button\"><pre class=\"code-block-pro-copy-button-pre\" aria-hidden=\"true\"><textarea class=\"code-block-pro-copy-button-textarea\" tabindex=\"-1\" aria-hidden=\"true\" readonly>private static byte[] hashPassword(String password, byte[] salt) {\n    PBEKeySpec spec = new PBEKeySpec(\n        password.toCharArray(), \n        salt, \n        100000,  \/\/ iterations\n        256      \/\/ key length\n    );\n    SecretKeyFactory factory = SecretKeyFactory.getInstance(\"PBKDF2WithHmacSHA256\");\n    return factory.generateSecret(spec).getEncoded();\n}\n<\/textarea><\/pre><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" style=\"width:24px;height:24px\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" stroke-width=\"2\"><path class=\"with-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M4.5 12.75l6 6 9-13.5\"><\/path><path class=\"without-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M16.5 8.25V6a2.25 2.25 0 00-2.25-2.25H6A2.25 2.25 0 003.75 6v8.25A2.25 2.25 0 006 16.5h2.25m8.25-8.25H18a2.25 2.25 0 012.25 2.25V18A2.25 2.25 0 0118 20.25h-7.5A2.25 2.25 0 018.25 18v-1.5m8.25-8.25h-6a2.25 2.25 0 00-2.25 2.25v6\"><\/path><\/svg><\/span><pre class=\"shiki one-dark-pro\" style=\"background-color: #282c34\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color: #61AFEF\">private<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">static<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">byte[]<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">hashPassword<\/span><span style=\"color: #ABB2BF\">(<\/span><span style=\"color: #61AFEF\">String<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">password,<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">byte[]<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">salt<\/span><span style=\"color: #ABB2BF\">) <\/span><span style=\"color: #98C379\">{<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">    <\/span><span style=\"color: #61AFEF\">PBEKeySpec<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">spec<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">=<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">new<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">PBEKeySpec<\/span><span style=\"color: #ABB2BF\">(<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">        <\/span><span style=\"color: #61AFEF\">password.toCharArray<\/span><span style=\"color: #ABB2BF\">(), <\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">        <\/span><span style=\"color: #61AFEF\">salt,<\/span><span style=\"color: #ABB2BF\"> <\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">        <\/span><span style=\"color: #61AFEF\">100000,<\/span><span style=\"color: #ABB2BF\">  <\/span><span style=\"color: #98C379\">\/\/<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">iterations<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">        <\/span><span style=\"color: #61AFEF\">256<\/span><span style=\"color: #ABB2BF\">      <\/span><span style=\"color: #98C379\">\/\/<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">key<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">length<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">    );<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">    <\/span><span style=\"color: #61AFEF\">SecretKeyFactory<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">factory<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">=<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">SecretKeyFactory.getInstance<\/span><span style=\"color: #ABB2BF\">(<\/span><span style=\"color: #61AFEF\">&quot;PBKDF2WithHmacSHA256&quot;<\/span><span style=\"color: #ABB2BF\">);<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">    <\/span><span style=\"color: #C678DD\">return<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">factory.generateSecret<\/span><span style=\"color: #ABB2BF\">(<\/span><span style=\"color: #61AFEF\">spec<\/span><span style=\"color: #ABB2BF\">)<\/span><span style=\"color: #98C379\">.getEncoded<\/span><span style=\"color: #ABB2BF\">();<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">}<\/span><\/span>\n<span class=\"line\"><\/span><\/code><\/pre><\/div>\n\n\n\n<ol start=\"2\" class=\"sera-block-list\">\n<li><strong>Constant-Time Comparison<\/strong> (prevents timing attacks):<\/li>\n<\/ol>\n\n\n\n<div class=\"sera-block-kevinbatdorf-code-block-pro cbp-has-line-numbers\" data-code-block-pro-font-family=\"Code-Pro-JetBrains-Mono\" style=\"font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;--cbp-line-number-color:#abb2bf;--cbp-line-number-width:calc(2 * 0.6 * .875rem);line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)\"><span role=\"button\" tabindex=\"0\" style=\"color:#abb2bf;display:none\" aria-label=\"Copy\" class=\"code-block-pro-copy-button\"><pre class=\"code-block-pro-copy-button-pre\" aria-hidden=\"true\"><textarea class=\"code-block-pro-copy-button-textarea\" tabindex=\"-1\" aria-hidden=\"true\" readonly>private static boolean constantTimeEquals(byte[] a, byte[] b) {\n    if (a.length != b.length) return false;\n    \n    int result = 0;\n    for (int i = 0; i &lt; a.length; i++) {\n        result |= a&#91;i&#93; ^ b&#91;i&#93;;  \/\/ Accumulate all differences\n    }\n    return result == 0;  \/\/ Always processes entire array\n}\n<\/textarea><\/pre><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" style=\"width:24px;height:24px\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" stroke-width=\"2\"><path class=\"with-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M4.5 12.75l6 6 9-13.5\"><\/path><path class=\"without-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M16.5 8.25V6a2.25 2.25 0 00-2.25-2.25H6A2.25 2.25 0 003.75 6v8.25A2.25 2.25 0 006 16.5h2.25m8.25-8.25H18a2.25 2.25 0 012.25 2.25V18A2.25 2.25 0 0118 20.25h-7.5A2.25 2.25 0 018.25 18v-1.5m8.25-8.25h-6a2.25 2.25 0 00-2.25 2.25v6\"><\/path><\/svg><\/span><pre class=\"shiki one-dark-pro\" style=\"background-color: #282c34\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color: #61AFEF\">private<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">static<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">boolean<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">constantTimeEquals<\/span><span style=\"color: #ABB2BF\">(<\/span><span style=\"color: #61AFEF\">byte[]<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">a,<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">byte[]<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">b<\/span><span style=\"color: #ABB2BF\">) <\/span><span style=\"color: #98C379\">{<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">    <\/span><span style=\"color: #C678DD\">if<\/span><span style=\"color: #ABB2BF\"> (<\/span><span style=\"color: #61AFEF\">a.length<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">!=<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">b.length<\/span><span style=\"color: #ABB2BF\">) <\/span><span style=\"color: #C678DD\">return<\/span><span style=\"color: #ABB2BF\"> false;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">    <\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">    <\/span><span style=\"color: #61AFEF\">int<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">result<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">=<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #D19A66\">0<\/span><span style=\"color: #ABB2BF\">;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">    <\/span><span style=\"color: #C678DD\">for<\/span><span style=\"color: #ABB2BF\"> (<\/span><span style=\"color: #61AFEF\">int<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">i<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">=<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #D19A66\">0<\/span><span style=\"color: #ABB2BF\">; <\/span><span style=\"color: #61AFEF\">i<\/span><span style=\"color: #ABB2BF\"> &lt; <\/span><span style=\"color: #98C379\">a.length<\/span><span style=\"color: #ABB2BF\">; <\/span><span style=\"color: #61AFEF\">i++<\/span><span style=\"color: #ABB2BF\">) {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">        <\/span><span style=\"color: #61AFEF\">result<\/span><span style=\"color: #ABB2BF\"> |= <\/span><span style=\"color: #98C379\">a&#91;i&#93;<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">^<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">b&#91;i&#93;<\/span><span style=\"color: #ABB2BF\">;  <\/span><span style=\"color: #61AFEF\">\/\/<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">Accumulate<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">all<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">differences<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">    }<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">    <\/span><span style=\"color: #C678DD\">return<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">result<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">==<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #D19A66\">0<\/span><span style=\"color: #ABB2BF\">;  <\/span><span style=\"color: #61AFEF\">\/\/<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">Always<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">processes<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">entire<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">array<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">}<\/span><\/span>\n<span class=\"line\"><\/span><\/code><\/pre><\/div>\n\n\n\n<ol start=\"3\" class=\"sera-block-list\">\n<li><strong>Dummy Hash<\/strong> (prevents username enumeration):<\/li>\n<\/ol>\n\n\n\n<div class=\"sera-block-kevinbatdorf-code-block-pro cbp-has-line-numbers\" data-code-block-pro-font-family=\"Code-Pro-JetBrains-Mono\" style=\"font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;--cbp-line-number-color:#abb2bf;--cbp-line-number-width:calc(2 * 0.6 * .875rem);line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)\"><span role=\"button\" tabindex=\"0\" style=\"color:#abb2bf;display:none\" aria-label=\"Copy\" class=\"code-block-pro-copy-button\"><pre class=\"code-block-pro-copy-button-pre\" aria-hidden=\"true\"><textarea class=\"code-block-pro-copy-button-textarea\" tabindex=\"-1\" aria-hidden=\"true\" readonly>public static boolean authenticate(String username, String password) {\n    UserCredentials creds = users.get(username);\n    \n    if (creds == null) {\n        dummyHash(password);  \/\/ Same timing as real auth\n        return false;\n    }\n    \n    \/\/ Real authentication\n    byte[] hash = hashPassword(password, creds.salt);\n    return constantTimeEquals(hash, creds.hash);\n}\n<\/textarea><\/pre><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" style=\"width:24px;height:24px\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" stroke-width=\"2\"><path class=\"with-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M4.5 12.75l6 6 9-13.5\"><\/path><path class=\"without-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M16.5 8.25V6a2.25 2.25 0 00-2.25-2.25H6A2.25 2.25 0 003.75 6v8.25A2.25 2.25 0 006 16.5h2.25m8.25-8.25H18a2.25 2.25 0 012.25 2.25V18A2.25 2.25 0 0118 20.25h-7.5A2.25 2.25 0 018.25 18v-1.5m8.25-8.25h-6a2.25 2.25 0 00-2.25 2.25v6\"><\/path><\/svg><\/span><pre class=\"shiki one-dark-pro\" style=\"background-color: #282c34\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color: #61AFEF\">public<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">static<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">boolean<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">authenticate<\/span><span style=\"color: #ABB2BF\">(<\/span><span style=\"color: #61AFEF\">String<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">username,<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">String<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">password<\/span><span style=\"color: #ABB2BF\">) <\/span><span style=\"color: #98C379\">{<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">    <\/span><span style=\"color: #61AFEF\">UserCredentials<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">creds<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">=<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">users.get<\/span><span style=\"color: #ABB2BF\">(<\/span><span style=\"color: #61AFEF\">username<\/span><span style=\"color: #ABB2BF\">);<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">    <\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">    <\/span><span style=\"color: #C678DD\">if<\/span><span style=\"color: #ABB2BF\"> (<\/span><span style=\"color: #61AFEF\">creds<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">==<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">null<\/span><span style=\"color: #ABB2BF\">) {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">        <\/span><span style=\"color: #61AFEF\">dummyHash(password<\/span><span style=\"color: #ABB2BF\">);  <\/span><span style=\"color: #61AFEF\">\/\/<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">Same<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">timing<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">as<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">real<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">auth<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">        <\/span><span style=\"color: #C678DD\">return<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #D19A66\">false<\/span><span style=\"color: #ABB2BF\">;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">    }<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">    <\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">    <\/span><span style=\"color: #61AFEF\">\/\/<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">Real<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">authentication<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">    <\/span><span style=\"color: #61AFEF\">byte[]<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">hash<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">=<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">hashPassword<\/span><span style=\"color: #ABB2BF\">(<\/span><span style=\"color: #61AFEF\">password,<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">creds.salt<\/span><span style=\"color: #ABB2BF\">);<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">    <\/span><span style=\"color: #C678DD\">return<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">constantTimeEquals<\/span><span style=\"color: #ABB2BF\">(<\/span><span style=\"color: #56B6C2\">hash<\/span><span style=\"color: #ABB2BF\">, <\/span><span style=\"color: #98C379\">creds.hash<\/span><span style=\"color: #ABB2BF\">);<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">}<\/span><\/span>\n<span class=\"line\"><\/span><\/code><\/pre><\/div>\n\n\n\n<p class=\"sera-block-paragraph\"><strong>Default Users<\/strong> (For Testing\/Development Only):<\/p>\n\n\n\n<div class=\"sera-block-kevinbatdorf-code-block-pro cbp-has-line-numbers\" data-code-block-pro-font-family=\"Code-Pro-JetBrains-Mono\" style=\"font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;--cbp-line-number-color:#abb2bf;--cbp-line-number-width:calc(1 * 0.6 * .875rem);line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)\"><span role=\"button\" tabindex=\"0\" style=\"color:#abb2bf;display:none\" aria-label=\"Copy\" class=\"code-block-pro-copy-button\"><pre class=\"code-block-pro-copy-button-pre\" aria-hidden=\"true\"><textarea class=\"code-block-pro-copy-button-textarea\" tabindex=\"-1\" aria-hidden=\"true\" readonly>Username: admin\nPassword: admin123\n\nUsername: testuser\nPassword: password123\n<\/textarea><\/pre><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" style=\"width:24px;height:24px\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" stroke-width=\"2\"><path class=\"with-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M4.5 12.75l6 6 9-13.5\"><\/path><path class=\"without-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M16.5 8.25V6a2.25 2.25 0 00-2.25-2.25H6A2.25 2.25 0 003.75 6v8.25A2.25 2.25 0 006 16.5h2.25m8.25-8.25H18a2.25 2.25 0 012.25 2.25V18A2.25 2.25 0 0118 20.25h-7.5A2.25 2.25 0 018.25 18v-1.5m8.25-8.25h-6a2.25 2.25 0 00-2.25 2.25v6\"><\/path><\/svg><\/span><pre class=\"shiki one-dark-pro\" style=\"background-color: #282c34\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color: #61AFEF\">Username:<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">admin<\/span><\/span>\n<span class=\"line\"><span style=\"color: #61AFEF\">Password:<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">admin123<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #61AFEF\">Username:<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">testuser<\/span><\/span>\n<span class=\"line\"><span style=\"color: #61AFEF\">Password:<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">password123<\/span><\/span>\n<span class=\"line\"><\/span><\/code><\/pre><\/div>\n\n\n\n<p class=\"sera-block-paragraph\"><strong>\u26a0\ufe0f WARNING<\/strong>: These default credentials are for educational and testing purposes only. Remove or change these credentials before any deployment, even in development environments accessible from network.<\/p>\n\n\n\n<p class=\"sera-block-paragraph\"><strong>Adding New Users<\/strong>:<\/p>\n\n\n\n<div class=\"sera-block-kevinbatdorf-code-block-pro cbp-has-line-numbers\" data-code-block-pro-font-family=\"Code-Pro-JetBrains-Mono\" style=\"font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;--cbp-line-number-color:#abb2bf;--cbp-line-number-width:calc(1 * 0.6 * .875rem);line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)\"><span role=\"button\" tabindex=\"0\" style=\"color:#abb2bf;display:none\" aria-label=\"Copy\" class=\"code-block-pro-copy-button\"><pre class=\"code-block-pro-copy-button-pre\" aria-hidden=\"true\"><textarea class=\"code-block-pro-copy-button-textarea\" tabindex=\"-1\" aria-hidden=\"true\" readonly>\/\/ Programmatic\nUserAuthenticationService.addUser(\"newuser\", \"SecurePass123!\");\n\n\/\/ Minimum password length: 8 characters\n<\/textarea><\/pre><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" style=\"width:24px;height:24px\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" stroke-width=\"2\"><path class=\"with-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M4.5 12.75l6 6 9-13.5\"><\/path><path class=\"without-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M16.5 8.25V6a2.25 2.25 0 00-2.25-2.25H6A2.25 2.25 0 003.75 6v8.25A2.25 2.25 0 006 16.5h2.25m8.25-8.25H18a2.25 2.25 0 012.25 2.25V18A2.25 2.25 0 0118 20.25h-7.5A2.25 2.25 0 018.25 18v-1.5m8.25-8.25h-6a2.25 2.25 0 00-2.25 2.25v6\"><\/path><\/svg><\/span><pre class=\"shiki one-dark-pro\" style=\"background-color: #282c34\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color: #61AFEF\">\/\/<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">Programmatic<\/span><\/span>\n<span class=\"line\"><span style=\"color: #61AFEF\">UserAuthenticationService.addUser(<\/span><span style=\"color: #61AFEF\">&quot;newuser&quot;<\/span><span style=\"color: #61AFEF\">,<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">&quot;SecurePass123!&quot;<\/span><span style=\"color: #ABB2BF\">);<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #61AFEF\">\/\/<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">Minimum<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">password<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">length:<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #D19A66\">8<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">characters<\/span><\/span>\n<span class=\"line\"><\/span><\/code><\/pre><\/div>\n\n\n\n<p class=\"sera-block-paragraph\"><\/p>\n\n\n\n<p class=\"sera-block-paragraph\"><strong>Production Considerations<\/strong>:<\/p>\n\n\n\n<p class=\"sera-block-paragraph\">For production, replace in-memory storage with:<\/p>\n\n\n\n<ul class=\"sera-block-list\">\n<li>Database with encrypted credentials<\/li>\n\n\n\n<li>LDAP\/Active Directory integration<\/li>\n\n\n\n<li>OAuth2\/OIDC authentication<\/li>\n\n\n\n<li>Multi-factor authentication (MFA)<\/li>\n<\/ul>\n\n\n\n<p class=\"sera-block-paragraph\">Example database integration:<\/p>\n\n\n\n<div class=\"sera-block-kevinbatdorf-code-block-pro cbp-has-line-numbers\" data-code-block-pro-font-family=\"Code-Pro-JetBrains-Mono\" style=\"font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;--cbp-line-number-color:#abb2bf;--cbp-line-number-width:calc(2 * 0.6 * .875rem);line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)\"><span role=\"button\" tabindex=\"0\" style=\"color:#abb2bf;display:none\" aria-label=\"Copy\" class=\"code-block-pro-copy-button\"><pre class=\"code-block-pro-copy-button-pre\" aria-hidden=\"true\"><textarea class=\"code-block-pro-copy-button-textarea\" tabindex=\"-1\" aria-hidden=\"true\" readonly>public static boolean authenticate(String username, String password) {\n    \/\/ Load from database\n    UserRecord record = database.loadUser(username);\n    if (record == null) {\n        dummyHash(password);\n        return false;\n    }\n    \n    byte[] hash = hashPassword(password, record.salt);\n    return constantTimeEquals(hash, record.passwordHash);\n}\n<\/textarea><\/pre><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" style=\"width:24px;height:24px\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" stroke-width=\"2\"><path class=\"with-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M4.5 12.75l6 6 9-13.5\"><\/path><path class=\"without-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M16.5 8.25V6a2.25 2.25 0 00-2.25-2.25H6A2.25 2.25 0 003.75 6v8.25A2.25 2.25 0 006 16.5h2.25m8.25-8.25H18a2.25 2.25 0 012.25 2.25V18A2.25 2.25 0 0118 20.25h-7.5A2.25 2.25 0 018.25 18v-1.5m8.25-8.25h-6a2.25 2.25 0 00-2.25 2.25v6\"><\/path><\/svg><\/span><pre class=\"shiki one-dark-pro\" style=\"background-color: #282c34\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color: #61AFEF\">public<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">static<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">boolean<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">authenticate<\/span><span style=\"color: #ABB2BF\">(<\/span><span style=\"color: #61AFEF\">String<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">username,<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">String<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">password<\/span><span style=\"color: #ABB2BF\">) <\/span><span style=\"color: #98C379\">{<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">    <\/span><span style=\"color: #61AFEF\">\/\/<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">Load<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">from<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">database<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">    <\/span><span style=\"color: #61AFEF\">UserRecord<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">record<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">=<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">database.loadUser<\/span><span style=\"color: #ABB2BF\">(<\/span><span style=\"color: #61AFEF\">username<\/span><span style=\"color: #ABB2BF\">);<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">    <\/span><span style=\"color: #C678DD\">if<\/span><span style=\"color: #ABB2BF\"> (<\/span><span style=\"color: #61AFEF\">record<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">==<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">null<\/span><span style=\"color: #ABB2BF\">) {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">        <\/span><span style=\"color: #61AFEF\">dummyHash(password<\/span><span style=\"color: #ABB2BF\">);<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">        <\/span><span style=\"color: #C678DD\">return<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #D19A66\">false<\/span><span style=\"color: #ABB2BF\">;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">    }<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">    <\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">    <\/span><span style=\"color: #61AFEF\">byte[]<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">hash<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">=<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">hashPassword<\/span><span style=\"color: #ABB2BF\">(<\/span><span style=\"color: #61AFEF\">password,<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">record.salt<\/span><span style=\"color: #ABB2BF\">);<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">    <\/span><span style=\"color: #C678DD\">return<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">constantTimeEquals<\/span><span style=\"color: #ABB2BF\">(<\/span><span style=\"color: #56B6C2\">hash<\/span><span style=\"color: #ABB2BF\">, <\/span><span style=\"color: #98C379\">record.passwordHash<\/span><span style=\"color: #ABB2BF\">);<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">}<\/span><\/span>\n<span class=\"line\"><\/span><\/code><\/pre><\/div>\n\n\n\n<hr class=\"sera-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h2 class=\"sera-block-heading\">Security Architecture<\/h2>\n\n\n\n<h3 class=\"sera-block-heading\">Defense in Depth<\/h3>\n\n\n\n<div class=\"sera-block-kevinbatdorf-code-block-pro cbp-has-line-numbers\" data-code-block-pro-font-family=\"Code-Pro-JetBrains-Mono\" style=\"font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;--cbp-line-number-color:#abb2bf;--cbp-line-number-width:calc(2 * 0.6 * .875rem);line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)\"><span role=\"button\" tabindex=\"0\" style=\"color:#abb2bf;display:none\" aria-label=\"Copy\" class=\"code-block-pro-copy-button\"><pre class=\"code-block-pro-copy-button-pre\" aria-hidden=\"true\"><textarea class=\"code-block-pro-copy-button-textarea\" tabindex=\"-1\" aria-hidden=\"true\" readonly>\u250c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2510\n\u2502 Layer 1: Network Security                                       \u2502\n\u2502  - SSH protocol encryption (client \u2190 \u2192 server transport)        \u2502\n\u2502  - Host key verification                                        \u2502\n\u2502  - Port-based access control                                    \u2502\n\u2514\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2518\n                              \u2193\n\u250c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2510\n\u2502 Layer 2: Authentication                                         \u2502\n\u2502  - PBKDF2-HMAC-SHA256 password hashing (100K iterations)        \u2502\n\u2502  - Constant-time comparison (timing attack prevention)          \u2502\n\u2502  - Username enumeration prevention                              \u2502\n\u2514\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2518\n                              \u2193\n\u250c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2510\n\u2502 Layer 3: Application Security                                   \u2502\n\u2502  - Input validation on all file operations                      \u2502\n\u2502  - Path traversal prevention (virtual file system)              \u2502\n\u2502  - Per-user directory isolation                                 \u2502\n\u2514\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2518\n                              \u2193\n\u250c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2510\n\u2502 Layer 4: Data At Rest Encryption (DARE)                         \u2502\n\u2502  - AES-256-GCM per-chunk encryption                             \u2502\n\u2502  - Per-chunk authentication tags                                \u2502\n\u2502  - Associated data binding (prevents chunk attacks)             \u2502\n\u2502  - Zero plaintext on disk                                       \u2502\n\u2514\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2518\n                              \u2193\n\u250c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2510\n\u2502 Layer 5: Storage Security                                       \u2502\n\u2502  - Encrypted keyset storage                                     \u2502\n\u2502  - File system permissions                                      \u2502\n\u2502  - Physical security (server hosting environment)               \u2502\n\u2514\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2518\n<\/textarea><\/pre><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" style=\"width:24px;height:24px\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" stroke-width=\"2\"><path class=\"with-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M4.5 12.75l6 6 9-13.5\"><\/path><path class=\"without-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M16.5 8.25V6a2.25 2.25 0 00-2.25-2.25H6A2.25 2.25 0 003.75 6v8.25A2.25 2.25 0 006 16.5h2.25m8.25-8.25H18a2.25 2.25 0 012.25 2.25V18A2.25 2.25 0 0118 20.25h-7.5A2.25 2.25 0 018.25 18v-1.5m8.25-8.25h-6a2.25 2.25 0 00-2.25 2.25v6\"><\/path><\/svg><\/span><pre class=\"shiki one-dark-pro\" style=\"background-color: #282c34\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color: #61AFEF\">\u250c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2510<\/span><\/span>\n<span class=\"line\"><span style=\"color: #61AFEF\">\u2502<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">Layer<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #D19A66\">1<\/span><span style=\"color: #98C379\">:<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">Network<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">Security<\/span><span style=\"color: #ABB2BF\">                                       <\/span><span style=\"color: #98C379\">\u2502<\/span><\/span>\n<span class=\"line\"><span style=\"color: #61AFEF\">\u2502<\/span><span style=\"color: #ABB2BF\">  <\/span><span style=\"color: #98C379\">-<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">SSH<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">protocol<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">encryption<\/span><span style=\"color: #ABB2BF\"> (client <\/span><span style=\"color: #98C379\">\u2190<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">\u2192<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">server<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">transport<\/span><span style=\"color: #ABB2BF\">)        \u2502<\/span><\/span>\n<span class=\"line\"><span style=\"color: #61AFEF\">\u2502<\/span><span style=\"color: #ABB2BF\">  <\/span><span style=\"color: #98C379\">-<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">Host<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">key<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">verification<\/span><span style=\"color: #ABB2BF\">                                        <\/span><span style=\"color: #98C379\">\u2502<\/span><\/span>\n<span class=\"line\"><span style=\"color: #61AFEF\">\u2502<\/span><span style=\"color: #ABB2BF\">  <\/span><span style=\"color: #98C379\">-<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">Port-based<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">access<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">control<\/span><span style=\"color: #ABB2BF\">                                    <\/span><span style=\"color: #98C379\">\u2502<\/span><\/span>\n<span class=\"line\"><span style=\"color: #61AFEF\">\u2514\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2518<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">                              <\/span><span style=\"color: #61AFEF\">\u2193<\/span><\/span>\n<span class=\"line\"><span style=\"color: #61AFEF\">\u250c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2510<\/span><\/span>\n<span class=\"line\"><span style=\"color: #61AFEF\">\u2502<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">Layer<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #D19A66\">2<\/span><span style=\"color: #98C379\">:<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">Authentication<\/span><span style=\"color: #ABB2BF\">                                         <\/span><span style=\"color: #98C379\">\u2502<\/span><\/span>\n<span class=\"line\"><span style=\"color: #61AFEF\">\u2502<\/span><span style=\"color: #ABB2BF\">  <\/span><span style=\"color: #98C379\">-<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">PBKDF2-HMAC-SHA256<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">password<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">hashing<\/span><span style=\"color: #ABB2BF\"> (100K <\/span><span style=\"color: #98C379\">iterations<\/span><span style=\"color: #ABB2BF\">)        \u2502<\/span><\/span>\n<span class=\"line\"><span style=\"color: #61AFEF\">\u2502<\/span><span style=\"color: #ABB2BF\">  <\/span><span style=\"color: #98C379\">-<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">Constant-time<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">comparison<\/span><span style=\"color: #ABB2BF\"> (timing <\/span><span style=\"color: #98C379\">attack<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">prevention<\/span><span style=\"color: #ABB2BF\">)          \u2502<\/span><\/span>\n<span class=\"line\"><span style=\"color: #61AFEF\">\u2502<\/span><span style=\"color: #ABB2BF\">  <\/span><span style=\"color: #98C379\">-<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">Username<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">enumeration<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">prevention<\/span><span style=\"color: #ABB2BF\">                              <\/span><span style=\"color: #98C379\">\u2502<\/span><\/span>\n<span class=\"line\"><span style=\"color: #61AFEF\">\u2514\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2518<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">                              <\/span><span style=\"color: #61AFEF\">\u2193<\/span><\/span>\n<span class=\"line\"><span style=\"color: #61AFEF\">\u250c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2510<\/span><\/span>\n<span class=\"line\"><span style=\"color: #61AFEF\">\u2502<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">Layer<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #D19A66\">3<\/span><span style=\"color: #98C379\">:<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">Application<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">Security<\/span><span style=\"color: #ABB2BF\">                                   <\/span><span style=\"color: #98C379\">\u2502<\/span><\/span>\n<span class=\"line\"><span style=\"color: #61AFEF\">\u2502<\/span><span style=\"color: #ABB2BF\">  <\/span><span style=\"color: #98C379\">-<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">Input<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">validation<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">on<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">all<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">file<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">operations<\/span><span style=\"color: #ABB2BF\">                      <\/span><span style=\"color: #98C379\">\u2502<\/span><\/span>\n<span class=\"line\"><span style=\"color: #61AFEF\">\u2502<\/span><span style=\"color: #ABB2BF\">  <\/span><span style=\"color: #98C379\">-<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">Path<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">traversal<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">prevention<\/span><span style=\"color: #ABB2BF\"> (virtual <\/span><span style=\"color: #98C379\">file<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">system<\/span><span style=\"color: #ABB2BF\">)              \u2502<\/span><\/span>\n<span class=\"line\"><span style=\"color: #61AFEF\">\u2502<\/span><span style=\"color: #ABB2BF\">  <\/span><span style=\"color: #98C379\">-<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">Per-user<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">directory<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">isolation<\/span><span style=\"color: #ABB2BF\">                                 <\/span><span style=\"color: #98C379\">\u2502<\/span><\/span>\n<span class=\"line\"><span style=\"color: #61AFEF\">\u2514\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2518<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">                              <\/span><span style=\"color: #61AFEF\">\u2193<\/span><\/span>\n<span class=\"line\"><span style=\"color: #61AFEF\">\u250c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2510<\/span><\/span>\n<span class=\"line\"><span style=\"color: #61AFEF\">\u2502<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">Layer<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #D19A66\">4<\/span><span style=\"color: #98C379\">:<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">Data<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">At<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">Rest<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">Encryption<\/span><span style=\"color: #ABB2BF\"> (DARE)                         \u2502<\/span><\/span>\n<span class=\"line\"><span style=\"color: #61AFEF\">\u2502<\/span><span style=\"color: #ABB2BF\">  <\/span><span style=\"color: #98C379\">-<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">AES-256-GCM<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">per-chunk<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">encryption<\/span><span style=\"color: #ABB2BF\">                             <\/span><span style=\"color: #98C379\">\u2502<\/span><\/span>\n<span class=\"line\"><span style=\"color: #61AFEF\">\u2502<\/span><span style=\"color: #ABB2BF\">  <\/span><span style=\"color: #98C379\">-<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">Per-chunk<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">authentication<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">tags<\/span><span style=\"color: #ABB2BF\">                                <\/span><span style=\"color: #98C379\">\u2502<\/span><\/span>\n<span class=\"line\"><span style=\"color: #61AFEF\">\u2502<\/span><span style=\"color: #ABB2BF\">  <\/span><span style=\"color: #98C379\">-<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">Associated<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">data<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">binding<\/span><span style=\"color: #ABB2BF\"> (prevents <\/span><span style=\"color: #98C379\">chunk<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">attacks<\/span><span style=\"color: #ABB2BF\">)             \u2502<\/span><\/span>\n<span class=\"line\"><span style=\"color: #61AFEF\">\u2502<\/span><span style=\"color: #ABB2BF\">  <\/span><span style=\"color: #98C379\">-<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">Zero<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">plaintext<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">on<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">disk<\/span><span style=\"color: #ABB2BF\">                                       <\/span><span style=\"color: #98C379\">\u2502<\/span><\/span>\n<span class=\"line\"><span style=\"color: #61AFEF\">\u2514\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2518<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">                              <\/span><span style=\"color: #61AFEF\">\u2193<\/span><\/span>\n<span class=\"line\"><span style=\"color: #61AFEF\">\u250c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2510<\/span><\/span>\n<span class=\"line\"><span style=\"color: #61AFEF\">\u2502<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">Layer<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #D19A66\">5<\/span><span style=\"color: #98C379\">:<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">Storage<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">Security<\/span><span style=\"color: #ABB2BF\">                                       <\/span><span style=\"color: #98C379\">\u2502<\/span><\/span>\n<span class=\"line\"><span style=\"color: #61AFEF\">\u2502<\/span><span style=\"color: #ABB2BF\">  <\/span><span style=\"color: #98C379\">-<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">Encrypted<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">keyset<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">storage<\/span><span style=\"color: #ABB2BF\">                                     <\/span><span style=\"color: #98C379\">\u2502<\/span><\/span>\n<span class=\"line\"><span style=\"color: #61AFEF\">\u2502<\/span><span style=\"color: #ABB2BF\">  <\/span><span style=\"color: #98C379\">-<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">File<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">system<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">permissions<\/span><span style=\"color: #ABB2BF\">                                      <\/span><span style=\"color: #98C379\">\u2502<\/span><\/span>\n<span class=\"line\"><span style=\"color: #61AFEF\">\u2502<\/span><span style=\"color: #ABB2BF\">  <\/span><span style=\"color: #98C379\">-<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">Physical<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">security<\/span><span style=\"color: #ABB2BF\"> (server <\/span><span style=\"color: #98C379\">hosting<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">environment<\/span><span style=\"color: #ABB2BF\">)               \u2502<\/span><\/span>\n<span class=\"line\"><span style=\"color: #61AFEF\">\u2514\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2518<\/span><\/span>\n<span class=\"line\"><\/span><\/code><\/pre><\/div>\n\n\n\n<h3 class=\"sera-block-heading\">Encryption Key Hierarchy<\/h3>\n\n\n\n<div class=\"sera-block-kevinbatdorf-code-block-pro cbp-has-line-numbers\" data-code-block-pro-font-family=\"Code-Pro-JetBrains-Mono\" style=\"font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;--cbp-line-number-color:#abb2bf;--cbp-line-number-width:calc(2 * 0.6 * .875rem);line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)\"><span role=\"button\" tabindex=\"0\" style=\"color:#abb2bf;display:none\" aria-label=\"Copy\" class=\"code-block-pro-copy-button\"><pre class=\"code-block-pro-copy-button-pre\" aria-hidden=\"true\"><textarea class=\"code-block-pro-copy-button-textarea\" tabindex=\"-1\" aria-hidden=\"true\" readonly>\u250c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2510\n\u2502              Master Key (from KMS or secure vault)           \u2502\n\u2502                    256-bit AES key                           \u2502\n\u2514\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u252c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2518\n                          \u2502 (encrypts)\n                          \u2193\n\u250c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2510\n\u2502              Data Encryption Keyset (Tink)                   \u2502\n\u2502           Stored encrypted in keyset.json                    \u2502\n\u2514\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u252c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2518\n                          \u2502 (provides)\n                          \u2193\n\u250c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2510\n\u2502         File Encryption Key (AES-256-GCM)                    \u2502\n\u2502          Generated by Google Tink, rotatable                 \u2502\n\u2514\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u252c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2518\n                          \u2502 (encrypts)\n                          \u2193\n\u250c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2510\n\u2502              Individual File Chunks                          \u2502\n\u2502      Each chunk: plaintext + AAD \u2192 ciphertext + tag          \u2502\n\u2514\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2518\n<\/textarea><\/pre><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" style=\"width:24px;height:24px\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" stroke-width=\"2\"><path class=\"with-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M4.5 12.75l6 6 9-13.5\"><\/path><path class=\"without-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M16.5 8.25V6a2.25 2.25 0 00-2.25-2.25H6A2.25 2.25 0 003.75 6v8.25A2.25 2.25 0 006 16.5h2.25m8.25-8.25H18a2.25 2.25 0 012.25 2.25V18A2.25 2.25 0 0118 20.25h-7.5A2.25 2.25 0 018.25 18v-1.5m8.25-8.25h-6a2.25 2.25 0 00-2.25 2.25v6\"><\/path><\/svg><\/span><pre class=\"shiki one-dark-pro\" style=\"background-color: #282c34\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color: #61AFEF\">\u250c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2510<\/span><\/span>\n<span class=\"line\"><span style=\"color: #61AFEF\">\u2502<\/span><span style=\"color: #ABB2BF\">              <\/span><span style=\"color: #98C379\">Master<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">Key<\/span><span style=\"color: #ABB2BF\"> (from <\/span><span style=\"color: #98C379\">KMS<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">or<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">secure<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">vault<\/span><span style=\"color: #ABB2BF\">)           \u2502<\/span><\/span>\n<span class=\"line\"><span style=\"color: #61AFEF\">\u2502<\/span><span style=\"color: #ABB2BF\">                    <\/span><span style=\"color: #D19A66\">256<\/span><span style=\"color: #98C379\">-bit<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">AES<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">key<\/span><span style=\"color: #ABB2BF\">                           <\/span><span style=\"color: #98C379\">\u2502<\/span><\/span>\n<span class=\"line\"><span style=\"color: #61AFEF\">\u2514\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u252c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2518<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">                          <\/span><span style=\"color: #61AFEF\">\u2502<\/span><span style=\"color: #ABB2BF\"> (encrypts)<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">                          <\/span><span style=\"color: #61AFEF\">\u2193<\/span><\/span>\n<span class=\"line\"><span style=\"color: #61AFEF\">\u250c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2510<\/span><\/span>\n<span class=\"line\"><span style=\"color: #61AFEF\">\u2502<\/span><span style=\"color: #ABB2BF\">              <\/span><span style=\"color: #98C379\">Data<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">Encryption<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">Keyset<\/span><span style=\"color: #ABB2BF\"> (Tink)                   \u2502<\/span><\/span>\n<span class=\"line\"><span style=\"color: #61AFEF\">\u2502<\/span><span style=\"color: #ABB2BF\">           <\/span><span style=\"color: #98C379\">Stored<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">encrypted<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">in<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">keyset.json<\/span><span style=\"color: #ABB2BF\">                    <\/span><span style=\"color: #98C379\">\u2502<\/span><\/span>\n<span class=\"line\"><span style=\"color: #61AFEF\">\u2514\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u252c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2518<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">                          <\/span><span style=\"color: #61AFEF\">\u2502<\/span><span style=\"color: #ABB2BF\"> (provides)<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">                          <\/span><span style=\"color: #61AFEF\">\u2193<\/span><\/span>\n<span class=\"line\"><span style=\"color: #61AFEF\">\u250c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2510<\/span><\/span>\n<span class=\"line\"><span style=\"color: #61AFEF\">\u2502<\/span><span style=\"color: #ABB2BF\">         <\/span><span style=\"color: #98C379\">File<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">Encryption<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">Key<\/span><span style=\"color: #ABB2BF\"> (AES-256-GCM)                    \u2502<\/span><\/span>\n<span class=\"line\"><span style=\"color: #61AFEF\">\u2502<\/span><span style=\"color: #ABB2BF\">          <\/span><span style=\"color: #98C379\">Generated<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">by<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">Google<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">Tink,<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">rotatable<\/span><span style=\"color: #ABB2BF\">                 <\/span><span style=\"color: #98C379\">\u2502<\/span><\/span>\n<span class=\"line\"><span style=\"color: #61AFEF\">\u2514\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u252c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2518<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">                          <\/span><span style=\"color: #61AFEF\">\u2502<\/span><span style=\"color: #ABB2BF\"> (encrypts)<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">                          <\/span><span style=\"color: #61AFEF\">\u2193<\/span><\/span>\n<span class=\"line\"><span style=\"color: #61AFEF\">\u250c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2510<\/span><\/span>\n<span class=\"line\"><span style=\"color: #61AFEF\">\u2502<\/span><span style=\"color: #ABB2BF\">              <\/span><span style=\"color: #98C379\">Individual<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">File<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">Chunks<\/span><span style=\"color: #ABB2BF\">                          <\/span><span style=\"color: #98C379\">\u2502<\/span><\/span>\n<span class=\"line\"><span style=\"color: #61AFEF\">\u2502<\/span><span style=\"color: #ABB2BF\">      <\/span><span style=\"color: #98C379\">Each<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">chunk:<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">plaintext<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">+<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">AAD<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">\u2192<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">ciphertext<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">+<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">tag<\/span><span style=\"color: #ABB2BF\">          <\/span><span style=\"color: #98C379\">\u2502<\/span><\/span>\n<span class=\"line\"><span style=\"color: #61AFEF\">\u2514\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2518<\/span><\/span>\n<span class=\"line\"><\/span><\/code><\/pre><\/div>\n\n\n\n<h3 class=\"sera-block-heading\">Threat Model &amp; Mitigations<\/h3>\n\n\n\n<figure class=\"sera-block-table\"><table class=\"has-fixed-layout\"><thead><tr><th>Threat<\/th><th>Mitigation<\/th><\/tr><\/thead><tbody><tr><td><strong>Disk theft \/ unauthorized physical access<\/strong><\/td><td>All files encrypted with AES-256-GCM, zero plaintext on disk<\/td><\/tr><tr><td><strong>Chunk reordering attack<\/strong><\/td><td>Associated data includes chunk index, prevents reordering<\/td><\/tr><tr><td><strong>Chunk substitution attack<\/strong><\/td><td>Associated data includes filename, prevents cross-file attacks<\/td><\/tr><tr><td><strong>Timing attacks on authentication<\/strong><\/td><td>Constant-time password comparison<\/td><\/tr><tr><td><strong>Username enumeration<\/strong><\/td><td>Dummy hash performed for invalid usernames<\/td><\/tr><tr><td><strong>Password brute force<\/strong><\/td><td>PBKDF2 with 100K iterations slows attempts<\/td><\/tr><tr><td><strong>Man-in-the-middle (transport)<\/strong><\/td><td>SSH protocol encryption (separate from DARE)<\/td><\/tr><tr><td><strong>Replay attacks<\/strong><\/td><td>GCM nonces prevent ciphertext replay<\/td><\/tr><tr><td><strong>Chunk corruption<\/strong><\/td><td>GCM authentication tags detect tampering<\/td><\/tr><\/tbody><\/table><\/figure>\n\n\n\n<hr class=\"sera-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h2 class=\"sera-block-heading\">Installation &amp; Setup<\/h2>\n\n\n\n<h3 class=\"sera-block-heading\">Prerequisites<\/h3>\n\n\n\n<div class=\"sera-block-kevinbatdorf-code-block-pro cbp-has-line-numbers\" data-code-block-pro-font-family=\"Code-Pro-JetBrains-Mono\" style=\"font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;--cbp-line-number-color:#abb2bf;--cbp-line-number-width:calc(1 * 0.6 * .875rem);line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)\"><span role=\"button\" tabindex=\"0\" style=\"color:#abb2bf;display:none\" aria-label=\"Copy\" class=\"code-block-pro-copy-button\"><pre class=\"code-block-pro-copy-button-pre\" aria-hidden=\"true\"><textarea class=\"code-block-pro-copy-button-textarea\" tabindex=\"-1\" aria-hidden=\"true\" readonly># Java 11 or higher\njava -version\n\n# Maven 3.6+ (for building)\nmvn -version\n\n# Git (for cloning)\ngit -version\n<\/textarea><\/pre><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" style=\"width:24px;height:24px\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" stroke-width=\"2\"><path class=\"with-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M4.5 12.75l6 6 9-13.5\"><\/path><path class=\"without-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M16.5 8.25V6a2.25 2.25 0 00-2.25-2.25H6A2.25 2.25 0 003.75 6v8.25A2.25 2.25 0 006 16.5h2.25m8.25-8.25H18a2.25 2.25 0 012.25 2.25V18A2.25 2.25 0 0118 20.25h-7.5A2.25 2.25 0 018.25 18v-1.5m8.25-8.25h-6a2.25 2.25 0 00-2.25 2.25v6\"><\/path><\/svg><\/span><pre class=\"shiki one-dark-pro\" style=\"background-color: #282c34\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color: #7F848E; font-style: italic\"># Java 11 or higher<\/span><\/span>\n<span class=\"line\"><span style=\"color: #61AFEF\">java<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #D19A66\">-version<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #7F848E; font-style: italic\"># Maven 3.6+ (for building)<\/span><\/span>\n<span class=\"line\"><span style=\"color: #61AFEF\">mvn<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #D19A66\">-version<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #7F848E; font-style: italic\"># Git (for cloning)<\/span><\/span>\n<span class=\"line\"><span style=\"color: #61AFEF\">git<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #D19A66\">-version<\/span><\/span>\n<span class=\"line\"><\/span><\/code><\/pre><\/div>\n\n\n\n<h3 class=\"sera-block-heading\">Build from Source<\/h3>\n\n\n\n<div class=\"sera-block-kevinbatdorf-code-block-pro cbp-has-line-numbers\" data-code-block-pro-font-family=\"Code-Pro-JetBrains-Mono\" style=\"font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;--cbp-line-number-color:#abb2bf;--cbp-line-number-width:calc(1 * 0.6 * .875rem);line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)\"><span role=\"button\" tabindex=\"0\" style=\"color:#abb2bf;display:none\" aria-label=\"Copy\" class=\"code-block-pro-copy-button\"><pre class=\"code-block-pro-copy-button-pre\" aria-hidden=\"true\"><textarea class=\"code-block-pro-copy-button-textarea\" tabindex=\"-1\" aria-hidden=\"true\" readonly># Clone repository\ngit clone https:\/\/github.com\/PortaSFTPServer\/MinaSSHDDataAtRestEncryptionSample.git \ncd MinaSSHDDataAtRestEncryptionSample\n\n# Build with Maven\nmvn clean package\n\n# Output: target\/MinaSSHDDataAtRestEncryptionSample-1.0-SNAPSHOT.jar\n<\/textarea><\/pre><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" style=\"width:24px;height:24px\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" stroke-width=\"2\"><path class=\"with-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M4.5 12.75l6 6 9-13.5\"><\/path><path class=\"without-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M16.5 8.25V6a2.25 2.25 0 00-2.25-2.25H6A2.25 2.25 0 003.75 6v8.25A2.25 2.25 0 006 16.5h2.25m8.25-8.25H18a2.25 2.25 0 012.25 2.25V18A2.25 2.25 0 0118 20.25h-7.5A2.25 2.25 0 018.25 18v-1.5m8.25-8.25h-6a2.25 2.25 0 00-2.25 2.25v6\"><\/path><\/svg><\/span><pre class=\"shiki one-dark-pro\" style=\"background-color: #282c34\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color: #7F848E; font-style: italic\"># Clone repository<\/span><\/span>\n<span class=\"line\"><span style=\"color: #61AFEF\">git<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">clone<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">https:\/\/github.com\/PortaSFTPServer\/MinaSSHDDataAtRestEncryptionSample.git<\/span><span style=\"color: #ABB2BF\"> <\/span><\/span>\n<span class=\"line\"><span style=\"color: #56B6C2\">cd<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">MinaSSHDDataAtRestEncryptionSample<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #7F848E; font-style: italic\"># Build with Maven<\/span><\/span>\n<span class=\"line\"><span style=\"color: #61AFEF\">mvn<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">clean<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">package<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #7F848E; font-style: italic\"># Output: target\/MinaSSHDDataAtRestEncryptionSample-1.0-SNAPSHOT.jar<\/span><\/span>\n<span class=\"line\"><\/span><\/code><\/pre><\/div>\n\n\n\n<h3 class=\"sera-block-heading\">Build Configuration<\/h3>\n\n\n\n<p class=\"sera-block-paragraph\">The <code>pom.xml<\/code> includes Maven Shade Plugin for creating an executable JAR:<\/p>\n\n\n\n<div class=\"sera-block-kevinbatdorf-code-block-pro cbp-has-line-numbers\" data-code-block-pro-font-family=\"Code-Pro-JetBrains-Mono\" style=\"font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;--cbp-line-number-color:#abb2bf;--cbp-line-number-width:calc(2 * 0.6 * .875rem);line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)\"><span role=\"button\" tabindex=\"0\" style=\"color:#abb2bf;display:none\" aria-label=\"Copy\" class=\"code-block-pro-copy-button\"><pre class=\"code-block-pro-copy-button-pre\" aria-hidden=\"true\"><textarea class=\"code-block-pro-copy-button-textarea\" tabindex=\"-1\" aria-hidden=\"true\" readonly>&lt;plugin>\n    &lt;groupId>org.apache.maven.plugins&lt;\/groupId>\n    &lt;artifactId>maven-shade-plugin&lt;\/artifactId>\n    &lt;version>3.5.3&lt;\/version>\n    &lt;configuration>\n        &lt;transformers>\n            &lt;transformer implementation=\"...ManifestResourceTransformer\">\n                &lt;mainClass>com.portasftpserver.minasshddataatrestencryptionsample.ChunkedEncryptedSftpServer&lt;\/mainClass>\n            &lt;\/transformer>\n        &lt;\/transformers>\n        &lt;!-- Exclude signature files -->\n        &lt;filters>\n            &lt;filter>\n                &lt;artifact>*:*&lt;\/artifact>\n                &lt;excludes>\n                    &lt;exclude>META-INF\/*.SF&lt;\/exclude>\n                    &lt;exclude>META-INF\/*.DSA&lt;\/exclude>\n                    &lt;exclude>META-INF\/*.RSA&lt;\/exclude>\n                &lt;\/excludes>\n            &lt;\/filter>\n        &lt;\/filters>\n    &lt;\/configuration>\n&lt;\/plugin>\n<\/textarea><\/pre><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" style=\"width:24px;height:24px\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" stroke-width=\"2\"><path class=\"with-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M4.5 12.75l6 6 9-13.5\"><\/path><path class=\"without-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M16.5 8.25V6a2.25 2.25 0 00-2.25-2.25H6A2.25 2.25 0 003.75 6v8.25A2.25 2.25 0 006 16.5h2.25m8.25-8.25H18a2.25 2.25 0 012.25 2.25V18A2.25 2.25 0 0118 20.25h-7.5A2.25 2.25 0 018.25 18v-1.5m8.25-8.25h-6a2.25 2.25 0 00-2.25 2.25v6\"><\/path><\/svg><\/span><pre class=\"shiki one-dark-pro\" style=\"background-color: #282c34\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color: #ABB2BF\">&lt;plugin&gt;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">    &lt;<\/span><span style=\"color: #61AFEF\">groupId&gt;org.apache.maven.plugins&lt;\/groupId&gt;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">    &lt;<\/span><span style=\"color: #61AFEF\">artifactId&gt;maven-shade-plugin&lt;\/artifactId&gt;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">    &lt;<\/span><span style=\"color: #61AFEF\">version&gt;3.5.3&lt;\/version&gt;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">    &lt;<\/span><span style=\"color: #61AFEF\">configuration&gt;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">        &lt;<\/span><span style=\"color: #61AFEF\">transformers&gt;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">            &lt;<\/span><span style=\"color: #61AFEF\">transformer<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">implementation=&quot;...ManifestResourceTransformer&quot;<\/span><span style=\"color: #ABB2BF\">&gt;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">                &lt;<\/span><span style=\"color: #61AFEF\">mainClass&gt;com.portasftpserver.minasshddataatrestencryptionsample.ChunkedEncryptedSftpServer&lt;\/mainClass&gt;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">            &lt;<\/span><span style=\"color: #61AFEF\">\/transformer&gt;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">        &lt;<\/span><span style=\"color: #61AFEF\">\/transformers&gt;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">        &lt;!<\/span><span style=\"color: #61AFEF\">--<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">Exclude<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">signature<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">files<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #D19A66\">--<\/span><span style=\"color: #ABB2BF\">&gt;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">        &lt;<\/span><span style=\"color: #61AFEF\">filters&gt;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">            &lt;<\/span><span style=\"color: #61AFEF\">filter&gt;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">                &lt;<\/span><span style=\"color: #61AFEF\">artifact&gt;*:*&lt;\/artifact&gt;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">                &lt;<\/span><span style=\"color: #61AFEF\">excludes&gt;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">                    &lt;<\/span><span style=\"color: #61AFEF\">exclude&gt;META-INF\/*.SF&lt;\/exclude&gt;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">                    &lt;<\/span><span style=\"color: #61AFEF\">exclude&gt;META-INF\/*.DSA&lt;\/exclude&gt;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">                    &lt;<\/span><span style=\"color: #61AFEF\">exclude&gt;META-INF\/*.RSA&lt;\/exclude&gt;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">                &lt;<\/span><span style=\"color: #61AFEF\">\/excludes&gt;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">            &lt;<\/span><span style=\"color: #61AFEF\">\/filter&gt;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">        &lt;<\/span><span style=\"color: #61AFEF\">\/filters&gt;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">    &lt;<\/span><span style=\"color: #61AFEF\">\/configuration&gt;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">&lt;\/plugin&gt;<\/span><\/span>\n<span class=\"line\"><\/span><\/code><\/pre><\/div>\n\n\n\n<h3 class=\"sera-block-heading\">First Run<\/h3>\n\n\n\n<pre class=\"sera-block-code\"><code># Run with defaults\njava -jar target\/MinaSSHDDataAtRestEncryptionSample-1.0-SNAPSHOT.jar\n\n# Server will:\n# 1. Generate encryption keyset (.\/keyset.json)\n# 2. Create storage directory (.\/sftp-storage)\n# 3. Initialize default users\n# 4. Start on port 2222\n<\/code><\/pre>\n\n\n\n<h3 class=\"sera-block-heading\">Directory Structure After First Run<\/h3>\n\n\n\n<div class=\"sera-block-kevinbatdorf-code-block-pro cbp-has-line-numbers\" data-code-block-pro-font-family=\"Code-Pro-JetBrains-Mono\" style=\"font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;--cbp-line-number-color:#abb2bf;--cbp-line-number-width:calc(1 * 0.6 * .875rem);line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)\"><span role=\"button\" tabindex=\"0\" style=\"color:#abb2bf;display:none\" aria-label=\"Copy\" class=\"code-block-pro-copy-button\"><pre class=\"code-block-pro-copy-button-pre\" aria-hidden=\"true\"><textarea class=\"code-block-pro-copy-button-textarea\" tabindex=\"-1\" aria-hidden=\"true\" readonly>project-root\/\n\u251c\u2500\u2500 keyset.json                    # Encrypted encryption keyset\n\u251c\u2500\u2500 hostkey.ser                    # SSH host key\n\u251c\u2500\u2500 sftp-storage\/                  # Storage root\n\u2502   \u251c\u2500\u2500 admin\/                     # User: admin\n\u2502   \u2514\u2500\u2500 testuser\/                  # User: testuser\n\u2514\u2500\u2500 target\/\n    \u2514\u2500\u2500 MinaSSHDDataAtRestEncryptionSample-1.0-SNAPSHOT.jar\n<\/textarea><\/pre><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" style=\"width:24px;height:24px\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" stroke-width=\"2\"><path class=\"with-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M4.5 12.75l6 6 9-13.5\"><\/path><path class=\"without-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M16.5 8.25V6a2.25 2.25 0 00-2.25-2.25H6A2.25 2.25 0 003.75 6v8.25A2.25 2.25 0 006 16.5h2.25m8.25-8.25H18a2.25 2.25 0 012.25 2.25V18A2.25 2.25 0 0118 20.25h-7.5A2.25 2.25 0 018.25 18v-1.5m8.25-8.25h-6a2.25 2.25 0 00-2.25 2.25v6\"><\/path><\/svg><\/span><pre class=\"shiki one-dark-pro\" style=\"background-color: #282c34\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color: #61AFEF\">project-root\/<\/span><\/span>\n<span class=\"line\"><span style=\"color: #61AFEF\">\u251c\u2500\u2500<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">keyset.json<\/span><span style=\"color: #ABB2BF\">                    <\/span><span style=\"color: #7F848E; font-style: italic\"># Encrypted encryption keyset<\/span><\/span>\n<span class=\"line\"><span style=\"color: #61AFEF\">\u251c\u2500\u2500<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">hostkey.ser<\/span><span style=\"color: #ABB2BF\">                    <\/span><span style=\"color: #7F848E; font-style: italic\"># SSH host key<\/span><\/span>\n<span class=\"line\"><span style=\"color: #61AFEF\">\u251c\u2500\u2500<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">sftp-storage\/<\/span><span style=\"color: #ABB2BF\">                  <\/span><span style=\"color: #7F848E; font-style: italic\"># Storage root<\/span><\/span>\n<span class=\"line\"><span style=\"color: #61AFEF\">\u2502<\/span><span style=\"color: #ABB2BF\">   <\/span><span style=\"color: #98C379\">\u251c\u2500\u2500<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">admin\/<\/span><span style=\"color: #ABB2BF\">                     <\/span><span style=\"color: #7F848E; font-style: italic\"># User: admin<\/span><\/span>\n<span class=\"line\"><span style=\"color: #61AFEF\">\u2502<\/span><span style=\"color: #ABB2BF\">   <\/span><span style=\"color: #98C379\">\u2514\u2500\u2500<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">testuser\/<\/span><span style=\"color: #ABB2BF\">                  <\/span><span style=\"color: #7F848E; font-style: italic\"># User: testuser<\/span><\/span>\n<span class=\"line\"><span style=\"color: #61AFEF\">\u2514\u2500\u2500<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">target\/<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">    <\/span><span style=\"color: #61AFEF\">\u2514\u2500\u2500<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">MinaSSHDDataAtRestEncryptionSample-1.0-SNAPSHOT.jar<\/span><\/span>\n<span class=\"line\"><\/span><\/code><\/pre><\/div>\n\n\n\n<hr class=\"sera-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h2 class=\"sera-block-heading\">Configuration<\/h2>\n\n\n\n<h3 class=\"sera-block-heading\">System Properties<\/h3>\n\n\n\n<p class=\"sera-block-paragraph\">Configure server behavior via Java system properties:<\/p>\n\n\n\n<div class=\"sera-block-kevinbatdorf-code-block-pro cbp-has-line-numbers\" data-code-block-pro-font-family=\"Code-Pro-JetBrains-Mono\" style=\"font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;--cbp-line-number-color:#abb2bf;--cbp-line-number-width:calc(1 * 0.6 * .875rem);line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)\"><span role=\"button\" tabindex=\"0\" style=\"color:#abb2bf;display:none\" aria-label=\"Copy\" class=\"code-block-pro-copy-button\"><pre class=\"code-block-pro-copy-button-pre\" aria-hidden=\"true\"><textarea class=\"code-block-pro-copy-button-textarea\" tabindex=\"-1\" aria-hidden=\"true\" readonly>java -Dsftp.port=2222 \\\n     -Dsftp.storage=\/data\/sftp \\\n     -Dsftp.keyset=\/keys\/keyset.json \\\n     -Dsftp.chunk.size=131072 \\\n     -Dsftp.use.enc.extension=false \\\n     -jar sftp-server.jar\n<\/textarea><\/pre><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" style=\"width:24px;height:24px\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" stroke-width=\"2\"><path class=\"with-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M4.5 12.75l6 6 9-13.5\"><\/path><path class=\"without-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M16.5 8.25V6a2.25 2.25 0 00-2.25-2.25H6A2.25 2.25 0 003.75 6v8.25A2.25 2.25 0 006 16.5h2.25m8.25-8.25H18a2.25 2.25 0 012.25 2.25V18A2.25 2.25 0 0118 20.25h-7.5A2.25 2.25 0 018.25 18v-1.5m8.25-8.25h-6a2.25 2.25 0 00-2.25 2.25v6\"><\/path><\/svg><\/span><pre class=\"shiki one-dark-pro\" style=\"background-color: #282c34\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color: #61AFEF\">java<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #D19A66\">-Dsftp.port=2222<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #56B6C2\">\\<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">     <\/span><span style=\"color: #D19A66\">-Dsftp.storage=\/data\/sftp<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #56B6C2\">\\<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">     <\/span><span style=\"color: #D19A66\">-Dsftp.keyset=\/keys\/keyset.json<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #56B6C2\">\\<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">     <\/span><span style=\"color: #D19A66\">-Dsftp.chunk.size=131072<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #56B6C2\">\\<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">     <\/span><span style=\"color: #D19A66\">-Dsftp.use.enc.extension=false<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #56B6C2\">\\<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">     <\/span><span style=\"color: #D19A66\">-jar<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">sftp-server.jar<\/span><\/span>\n<span class=\"line\"><\/span><\/code><\/pre><\/div>\n\n\n\n<h3 class=\"sera-block-heading\">Configuration Reference<\/h3>\n\n\n\n<figure class=\"sera-block-table\"><table class=\"has-fixed-layout\"><thead><tr><th>Property<\/th><th>Default<\/th><th>Description<\/th><th>Valid Values<\/th><\/tr><\/thead><tbody><tr><td>sftp.port<\/td><td>2222<\/td><td>Server port<\/td><td>1-65535<\/td><\/tr><tr><td>sftp.storage<\/td><td>.\/sftp-storage<\/td><td>Storage root<\/td><td>Any valid path<\/td><\/tr><tr><td>sftp.keyset<\/td><td>.\/keyset.json<\/td><td>Keyset file<\/td><td>Any valid path<\/td><\/tr><tr><td>sftp.chunk.size<\/td><td>65536<\/td><td>Chunk size (bytes)<\/td><td>&gt; 0, recommend 64KB-1MB<\/td><\/tr><tr><td>sftp.use.enc.extension<\/td><td>false<\/td><td>Use .enc suffix<\/td><td>true \/ false<\/td><\/tr><tr><td><\/td><td><\/td><td><\/td><td><\/td><\/tr><\/tbody><\/table><\/figure>\n\n\n\n<h3 class=\"sera-block-heading\">Chunk Size Selection<\/h3>\n\n\n\n<figure class=\"sera-block-table\"><table class=\"has-fixed-layout\"><thead><tr><th>Chunk Size<\/th><th>Use Case<\/th><th>Pros<\/th><th>Cons<\/th><\/tr><\/thead><tbody><tr><td>16 KB<\/td><td>Small files, low memory<\/td><td>Fast random access<\/td><td>More overhead<\/td><\/tr><tr><td>64 KB<\/td><td>Default, balanced<\/td><td>Good balance<\/td><td>&#8211;<\/td><\/tr><tr><td>256 KB<\/td><td>Large files<\/td><td>Fewer chunks<\/td><td>Higher memory per file<\/td><\/tr><tr><td>1 MB<\/td><td>Very large files<\/td><td>Maximum efficiency<\/td><td>Slower random access<\/td><\/tr><tr><td><\/td><td><\/td><td><\/td><td><\/td><\/tr><\/tbody><\/table><\/figure>\n\n\n\n<p class=\"sera-block-paragraph\">Formula for memory usage per open file:<\/p>\n\n\n\n<div class=\"sera-block-kevinbatdorf-code-block-pro cbp-has-line-numbers\" data-code-block-pro-font-family=\"Code-Pro-JetBrains-Mono\" style=\"font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;--cbp-line-number-color:#abb2bf;--cbp-line-number-width:calc(1 * 0.6 * .875rem);line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)\"><span role=\"button\" tabindex=\"0\" style=\"color:#abb2bf;display:none\" aria-label=\"Copy\" class=\"code-block-pro-copy-button\"><pre class=\"code-block-pro-copy-button-pre\" aria-hidden=\"true\"><textarea class=\"code-block-pro-copy-button-textarea\" tabindex=\"-1\" aria-hidden=\"true\" readonly>Memory \u2248 chunk_size \u00d7 2 + overhead<\/textarea><\/pre><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" style=\"width:24px;height:24px\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" stroke-width=\"2\"><path class=\"with-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M4.5 12.75l6 6 9-13.5\"><\/path><path class=\"without-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M16.5 8.25V6a2.25 2.25 0 00-2.25-2.25H6A2.25 2.25 0 003.75 6v8.25A2.25 2.25 0 006 16.5h2.25m8.25-8.25H18a2.25 2.25 0 012.25 2.25V18A2.25 2.25 0 0118 20.25h-7.5A2.25 2.25 0 018.25 18v-1.5m8.25-8.25h-6a2.25 2.25 0 00-2.25 2.25v6\"><\/path><\/svg><\/span><pre class=\"shiki one-dark-pro\" style=\"background-color: #282c34\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color: #E06C75\">Memory<\/span><span style=\"color: #ABB2BF\"> \u2248 <\/span><span style=\"color: #E06C75\">chunk_size<\/span><span style=\"color: #ABB2BF\"> \u00d7 <\/span><span style=\"color: #D19A66\">2<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #56B6C2\">+<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #E06C75\">overhead<\/span><\/span><\/code><\/pre><\/div>\n\n\n\n<p class=\"sera-block-paragraph\">Example:<\/p>\n\n\n\n<ul class=\"sera-block-list\">\n<li>64KB chunks: ~130KB per open file<\/li>\n\n\n\n<li>256KB chunks: ~520KB per open file<\/li>\n<\/ul>\n\n\n\n<h3 class=\"sera-block-heading\">Production Configuration Example<\/h3>\n\n\n\n<div class=\"sera-block-kevinbatdorf-code-block-pro cbp-has-line-numbers\" data-code-block-pro-font-family=\"Code-Pro-JetBrains-Mono\" style=\"font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;--cbp-line-number-color:#abb2bf;--cbp-line-number-width:calc(2 * 0.6 * .875rem);line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)\"><span role=\"button\" tabindex=\"0\" style=\"color:#abb2bf;display:none\" aria-label=\"Copy\" class=\"code-block-pro-copy-button\"><pre class=\"code-block-pro-copy-button-pre\" aria-hidden=\"true\"><textarea class=\"code-block-pro-copy-button-textarea\" tabindex=\"-1\" aria-hidden=\"true\" readonly>#!\/bin\/bash\n\n# Production SFTP Server Startup Script\n\n# JVM Options\nJAVA_OPTS=\"-Xms1G -Xmx4G \\\n           -XX:+UseG1GC \\\n           -XX:MaxGCPauseMillis=200\"\n\n# Application Configuration\nAPP_OPTS=\"-Dsftp.port=2222 \\\n          -Dsftp.storage=\/data\/encrypted-sftp \\\n          -Dsftp.keyset=\/secure\/keys\/keyset.json \\\n          -Dsftp.chunk.size=65536 \\\n          -Dsftp.use.enc.extension=false\"\n\n# Logging Configuration\nLOG_OPTS=\"-Dlogback.configurationFile=\/etc\/sftp\/logback.xml\"\n\n# Run server\njava $JAVA_OPTS $APP_OPTS $LOG_OPTS \\\n     -jar \/opt\/sftp-server\/sftp-server.jar\n<\/textarea><\/pre><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" style=\"width:24px;height:24px\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" stroke-width=\"2\"><path class=\"with-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M4.5 12.75l6 6 9-13.5\"><\/path><path class=\"without-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M16.5 8.25V6a2.25 2.25 0 00-2.25-2.25H6A2.25 2.25 0 003.75 6v8.25A2.25 2.25 0 006 16.5h2.25m8.25-8.25H18a2.25 2.25 0 012.25 2.25V18A2.25 2.25 0 0118 20.25h-7.5A2.25 2.25 0 018.25 18v-1.5m8.25-8.25h-6a2.25 2.25 0 00-2.25 2.25v6\"><\/path><\/svg><\/span><pre class=\"shiki one-dark-pro\" style=\"background-color: #282c34\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color: #7F848E; font-style: italic\">#!\/bin\/bash<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #7F848E; font-style: italic\"># Production SFTP Server Startup Script<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #7F848E; font-style: italic\"># JVM Options<\/span><\/span>\n<span class=\"line\"><span style=\"color: #E06C75\">JAVA_OPTS<\/span><span style=\"color: #56B6C2\">=<\/span><span style=\"color: #98C379\">&quot;-Xms1G -Xmx4G <\/span><span style=\"color: #56B6C2\">\\<\/span><\/span>\n<span class=\"line\"><span style=\"color: #98C379\">           -XX:+UseG1GC <\/span><span style=\"color: #56B6C2\">\\<\/span><\/span>\n<span class=\"line\"><span style=\"color: #98C379\">           -XX:MaxGCPauseMillis=200&quot;<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #7F848E; font-style: italic\"># Application Configuration<\/span><\/span>\n<span class=\"line\"><span style=\"color: #E06C75\">APP_OPTS<\/span><span style=\"color: #56B6C2\">=<\/span><span style=\"color: #98C379\">&quot;-Dsftp.port=2222 <\/span><span style=\"color: #56B6C2\">\\<\/span><\/span>\n<span class=\"line\"><span style=\"color: #98C379\">          -Dsftp.storage=\/data\/encrypted-sftp <\/span><span style=\"color: #56B6C2\">\\<\/span><\/span>\n<span class=\"line\"><span style=\"color: #98C379\">          -Dsftp.keyset=\/secure\/keys\/keyset.json <\/span><span style=\"color: #56B6C2\">\\<\/span><\/span>\n<span class=\"line\"><span style=\"color: #98C379\">          -Dsftp.chunk.size=65536 <\/span><span style=\"color: #56B6C2\">\\<\/span><\/span>\n<span class=\"line\"><span style=\"color: #98C379\">          -Dsftp.use.enc.extension=false&quot;<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #7F848E; font-style: italic\"># Logging Configuration<\/span><\/span>\n<span class=\"line\"><span style=\"color: #E06C75\">LOG_OPTS<\/span><span style=\"color: #56B6C2\">=<\/span><span style=\"color: #98C379\">&quot;-Dlogback.configurationFile=\/etc\/sftp\/logback.xml&quot;<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #7F848E; font-style: italic\"># Run server<\/span><\/span>\n<span class=\"line\"><span style=\"color: #61AFEF\">java<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #E06C75\">$JAVA_OPTS<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #E06C75\">$APP_OPTS<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #E06C75\">$LOG_OPTS<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #56B6C2\">\\<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">     <\/span><span style=\"color: #D19A66\">-jar<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">\/opt\/sftp-server\/sftp-server.jar<\/span><\/span>\n<span class=\"line\"><\/span><\/code><\/pre><\/div>\n\n\n\n<h3 class=\"sera-block-heading\">Logback Configuration (Optional)<\/h3>\n\n\n\n<p class=\"sera-block-paragraph\">Create <code>logback.xml<\/code> for detailed logging:<\/p>\n\n\n\n<div class=\"sera-block-kevinbatdorf-code-block-pro cbp-has-line-numbers\" data-code-block-pro-font-family=\"Code-Pro-JetBrains-Mono\" style=\"font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;--cbp-line-number-color:#abb2bf;--cbp-line-number-width:calc(2 * 0.6 * .875rem);line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)\"><span role=\"button\" tabindex=\"0\" style=\"color:#abb2bf;display:none\" aria-label=\"Copy\" class=\"code-block-pro-copy-button\"><pre class=\"code-block-pro-copy-button-pre\" aria-hidden=\"true\"><textarea class=\"code-block-pro-copy-button-textarea\" tabindex=\"-1\" aria-hidden=\"true\" readonly>&lt;configuration>\n    &lt;appender name=\"FILE\" class=\"ch.qos.logback.core.rolling.RollingFileAppender\">\n        &lt;file>\/var\/log\/sftp-server\/server.log&lt;\/file>\n        &lt;rollingPolicy class=\"ch.qos.logback.core.rolling.TimeBasedRollingPolicy\">\n            &lt;fileNamePattern>\/var\/log\/sftp-server\/server.%d{yyyy-MM-dd}.log&lt;\/fileNamePattern>\n            &lt;maxHistory>30&lt;\/maxHistory>\n        &lt;\/rollingPolicy>\n        &lt;encoder>\n            &lt;pattern>%d{yyyy-MM-dd HH:mm:ss} &#91;%thread&#93; %-5level %logger{36} - %msg%n&lt;\/pattern>\n        &lt;\/encoder>\n    &lt;\/appender>\n    \n    &lt;root level=\"INFO\">\n        &lt;appender-ref ref=\"FILE\" \/>\n    &lt;\/root>\n    \n    &lt;!-- Suppress SSHD debug messages -->\n    &lt;logger name=\"org.apache.sshd\" level=\"WARN\" \/>\n&lt;\/configuration>\n<\/textarea><\/pre><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" style=\"width:24px;height:24px\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" stroke-width=\"2\"><path class=\"with-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M4.5 12.75l6 6 9-13.5\"><\/path><path class=\"without-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M16.5 8.25V6a2.25 2.25 0 00-2.25-2.25H6A2.25 2.25 0 003.75 6v8.25A2.25 2.25 0 006 16.5h2.25m8.25-8.25H18a2.25 2.25 0 012.25 2.25V18A2.25 2.25 0 0118 20.25h-7.5A2.25 2.25 0 018.25 18v-1.5m8.25-8.25h-6a2.25 2.25 0 00-2.25 2.25v6\"><\/path><\/svg><\/span><pre class=\"shiki one-dark-pro\" style=\"background-color: #282c34\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color: #ABB2BF\">&lt;configuration&gt;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">    &lt;<\/span><span style=\"color: #61AFEF\">appender<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">name=&quot;FILE&quot;<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">class=&quot;ch.qos.logback.core.rolling.RollingFileAppender&quot;<\/span><span style=\"color: #ABB2BF\">&gt;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">        &lt;<\/span><span style=\"color: #61AFEF\">file&gt;\/var\/log\/sftp-server\/server.log&lt;\/file&gt;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">        &lt;<\/span><span style=\"color: #61AFEF\">rollingPolicy<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">class=&quot;ch.qos.logback.core.rolling.TimeBasedRollingPolicy&quot;<\/span><span style=\"color: #ABB2BF\">&gt;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">            &lt;<\/span><span style=\"color: #61AFEF\">fileNamePattern&gt;\/var\/log\/sftp-server\/server.%d<\/span><span style=\"color: #ABB2BF\">{yyyy-MM-dd}<\/span><span style=\"color: #61AFEF\">.log&lt;\/fileNamePattern&gt;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">            &lt;<\/span><span style=\"color: #61AFEF\">maxHistory&gt;30&lt;\/maxHistory&gt;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">        &lt;<\/span><span style=\"color: #61AFEF\">\/rollingPolicy&gt;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">        &lt;<\/span><span style=\"color: #61AFEF\">encoder&gt;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">            &lt;<\/span><span style=\"color: #61AFEF\">pattern&gt;%d<\/span><span style=\"color: #ABB2BF\">{yyyy-MM-dd <\/span><span style=\"color: #98C379\">HH:mm:ss}<\/span><span style=\"color: #ABB2BF\"> &#91;%thread&#93; %-5level %logger{<\/span><span style=\"color: #61AFEF\">36}<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">-<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">%msg%n<\/span><span style=\"color: #ABB2BF\">&lt;<\/span><span style=\"color: #98C379\">\/patter<\/span><span style=\"color: #ABB2BF\">n&gt;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">        &lt;<\/span><span style=\"color: #61AFEF\">\/encoder&gt;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">    &lt;<\/span><span style=\"color: #61AFEF\">\/appender&gt;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">    <\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">    &lt;<\/span><span style=\"color: #61AFEF\">root<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">level=&quot;INFO&quot;<\/span><span style=\"color: #ABB2BF\">&gt;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">        &lt;<\/span><span style=\"color: #61AFEF\">appender-ref<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">ref=&quot;FILE&quot;<\/span><span style=\"color: #ABB2BF\"> \/&gt;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">    &lt;<\/span><span style=\"color: #61AFEF\">\/root&gt;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">    <\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">    &lt;!<\/span><span style=\"color: #61AFEF\">--<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">Suppress<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">SSHD<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">debug<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">messages<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #D19A66\">--<\/span><span style=\"color: #ABB2BF\">&gt;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">    &lt;<\/span><span style=\"color: #61AFEF\">logger<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">name=&quot;org.apache.sshd&quot;<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">level=&quot;WARN&quot;<\/span><span style=\"color: #ABB2BF\"> \/&gt;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">&lt;\/configuration&gt;<\/span><\/span>\n<span class=\"line\"><\/span><\/code><\/pre><\/div>\n\n\n\n<hr class=\"sera-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h2 class=\"sera-block-heading\">Usage Examples<\/h2>\n\n\n\n<h3 class=\"sera-block-heading\">Connecting with SFTP Client<\/h3>\n\n\n\n<h4 class=\"sera-block-heading\">Command Line (sftp)<\/h4>\n\n\n\n<div class=\"sera-block-kevinbatdorf-code-block-pro cbp-has-line-numbers\" data-code-block-pro-font-family=\"Code-Pro-JetBrains-Mono\" style=\"font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;--cbp-line-number-color:#abb2bf;--cbp-line-number-width:calc(2 * 0.6 * .875rem);line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)\"><span role=\"button\" tabindex=\"0\" style=\"color:#abb2bf;display:none\" aria-label=\"Copy\" class=\"code-block-pro-copy-button\"><pre class=\"code-block-pro-copy-button-pre\" aria-hidden=\"true\"><textarea class=\"code-block-pro-copy-button-textarea\" tabindex=\"-1\" aria-hidden=\"true\" readonly># Connect to server\nsftp -P 2222 admin@localhost\n\n# Commands\nsftp> ls                    # List files\nsftp> pwd                   # Print working directory\nsftp> put localfile.txt     # Upload file\nsftp> get remotefile.txt    # Download file\nsftp> rm oldfile.txt        # Delete file\nsftp> rename old.txt new.txt # Rename file\nsftp> mkdir newfolder       # Create directory\nsftp> bye                   # Disconnect\n<\/textarea><\/pre><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" style=\"width:24px;height:24px\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" stroke-width=\"2\"><path class=\"with-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M4.5 12.75l6 6 9-13.5\"><\/path><path class=\"without-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M16.5 8.25V6a2.25 2.25 0 00-2.25-2.25H6A2.25 2.25 0 003.75 6v8.25A2.25 2.25 0 006 16.5h2.25m8.25-8.25H18a2.25 2.25 0 012.25 2.25V18A2.25 2.25 0 0118 20.25h-7.5A2.25 2.25 0 018.25 18v-1.5m8.25-8.25h-6a2.25 2.25 0 00-2.25 2.25v6\"><\/path><\/svg><\/span><pre class=\"shiki one-dark-pro\" style=\"background-color: #282c34\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color: #7F848E; font-style: italic\"># Connect to server<\/span><\/span>\n<span class=\"line\"><span style=\"color: #61AFEF\">sftp<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #D19A66\">-P<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #D19A66\">2222<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">admin@localhost<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #7F848E; font-style: italic\"># Commands<\/span><\/span>\n<span class=\"line\"><span style=\"color: #61AFEF\">sftp&gt;<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">ls<\/span><span style=\"color: #ABB2BF\">                    <\/span><span style=\"color: #7F848E; font-style: italic\"># List files<\/span><\/span>\n<span class=\"line\"><span style=\"color: #61AFEF\">sftp&gt;<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">pwd<\/span><span style=\"color: #ABB2BF\">                   <\/span><span style=\"color: #7F848E; font-style: italic\"># Print working directory<\/span><\/span>\n<span class=\"line\"><span style=\"color: #61AFEF\">sftp&gt;<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">put<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">localfile.txt<\/span><span style=\"color: #ABB2BF\">     <\/span><span style=\"color: #7F848E; font-style: italic\"># Upload file<\/span><\/span>\n<span class=\"line\"><span style=\"color: #61AFEF\">sftp&gt;<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">get<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">remotefile.txt<\/span><span style=\"color: #ABB2BF\">    <\/span><span style=\"color: #7F848E; font-style: italic\"># Download file<\/span><\/span>\n<span class=\"line\"><span style=\"color: #61AFEF\">sftp&gt;<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">rm<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">oldfile.txt<\/span><span style=\"color: #ABB2BF\">        <\/span><span style=\"color: #7F848E; font-style: italic\"># Delete file<\/span><\/span>\n<span class=\"line\"><span style=\"color: #61AFEF\">sftp&gt;<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">rename<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">old.txt<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">new.txt<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #7F848E; font-style: italic\"># Rename file<\/span><\/span>\n<span class=\"line\"><span style=\"color: #61AFEF\">sftp&gt;<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">mkdir<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">newfolder<\/span><span style=\"color: #ABB2BF\">       <\/span><span style=\"color: #7F848E; font-style: italic\"># Create directory<\/span><\/span>\n<span class=\"line\"><span style=\"color: #61AFEF\">sftp&gt;<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">bye<\/span><span style=\"color: #ABB2BF\">                   <\/span><span style=\"color: #7F848E; font-style: italic\"># Disconnect<\/span><\/span>\n<span class=\"line\"><\/span><\/code><\/pre><\/div>\n\n\n\n<h4 class=\"sera-block-heading\">FileZilla<\/h4>\n\n\n\n<div class=\"sera-block-kevinbatdorf-code-block-pro cbp-has-line-numbers\" data-code-block-pro-font-family=\"Code-Pro-JetBrains-Mono\" style=\"font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;--cbp-line-number-color:#abb2bf;--cbp-line-number-width:calc(1 * 0.6 * .875rem);line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)\"><span role=\"button\" tabindex=\"0\" style=\"color:#abb2bf;display:none\" aria-label=\"Copy\" class=\"code-block-pro-copy-button\"><pre class=\"code-block-pro-copy-button-pre\" aria-hidden=\"true\"><textarea class=\"code-block-pro-copy-button-textarea\" tabindex=\"-1\" aria-hidden=\"true\" readonly>Host: sftp:\/\/localhost\nPort: 2222\nProtocol: SFTP - SSH File Transfer Protocol\nLogon Type: Normal\nUser: admin\nPassword: admin123\n<\/textarea><\/pre><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" style=\"width:24px;height:24px\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" stroke-width=\"2\"><path class=\"with-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M4.5 12.75l6 6 9-13.5\"><\/path><path class=\"without-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M16.5 8.25V6a2.25 2.25 0 00-2.25-2.25H6A2.25 2.25 0 003.75 6v8.25A2.25 2.25 0 006 16.5h2.25m8.25-8.25H18a2.25 2.25 0 012.25 2.25V18A2.25 2.25 0 0118 20.25h-7.5A2.25 2.25 0 018.25 18v-1.5m8.25-8.25h-6a2.25 2.25 0 00-2.25 2.25v6\"><\/path><\/svg><\/span><pre class=\"shiki one-dark-pro\" style=\"background-color: #282c34\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color: #61AFEF\">Host:<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">sftp:\/\/localhost<\/span><\/span>\n<span class=\"line\"><span style=\"color: #61AFEF\">Port:<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #D19A66\">2222<\/span><\/span>\n<span class=\"line\"><span style=\"color: #61AFEF\">Protocol:<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">SFTP<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">-<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">SSH<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">File<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">Transfer<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">Protocol<\/span><\/span>\n<span class=\"line\"><span style=\"color: #61AFEF\">Logon<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">Type:<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">Normal<\/span><\/span>\n<span class=\"line\"><span style=\"color: #61AFEF\">User:<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">admin<\/span><\/span>\n<span class=\"line\"><span style=\"color: #61AFEF\">Password:<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">admin123<\/span><\/span>\n<span class=\"line\"><\/span><\/code><\/pre><\/div>\n\n\n\n<h4 class=\"sera-block-heading\">WinSCP<\/h4>\n\n\n\n<div class=\"sera-block-kevinbatdorf-code-block-pro cbp-has-line-numbers\" data-code-block-pro-font-family=\"Code-Pro-JetBrains-Mono\" style=\"font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;--cbp-line-number-color:#abb2bf;--cbp-line-number-width:calc(1 * 0.6 * .875rem);line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)\"><span role=\"button\" tabindex=\"0\" style=\"color:#abb2bf;display:none\" aria-label=\"Copy\" class=\"code-block-pro-copy-button\"><pre class=\"code-block-pro-copy-button-pre\" aria-hidden=\"true\"><textarea class=\"code-block-pro-copy-button-textarea\" tabindex=\"-1\" aria-hidden=\"true\" readonly>File protocol: SFTP\nHost name: localhost\nPort number: 2222\nUser name: admin\nPassword: admin123\n<\/textarea><\/pre><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" style=\"width:24px;height:24px\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" stroke-width=\"2\"><path class=\"with-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M4.5 12.75l6 6 9-13.5\"><\/path><path class=\"without-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M16.5 8.25V6a2.25 2.25 0 00-2.25-2.25H6A2.25 2.25 0 003.75 6v8.25A2.25 2.25 0 006 16.5h2.25m8.25-8.25H18a2.25 2.25 0 012.25 2.25V18A2.25 2.25 0 0118 20.25h-7.5A2.25 2.25 0 018.25 18v-1.5m8.25-8.25h-6a2.25 2.25 0 00-2.25 2.25v6\"><\/path><\/svg><\/span><pre class=\"shiki one-dark-pro\" style=\"background-color: #282c34\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color: #61AFEF\">File<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">protocol:<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">SFTP<\/span><\/span>\n<span class=\"line\"><span style=\"color: #61AFEF\">Host<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">name:<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">localhost<\/span><\/span>\n<span class=\"line\"><span style=\"color: #61AFEF\">Port<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">number:<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #D19A66\">2222<\/span><\/span>\n<span class=\"line\"><span style=\"color: #61AFEF\">User<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">name:<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">admin<\/span><\/span>\n<span class=\"line\"><span style=\"color: #61AFEF\">Password:<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">admin123<\/span><\/span>\n<span class=\"line\"><\/span><\/code><\/pre><\/div>\n\n\n\n<h3 class=\"sera-block-heading\">Uploading Files<\/h3>\n\n\n\n<div class=\"sera-block-kevinbatdorf-code-block-pro cbp-has-line-numbers\" data-code-block-pro-font-family=\"Code-Pro-JetBrains-Mono\" style=\"font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;--cbp-line-number-color:#abb2bf;--cbp-line-number-width:calc(2 * 0.6 * .875rem);line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)\"><span role=\"button\" tabindex=\"0\" style=\"color:#abb2bf;display:none\" aria-label=\"Copy\" class=\"code-block-pro-copy-button\"><pre class=\"code-block-pro-copy-button-pre\" aria-hidden=\"true\"><textarea class=\"code-block-pro-copy-button-textarea\" tabindex=\"-1\" aria-hidden=\"true\" readonly># Single file\nsftp> put document.pdf\nUploading document.pdf to \/admin\/document.pdf\ndocument.pdf                    100%  1024KB   1.0MB\/s   00:01\n\n# Multiple files\nsftp> mput *.pdf\nUploading file1.pdf to \/admin\/file1.pdf\nUploading file2.pdf to \/admin\/file2.pdf\n\n# With progress\nsftp> put largefile.zip\nUploading largefile.zip to \/admin\/largefile.zip\nlargefile.zip                   25%   250MB   10.0MB\/s   00:75 ETA\n<\/textarea><\/pre><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" style=\"width:24px;height:24px\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" stroke-width=\"2\"><path class=\"with-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M4.5 12.75l6 6 9-13.5\"><\/path><path class=\"without-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M16.5 8.25V6a2.25 2.25 0 00-2.25-2.25H6A2.25 2.25 0 003.75 6v8.25A2.25 2.25 0 006 16.5h2.25m8.25-8.25H18a2.25 2.25 0 012.25 2.25V18A2.25 2.25 0 0118 20.25h-7.5A2.25 2.25 0 018.25 18v-1.5m8.25-8.25h-6a2.25 2.25 0 00-2.25 2.25v6\"><\/path><\/svg><\/span><pre class=\"shiki one-dark-pro\" style=\"background-color: #282c34\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color: #7F848E; font-style: italic\"># Single file<\/span><\/span>\n<span class=\"line\"><span style=\"color: #61AFEF\">sftp&gt;<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">put<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">document.pdf<\/span><\/span>\n<span class=\"line\"><span style=\"color: #61AFEF\">Uploading<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">document.pdf<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">to<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">\/admin\/document.pdf<\/span><\/span>\n<span class=\"line\"><span style=\"color: #61AFEF\">document.pdf<\/span><span style=\"color: #ABB2BF\">                    <\/span><span style=\"color: #D19A66\">100<\/span><span style=\"color: #98C379\">%<\/span><span style=\"color: #ABB2BF\">  <\/span><span style=\"color: #D19A66\">1024<\/span><span style=\"color: #98C379\">KB<\/span><span style=\"color: #ABB2BF\">   <\/span><span style=\"color: #D19A66\">1.0<\/span><span style=\"color: #98C379\">MB\/s<\/span><span style=\"color: #ABB2BF\">   <\/span><span style=\"color: #D19A66\">00<\/span><span style=\"color: #98C379\">:01<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #7F848E; font-style: italic\"># Multiple files<\/span><\/span>\n<span class=\"line\"><span style=\"color: #61AFEF\">sftp&gt;<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">mput<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #E5C07B\">*<\/span><span style=\"color: #98C379\">.pdf<\/span><\/span>\n<span class=\"line\"><span style=\"color: #61AFEF\">Uploading<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">file1.pdf<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">to<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">\/admin\/file1.pdf<\/span><\/span>\n<span class=\"line\"><span style=\"color: #61AFEF\">Uploading<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">file2.pdf<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">to<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">\/admin\/file2.pdf<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #7F848E; font-style: italic\"># With progress<\/span><\/span>\n<span class=\"line\"><span style=\"color: #61AFEF\">sftp&gt;<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">put<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">largefile.zip<\/span><\/span>\n<span class=\"line\"><span style=\"color: #61AFEF\">Uploading<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">largefile.zip<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">to<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">\/admin\/largefile.zip<\/span><\/span>\n<span class=\"line\"><span style=\"color: #61AFEF\">largefile.zip<\/span><span style=\"color: #ABB2BF\">                   <\/span><span style=\"color: #D19A66\">25<\/span><span style=\"color: #98C379\">%<\/span><span style=\"color: #ABB2BF\">   <\/span><span style=\"color: #D19A66\">250<\/span><span style=\"color: #98C379\">MB<\/span><span style=\"color: #ABB2BF\">   <\/span><span style=\"color: #D19A66\">10.0<\/span><span style=\"color: #98C379\">MB\/s<\/span><span style=\"color: #ABB2BF\">   <\/span><span style=\"color: #D19A66\">00<\/span><span style=\"color: #98C379\">:75<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">ETA<\/span><\/span>\n<span class=\"line\"><\/span><\/code><\/pre><\/div>\n\n\n\n<p class=\"sera-block-paragraph\">Server logs:<\/p>\n\n\n\n<div class=\"sera-block-kevinbatdorf-code-block-pro cbp-has-line-numbers\" data-code-block-pro-font-family=\"Code-Pro-JetBrains-Mono\" style=\"font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;--cbp-line-number-color:#abb2bf;--cbp-line-number-width:calc(1 * 0.6 * .875rem);line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)\"><span role=\"button\" tabindex=\"0\" style=\"color:#abb2bf;display:none\" aria-label=\"Copy\" class=\"code-block-pro-copy-button\"><pre class=\"code-block-pro-copy-button-pre\" aria-hidden=\"true\"><textarea class=\"code-block-pro-copy-button-textarea\" tabindex=\"-1\" aria-hidden=\"true\" readonly>&#91;SFTP-OPEN&#93; admin opened: document.pdf (0 B)\n&#91;SFTP-WRITE&#93; document.pdf: 10.0 MB uploaded\n&#91;SFTP-WRITE&#93; document.pdf: 20.0 MB uploaded\n&#91;SFTP-CLOSE&#93; document.pdf closed (total: 0 B)\n<\/textarea><\/pre><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" style=\"width:24px;height:24px\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" stroke-width=\"2\"><path class=\"with-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M4.5 12.75l6 6 9-13.5\"><\/path><path class=\"without-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M16.5 8.25V6a2.25 2.25 0 00-2.25-2.25H6A2.25 2.25 0 003.75 6v8.25A2.25 2.25 0 006 16.5h2.25m8.25-8.25H18a2.25 2.25 0 012.25 2.25V18A2.25 2.25 0 0118 20.25h-7.5A2.25 2.25 0 018.25 18v-1.5m8.25-8.25h-6a2.25 2.25 0 00-2.25 2.25v6\"><\/path><\/svg><\/span><pre class=\"shiki one-dark-pro\" style=\"background-color: #282c34\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color: #ABB2BF\">&#91;SFTP-OPEN&#93; admin opened: document.pdf (<\/span><span style=\"color: #61AFEF\">0<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">B<\/span><span style=\"color: #ABB2BF\">)<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">&#91;SFTP-WRITE&#93; document.pdf: 10.0 MB uploaded<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">&#91;SFTP-WRITE&#93; document.pdf: 20.0 MB uploaded<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">&#91;SFTP-CLOSE&#93; document.pdf closed (<\/span><span style=\"color: #61AFEF\">total:<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #D19A66\">0<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">B<\/span><span style=\"color: #ABB2BF\">)<\/span><\/span>\n<span class=\"line\"><\/span><\/code><\/pre><\/div>\n\n\n\n<h3 class=\"sera-block-heading\">Downloading Files<\/h3>\n\n\n\n<div class=\"sera-block-kevinbatdorf-code-block-pro cbp-has-line-numbers\" data-code-block-pro-font-family=\"Code-Pro-JetBrains-Mono\" style=\"font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;--cbp-line-number-color:#abb2bf;--cbp-line-number-width:calc(1 * 0.6 * .875rem);line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)\"><span role=\"button\" tabindex=\"0\" style=\"color:#abb2bf;display:none\" aria-label=\"Copy\" class=\"code-block-pro-copy-button\"><pre class=\"code-block-pro-copy-button-pre\" aria-hidden=\"true\"><textarea class=\"code-block-pro-copy-button-textarea\" tabindex=\"-1\" aria-hidden=\"true\" readonly># Single file\nsftp> get document.pdf\nFetching \/admin\/document.pdf to document.pdf\ndocument.pdf                    100%  1024KB   1.0MB\/s   00:01\n\n# Multiple files\nsftp> mget *.pdf\n<\/textarea><\/pre><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" style=\"width:24px;height:24px\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" stroke-width=\"2\"><path class=\"with-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M4.5 12.75l6 6 9-13.5\"><\/path><path class=\"without-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M16.5 8.25V6a2.25 2.25 0 00-2.25-2.25H6A2.25 2.25 0 003.75 6v8.25A2.25 2.25 0 006 16.5h2.25m8.25-8.25H18a2.25 2.25 0 012.25 2.25V18A2.25 2.25 0 0118 20.25h-7.5A2.25 2.25 0 018.25 18v-1.5m8.25-8.25h-6a2.25 2.25 0 00-2.25 2.25v6\"><\/path><\/svg><\/span><pre class=\"shiki one-dark-pro\" style=\"background-color: #282c34\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color: #7F848E; font-style: italic\"># Single file<\/span><\/span>\n<span class=\"line\"><span style=\"color: #61AFEF\">sftp&gt;<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">get<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">document.pdf<\/span><\/span>\n<span class=\"line\"><span style=\"color: #61AFEF\">Fetching<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">\/admin\/document.pdf<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">to<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">document.pdf<\/span><\/span>\n<span class=\"line\"><span style=\"color: #61AFEF\">document.pdf<\/span><span style=\"color: #ABB2BF\">                    <\/span><span style=\"color: #D19A66\">100<\/span><span style=\"color: #98C379\">%<\/span><span style=\"color: #ABB2BF\">  <\/span><span style=\"color: #D19A66\">1024<\/span><span style=\"color: #98C379\">KB<\/span><span style=\"color: #ABB2BF\">   <\/span><span style=\"color: #D19A66\">1.0<\/span><span style=\"color: #98C379\">MB\/s<\/span><span style=\"color: #ABB2BF\">   <\/span><span style=\"color: #D19A66\">00<\/span><span style=\"color: #98C379\">:01<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #7F848E; font-style: italic\"># Multiple files<\/span><\/span>\n<span class=\"line\"><span style=\"color: #61AFEF\">sftp&gt;<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">mget<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #E5C07B\">*<\/span><span style=\"color: #98C379\">.pdf<\/span><\/span>\n<span class=\"line\"><\/span><\/code><\/pre><\/div>\n\n\n\n<p class=\"sera-block-paragraph\">Server logs:<\/p>\n\n\n\n<div class=\"sera-block-kevinbatdorf-code-block-pro cbp-has-line-numbers\" data-code-block-pro-font-family=\"Code-Pro-JetBrains-Mono\" style=\"font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;--cbp-line-number-color:#abb2bf;--cbp-line-number-width:calc(1 * 0.6 * .875rem);line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)\"><span role=\"button\" tabindex=\"0\" style=\"color:#abb2bf;display:none\" aria-label=\"Copy\" class=\"code-block-pro-copy-button\"><pre class=\"code-block-pro-copy-button-pre\" aria-hidden=\"true\"><textarea class=\"code-block-pro-copy-button-textarea\" tabindex=\"-1\" aria-hidden=\"true\" readonly>&#91;SFTP-OPEN&#93; admin opened: document.pdf (1.0 MB)\n&#91;SFTP-READ&#93; document.pdf: 512 KB \/ 1.0 MB (50%)\n&#91;SFTP-READ&#93; document.pdf: End of file reached (download complete)\n&#91;SFTP-CLOSE&#93; document.pdf closed (total: 1.0 MB)\n<\/textarea><\/pre><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" style=\"width:24px;height:24px\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" stroke-width=\"2\"><path class=\"with-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M4.5 12.75l6 6 9-13.5\"><\/path><path class=\"without-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M16.5 8.25V6a2.25 2.25 0 00-2.25-2.25H6A2.25 2.25 0 003.75 6v8.25A2.25 2.25 0 006 16.5h2.25m8.25-8.25H18a2.25 2.25 0 012.25 2.25V18A2.25 2.25 0 0118 20.25h-7.5A2.25 2.25 0 018.25 18v-1.5m8.25-8.25h-6a2.25 2.25 0 00-2.25 2.25v6\"><\/path><\/svg><\/span><pre class=\"shiki one-dark-pro\" style=\"background-color: #282c34\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color: #ABB2BF\">&#91;SFTP-OPEN&#93; admin opened: document.pdf (<\/span><span style=\"color: #61AFEF\">1.0<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">MB<\/span><span style=\"color: #ABB2BF\">)<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">&#91;SFTP-READ&#93; document.pdf: 512 KB \/ 1.0 MB (<\/span><span style=\"color: #61AFEF\">50%<\/span><span style=\"color: #ABB2BF\">)<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">&#91;SFTP-READ&#93; document.pdf: End of file reached (<\/span><span style=\"color: #61AFEF\">download<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">complete<\/span><span style=\"color: #ABB2BF\">)<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">&#91;SFTP-CLOSE&#93; document.pdf closed (<\/span><span style=\"color: #61AFEF\">total:<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #D19A66\">1.0<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">MB<\/span><span style=\"color: #ABB2BF\">)<\/span><\/span>\n<span class=\"line\"><\/span><\/code><\/pre><\/div>\n\n\n\n<h3 class=\"sera-block-heading\">File Management<\/h3>\n\n\n\n<pre class=\"sera-block-code\"><code># Rename\nsftp&gt; rename oldname.txt newname.txt\n<\/code><\/pre>\n\n\n\n<p class=\"sera-block-paragraph\">Server logs:<\/p>\n\n\n\n<div class=\"sera-block-kevinbatdorf-code-block-pro cbp-has-line-numbers\" data-code-block-pro-font-family=\"Code-Pro-JetBrains-Mono\" style=\"font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;--cbp-line-number-color:#abb2bf;--cbp-line-number-width:calc(1 * 0.6 * .875rem);line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)\"><span role=\"button\" tabindex=\"0\" style=\"color:#abb2bf;display:none\" aria-label=\"Copy\" class=\"code-block-pro-copy-button\"><pre class=\"code-block-pro-copy-button-pre\" aria-hidden=\"true\"><textarea class=\"code-block-pro-copy-button-textarea\" tabindex=\"-1\" aria-hidden=\"true\" readonly>&#91;SFTP-MOVE&#93; admin moved: oldname.txt -> newname.txt\n<\/textarea><\/pre><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" style=\"width:24px;height:24px\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" stroke-width=\"2\"><path class=\"with-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M4.5 12.75l6 6 9-13.5\"><\/path><path class=\"without-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M16.5 8.25V6a2.25 2.25 0 00-2.25-2.25H6A2.25 2.25 0 003.75 6v8.25A2.25 2.25 0 006 16.5h2.25m8.25-8.25H18a2.25 2.25 0 012.25 2.25V18A2.25 2.25 0 0118 20.25h-7.5A2.25 2.25 0 018.25 18v-1.5m8.25-8.25h-6a2.25 2.25 0 00-2.25 2.25v6\"><\/path><\/svg><\/span><pre class=\"shiki one-dark-pro\" style=\"background-color: #282c34\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color: #ABB2BF\">&#91;SFTP-MOVE&#93; admin moved: oldname.txt -&gt; newname.txt<\/span><\/span>\n<span class=\"line\"><\/span><\/code><\/pre><\/div>\n\n\n\n<div class=\"sera-block-kevinbatdorf-code-block-pro cbp-has-line-numbers\" data-code-block-pro-font-family=\"Code-Pro-JetBrains-Mono\" style=\"font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;--cbp-line-number-color:#abb2bf;--cbp-line-number-width:calc(1 * 0.6 * .875rem);line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)\"><span role=\"button\" tabindex=\"0\" style=\"color:#abb2bf;display:none\" aria-label=\"Copy\" class=\"code-block-pro-copy-button\"><pre class=\"code-block-pro-copy-button-pre\" aria-hidden=\"true\"><textarea class=\"code-block-pro-copy-button-textarea\" tabindex=\"-1\" aria-hidden=\"true\" readonly># Delete\nsftp> rm unwanted.txt\n<\/textarea><\/pre><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" style=\"width:24px;height:24px\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" stroke-width=\"2\"><path class=\"with-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M4.5 12.75l6 6 9-13.5\"><\/path><path class=\"without-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M16.5 8.25V6a2.25 2.25 0 00-2.25-2.25H6A2.25 2.25 0 003.75 6v8.25A2.25 2.25 0 006 16.5h2.25m8.25-8.25H18a2.25 2.25 0 012.25 2.25V18A2.25 2.25 0 0118 20.25h-7.5A2.25 2.25 0 018.25 18v-1.5m8.25-8.25h-6a2.25 2.25 0 00-2.25 2.25v6\"><\/path><\/svg><\/span><pre class=\"shiki one-dark-pro\" style=\"background-color: #282c34\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color: #7F848E; font-style: italic\"># Delete<\/span><\/span>\n<span class=\"line\"><span style=\"color: #61AFEF\">sftp&gt;<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">rm<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">unwanted.txt<\/span><\/span>\n<span class=\"line\"><\/span><\/code><\/pre><\/div>\n\n\n\n<p class=\"sera-block-paragraph\">Server logs:<\/p>\n\n\n\n<div class=\"sera-block-kevinbatdorf-code-block-pro cbp-has-line-numbers\" data-code-block-pro-font-family=\"Code-Pro-JetBrains-Mono\" style=\"font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;--cbp-line-number-color:#abb2bf;--cbp-line-number-width:calc(1 * 0.6 * .875rem);line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)\"><span role=\"button\" tabindex=\"0\" style=\"color:#abb2bf;display:none\" aria-label=\"Copy\" class=\"code-block-pro-copy-button\"><pre class=\"code-block-pro-copy-button-pre\" aria-hidden=\"true\"><textarea class=\"code-block-pro-copy-button-textarea\" tabindex=\"-1\" aria-hidden=\"true\" readonly>&#91;SFTP-DELETE&#93; admin deleted: unwanted.txt\n<\/textarea><\/pre><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" style=\"width:24px;height:24px\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" stroke-width=\"2\"><path class=\"with-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M4.5 12.75l6 6 9-13.5\"><\/path><path class=\"without-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M16.5 8.25V6a2.25 2.25 0 00-2.25-2.25H6A2.25 2.25 0 003.75 6v8.25A2.25 2.25 0 006 16.5h2.25m8.25-8.25H18a2.25 2.25 0 012.25 2.25V18A2.25 2.25 0 0118 20.25h-7.5A2.25 2.25 0 018.25 18v-1.5m8.25-8.25h-6a2.25 2.25 0 00-2.25 2.25v6\"><\/path><\/svg><\/span><pre class=\"shiki one-dark-pro\" style=\"background-color: #282c34\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color: #ABB2BF\">&#91;SFTP-DELETE&#93; admin deleted: unwanted.txt<\/span><\/span>\n<span class=\"line\"><\/span><\/code><\/pre><\/div>\n\n\n\n<h3 class=\"sera-block-heading\">Programmatic Access (Java)<\/h3>\n\n\n\n<div class=\"sera-block-kevinbatdorf-code-block-pro cbp-has-line-numbers\" data-code-block-pro-font-family=\"Code-Pro-JetBrains-Mono\" style=\"font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;--cbp-line-number-color:#abb2bf;--cbp-line-number-width:calc(2 * 0.6 * .875rem);line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)\"><span role=\"button\" tabindex=\"0\" style=\"color:#abb2bf;display:none\" aria-label=\"Copy\" class=\"code-block-pro-copy-button\"><pre class=\"code-block-pro-copy-button-pre\" aria-hidden=\"true\"><textarea class=\"code-block-pro-copy-button-textarea\" tabindex=\"-1\" aria-hidden=\"true\" readonly>import com.jcraft.jsch.*;\n\npublic class SFTPClient {\n    public static void main(String[] args) throws Exception {\n        JSch jsch = new JSch();\n        Session session = jsch.getSession(\"admin\", \"localhost\", 2222);\n        session.setPassword(\"admin123\");\n        session.setConfig(\"StrictHostKeyChecking\", \"no\");\n        session.connect();\n        \n        ChannelSftp channel = (ChannelSftp) session.openChannel(\"sftp\");\n        channel.connect();\n        \n        \/\/ Upload file\n        channel.put(\"local.txt\", \"remote.txt\");\n        \n        \/\/ Download file\n        channel.get(\"remote.txt\", \"downloaded.txt\");\n        \n        \/\/ List files\n        Vector&lt;ChannelSftp.LsEntry> files = channel.ls(\".\");\n        for (ChannelSftp.LsEntry file : files) {\n            System.out.println(file.getFilename());\n        }\n        \n        channel.disconnect();\n        session.disconnect();\n    }\n}\n<\/textarea><\/pre><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" style=\"width:24px;height:24px\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" stroke-width=\"2\"><path class=\"with-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M4.5 12.75l6 6 9-13.5\"><\/path><path class=\"without-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M16.5 8.25V6a2.25 2.25 0 00-2.25-2.25H6A2.25 2.25 0 003.75 6v8.25A2.25 2.25 0 006 16.5h2.25m8.25-8.25H18a2.25 2.25 0 012.25 2.25V18A2.25 2.25 0 0118 20.25h-7.5A2.25 2.25 0 018.25 18v-1.5m8.25-8.25h-6a2.25 2.25 0 00-2.25 2.25v6\"><\/path><\/svg><\/span><pre class=\"shiki one-dark-pro\" style=\"background-color: #282c34\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color: #61AFEF\">import<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">com.jcraft.jsch.<\/span><span style=\"color: #E5C07B\">*<\/span><span style=\"color: #ABB2BF\">;<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #61AFEF\">public<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">class<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">SFTPClient<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">{<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">    <\/span><span style=\"color: #61AFEF\">public<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">static<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">void<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">main<\/span><span style=\"color: #ABB2BF\">(<\/span><span style=\"color: #61AFEF\">String[]<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">args<\/span><span style=\"color: #ABB2BF\">) <\/span><span style=\"color: #98C379\">throws<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">Exception<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">{<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">        <\/span><span style=\"color: #61AFEF\">JSch<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">jsch<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">=<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">new<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">JSch<\/span><span style=\"color: #ABB2BF\">();<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">        <\/span><span style=\"color: #61AFEF\">Session<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">session<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">=<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">jsch.getSession<\/span><span style=\"color: #ABB2BF\">(<\/span><span style=\"color: #61AFEF\">&quot;admin&quot;<\/span><span style=\"color: #61AFEF\">,<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">&quot;localhost&quot;,<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #D19A66\">2222<\/span><span style=\"color: #ABB2BF\">);<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">        <\/span><span style=\"color: #61AFEF\">session.setPassword(<\/span><span style=\"color: #61AFEF\">&quot;admin123&quot;<\/span><span style=\"color: #ABB2BF\">);<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">        <\/span><span style=\"color: #61AFEF\">session.setConfig(<\/span><span style=\"color: #61AFEF\">&quot;StrictHostKeyChecking&quot;<\/span><span style=\"color: #61AFEF\">,<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">&quot;no&quot;<\/span><span style=\"color: #ABB2BF\">);<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">        <\/span><span style=\"color: #61AFEF\">session.connect<\/span><span style=\"color: #ABB2BF\">();<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">        <\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">        <\/span><span style=\"color: #61AFEF\">ChannelSftp<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">channel<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">=<\/span><span style=\"color: #ABB2BF\"> (ChannelSftp) session.openChannel(<\/span><span style=\"color: #61AFEF\">&quot;sftp&quot;<\/span><span style=\"color: #ABB2BF\">);<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">        <\/span><span style=\"color: #61AFEF\">channel.connect<\/span><span style=\"color: #ABB2BF\">();<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">        <\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">        <\/span><span style=\"color: #61AFEF\">\/\/<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">Upload<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">file<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">        <\/span><span style=\"color: #61AFEF\">channel.put(<\/span><span style=\"color: #61AFEF\">&quot;local.txt&quot;<\/span><span style=\"color: #61AFEF\">,<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">&quot;remote.txt&quot;<\/span><span style=\"color: #ABB2BF\">);<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">        <\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">        <\/span><span style=\"color: #61AFEF\">\/\/<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">Download<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">file<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">        <\/span><span style=\"color: #61AFEF\">channel.get(<\/span><span style=\"color: #61AFEF\">&quot;remote.txt&quot;<\/span><span style=\"color: #61AFEF\">,<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">&quot;downloaded.txt&quot;<\/span><span style=\"color: #ABB2BF\">);<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">        <\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">        <\/span><span style=\"color: #61AFEF\">\/\/<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">List<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">files<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">        <\/span><span style=\"color: #61AFEF\">Vector&lt;ChannelSftp.LsEntry&gt;<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">files<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">=<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">channel.ls<\/span><span style=\"color: #ABB2BF\">(<\/span><span style=\"color: #61AFEF\">&quot;.&quot;<\/span><span style=\"color: #ABB2BF\">);<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">        <\/span><span style=\"color: #C678DD\">for<\/span><span style=\"color: #ABB2BF\"> (<\/span><span style=\"color: #61AFEF\">ChannelSftp.LsEntry<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">file<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">:<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">files<\/span><span style=\"color: #ABB2BF\">) {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">            <\/span><span style=\"color: #61AFEF\">System.out.println(file.getFilename(<\/span><span style=\"color: #ABB2BF\">));<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">        }<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">        <\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">        <\/span><span style=\"color: #61AFEF\">channel.disconnect<\/span><span style=\"color: #ABB2BF\">();<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">        <\/span><span style=\"color: #61AFEF\">session.disconnect<\/span><span style=\"color: #ABB2BF\">();<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">    }<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">}<\/span><\/span>\n<span class=\"line\"><\/span><\/code><\/pre><\/div>\n\n\n\n<hr class=\"sera-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h2 class=\"sera-block-heading\">Performance Considerations<\/h2>\n\n\n\n<h3 class=\"sera-block-heading\">Memory Usage<\/h3>\n\n\n\n<p class=\"sera-block-paragraph\"><strong>Per Open File<\/strong>:<\/p>\n\n\n\n<div class=\"sera-block-kevinbatdorf-code-block-pro cbp-has-line-numbers\" data-code-block-pro-font-family=\"Code-Pro-JetBrains-Mono\" style=\"font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;--cbp-line-number-color:#abb2bf;--cbp-line-number-width:calc(1 * 0.6 * .875rem);line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)\"><span role=\"button\" tabindex=\"0\" style=\"color:#abb2bf;display:none\" aria-label=\"Copy\" class=\"code-block-pro-copy-button\"><pre class=\"code-block-pro-copy-button-pre\" aria-hidden=\"true\"><textarea class=\"code-block-pro-copy-button-textarea\" tabindex=\"-1\" aria-hidden=\"true\" readonly>Memory = chunk_size (buffer) + chunk_size (cache) + overhead\n<\/textarea><\/pre><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" style=\"width:24px;height:24px\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" stroke-width=\"2\"><path class=\"with-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M4.5 12.75l6 6 9-13.5\"><\/path><path class=\"without-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M16.5 8.25V6a2.25 2.25 0 00-2.25-2.25H6A2.25 2.25 0 003.75 6v8.25A2.25 2.25 0 006 16.5h2.25m8.25-8.25H18a2.25 2.25 0 012.25 2.25V18A2.25 2.25 0 0118 20.25h-7.5A2.25 2.25 0 018.25 18v-1.5m8.25-8.25h-6a2.25 2.25 0 00-2.25 2.25v6\"><\/path><\/svg><\/span><pre class=\"shiki one-dark-pro\" style=\"background-color: #282c34\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color: #61AFEF\">Memory<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">=<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">chunk_size<\/span><span style=\"color: #ABB2BF\"> (buffer) + chunk_size (<\/span><span style=\"color: #61AFEF\">cache<\/span><span style=\"color: #ABB2BF\">) + overhead<\/span><\/span>\n<span class=\"line\"><\/span><\/code><\/pre><\/div>\n\n\n\n<p class=\"sera-block-paragraph\">Examples:<\/p>\n\n\n\n<ul class=\"sera-block-list\">\n<li>64KB chunks: ~130KB per file<\/li>\n\n\n\n<li>256KB chunks: ~520KB per file<\/li>\n<\/ul>\n\n\n\n<p class=\"sera-block-paragraph\"><strong>Concurrent Transfers<\/strong>:<\/p>\n\n\n\n<pre class=\"sera-block-code\"><code>Total Memory \u2248 concurrent_files \u00d7 chunk_size \u00d7 2\n<\/code><\/pre>\n\n\n\n<p class=\"sera-block-paragraph\">Example: 10 concurrent transfers with 64KB chunks:<\/p>\n\n\n\n<pre class=\"sera-block-code\"><code>10 \u00d7 64KB \u00d7 2 = 1.28 MB (plus JVM overhead)\n<\/code><\/pre>\n\n\n\n<h3 class=\"sera-block-heading\">Disk I\/O<\/h3>\n\n\n\n<p class=\"sera-block-paragraph\"><strong>Write Operations<\/strong>:<\/p>\n\n\n\n<ul class=\"sera-block-list\">\n<li>Sequential writes (optimal for HDDs)<\/li>\n\n\n\n<li>Chunk size aligned with file system block size recommended<\/li>\n\n\n\n<li>SSD: Any chunk size performs well<\/li>\n<\/ul>\n\n\n\n<p class=\"sera-block-paragraph\"><strong>Read Operations<\/strong>:<\/p>\n\n\n\n<ul class=\"sera-block-list\">\n<li>Random access supported<\/li>\n\n\n\n<li>Only requested chunks decrypted (no full-file read)<\/li>\n\n\n\n<li>Caching reduces repeated decryption<\/li>\n<\/ul>\n\n\n\n<h3 class=\"sera-block-heading\">CPU Usage<\/h3>\n\n\n\n<p class=\"sera-block-paragraph\"><strong>Encryption Overhead<\/strong>:<\/p>\n\n\n\n<ul class=\"sera-block-list\">\n<li>AES-256-GCM is hardware-accelerated on modern CPUs with AES-NI support<\/li>\n\n\n\n<li>Performance impact varies based on CPU capabilities<\/li>\n\n\n\n<li>Generally negligible for typical SFTP workloads<\/li>\n\n\n\n<li>Chunk-based architecture allows for future parallelization<\/li>\n<\/ul>\n\n\n\n<p class=\"sera-block-paragraph\"><strong>Authentication<\/strong>:<\/p>\n\n\n\n<ul class=\"sera-block-list\">\n<li>PBKDF2 with 100K iterations intentionally adds computational delay<\/li>\n\n\n\n<li>Designed to slow down brute force attempts<\/li>\n\n\n\n<li>Timing varies based on CPU performance<\/li>\n<\/ul>\n\n\n\n<h3 class=\"sera-block-heading\">Network Throughput<\/h3>\n\n\n\n<p class=\"sera-block-paragraph\"><strong>Factors<\/strong>:<\/p>\n\n\n\n<ol class=\"sera-block-list\">\n<li>SSH protocol overhead<\/li>\n\n\n\n<li>Encryption\/decryption processing<\/li>\n\n\n\n<li>Network bandwidth (typically primary bottleneck)<\/li>\n\n\n\n<li>Disk I\/O (secondary consideration)<\/li>\n<\/ol>\n\n\n\n<p class=\"sera-block-paragraph\"><strong>Typical Performance Characteristics<\/strong>:<\/p>\n\n\n\n<pre class=\"sera-block-code\"><code>Network bandwidth: Primary bottleneck for most deployments\nSSD throughput: Generally exceeds network capabilities\nHDD throughput: May bottleneck on sequential operations\n\nExpected: Network bandwidth typically limits transfer speeds\n<\/code><\/pre>\n\n\n\n<h3 class=\"sera-block-heading\">Optimization Tips<\/h3>\n\n\n\n<ol class=\"sera-block-list\">\n<li><strong>Chunk Size Tuning<\/strong>: <code>- Small files (&lt;1MB): 16-32KB chunks - Medium files (1-100MB): 64-128KB chunks - Large files (&gt;100MB): 256KB-1MB chunks<\/code><\/li>\n\n\n\n<li><strong>File System<\/strong>: <code>- Use ext4 or XFS on Linux - Disable atime updates: mount with 'noatime' - Align chunk size with block size if possible<\/code><\/li>\n\n\n\n<li><strong>JVM Tuning<\/strong>: <code># Recommended JVM flags -Xms1G -Xmx4G # Heap size -XX:+UseG1GC # Garbage collector -XX:MaxGCPauseMillis=200 # GC pause target<\/code><\/li>\n\n\n\n<li><strong>Concurrent Connections<\/strong>: <code>- Monitor memory usage - Limit concurrent transfers if memory-constrained - Calculate: max_connections = (available_memory \/ chunk_size \/ 2)<\/code><\/li>\n<\/ol>\n\n\n\n<hr class=\"sera-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h2 class=\"sera-block-heading\">Security Considerations<\/h2>\n\n\n\n<h3 class=\"sera-block-heading\">\u26a0\ufe0f Educational Implementation Notice<\/h3>\n\n\n\n<p class=\"sera-block-paragraph\">This is a demonstration implementation for educational and testing purposes. The following security items are intentionally simplified and <strong>MUST<\/strong> be addressed before any production deployment.<\/p>\n\n\n\n<h3 class=\"sera-block-heading\">Critical Security Notes<\/h3>\n\n\n\n<ol class=\"sera-block-list\">\n<li><strong>Master Key Management<\/strong> (DEVELOPMENT\/TESTING ONLY &#8211; CRITICAL FOR PRODUCTION): <code>\/\/ CURRENT IMPLEMENTATION (EDUCATIONAL\/DEVELOPMENT ONLY): byte[] masterKeyBytes = Arrays.copyOf( \"your-plaintext-password-here\".getBytes(...), 32); \/\/ \u26a0\ufe0f THIS IS NOT SECURE FOR PRODUCTION \u26a0\ufe0f \/\/ PRODUCTION REQUIREMENTS: \/\/ - Load from KMS (AWS KMS, Azure Key Vault, HashiCorp Vault) \/\/ - Use environment variables (minimum) \/\/ - Implement key rotation \/\/ - Add salt and proper key derivation \/\/ - Never hardcode credentials<\/code><\/li>\n\n\n\n<li><strong>Keyset Storage<\/strong>:\n<ul class=\"sera-block-list\">\n<li>Current: Encrypted with master key<\/li>\n\n\n\n<li>Recommended: Store in KMS or secure vault<\/li>\n\n\n\n<li>Backup: Keep encrypted backups in separate location<\/li>\n\n\n\n<li>Rotation: Implement regular key rotation policy<\/li>\n<\/ul>\n<\/li>\n\n\n\n<li><strong>User Authentication<\/strong> (EDUCATIONAL IMPLEMENTATION):\n<ul class=\"sera-block-list\">\n<li>Current: In-memory, PBKDF2-hashed (for testing\/development)<\/li>\n\n\n\n<li>Default credentials provided for demonstration purposes only<\/li>\n\n\n\n<li>Production requirements:\n<ul class=\"sera-block-list\">\n<li>Database with encrypted storage<\/li>\n\n\n\n<li>LDAP\/Active Directory integration<\/li>\n\n\n\n<li>Multi-factor authentication (MFA)<\/li>\n\n\n\n<li>Account lockout after failed attempts<\/li>\n\n\n\n<li>No default credentials<\/li>\n<\/ul>\n<\/li>\n<\/ul>\n<\/li>\n\n\n\n<li><strong>Network Security<\/strong>:\n<ul class=\"sera-block-list\">\n<li>Use firewall to restrict port 2222 access<\/li>\n\n\n\n<li>Consider VPN or IP whitelisting<\/li>\n\n\n\n<li>Monitor for brute force attempts<\/li>\n\n\n\n<li>Implement rate limiting<\/li>\n<\/ul>\n<\/li>\n\n\n\n<li><strong>File System Permissions<\/strong>: <code># Recommended permissions chmod 700 \/data\/sftp-storage # Owner only chmod 600 \/secure\/keys\/keyset.json # Owner read\/write only chmod 600 \/secure\/keys\/hostkey.ser # Owner read\/write only<\/code><\/li>\n<\/ol>\n\n\n\n<h3 class=\"sera-block-heading\">Attack Scenarios &amp; Mitigations<\/h3>\n\n\n\n<h4 class=\"sera-block-heading\">1. Unauthorized Disk Access<\/h4>\n\n\n\n<p class=\"sera-block-paragraph\"><strong>Scenario<\/strong>: Attacker gains physical access to server disk<\/p>\n\n\n\n<p class=\"sera-block-paragraph\"><strong>Mitigation<\/strong>:<\/p>\n\n\n\n<ul class=\"sera-block-list\">\n<li>All files encrypted with AES-256-GCM<\/li>\n\n\n\n<li>Keyset encrypted with master key<\/li>\n\n\n\n<li>Master key stored in KMS (production)<\/li>\n\n\n\n<li>Result: Attacker cannot decrypt files without master key<\/li>\n<\/ul>\n\n\n\n<h4 class=\"sera-block-heading\">2. Chunk Manipulation<\/h4>\n\n\n\n<p class=\"sera-block-paragraph\"><strong>Scenario<\/strong>: Attacker modifies encrypted chunks on disk<\/p>\n\n\n\n<p class=\"sera-block-paragraph\"><strong>Mitigation<\/strong>:<\/p>\n\n\n\n<ul class=\"sera-block-list\">\n<li>Each chunk has GCM authentication tag<\/li>\n\n\n\n<li>Associated data includes filename and chunk index<\/li>\n\n\n\n<li>Tampering detected during decryption<\/li>\n\n\n\n<li>Result: Modified chunks rejected, read fails<\/li>\n<\/ul>\n\n\n\n<h4 class=\"sera-block-heading\">3. Chunk Reordering<\/h4>\n\n\n\n<p class=\"sera-block-paragraph\"><strong>Scenario<\/strong>: Attacker swaps chunk N with chunk M<\/p>\n\n\n\n<p class=\"sera-block-paragraph\"><strong>Mitigation<\/strong>:<\/p>\n\n\n\n<ul class=\"sera-block-list\">\n<li>Associated data: <code>\"filename:chunk:N\"<\/code><\/li>\n\n\n\n<li>Decryption with wrong AAD fails<\/li>\n\n\n\n<li>Result: Reordered chunks detected and rejected<\/li>\n<\/ul>\n\n\n\n<h4 class=\"sera-block-heading\">4. Cross-File Attack<\/h4>\n\n\n\n<p class=\"sera-block-paragraph\"><strong>Scenario<\/strong>: Attacker copies chunk from file A to file B<\/p>\n\n\n\n<p class=\"sera-block-paragraph\"><strong>Mitigation<\/strong>:<\/p>\n\n\n\n<ul class=\"sera-block-list\">\n<li>Associated data includes filename<\/li>\n\n\n\n<li>Decryption requires matching filename<\/li>\n\n\n\n<li>Result: Cross-file chunks rejected<\/li>\n<\/ul>\n\n\n\n<h4 class=\"sera-block-heading\">5. Brute Force Authentication<\/h4>\n\n\n\n<p class=\"sera-block-paragraph\"><strong>Scenario<\/strong>: Attacker attempts password guessing<\/p>\n\n\n\n<p class=\"sera-block-paragraph\"><strong>Mitigation<\/strong>:<\/p>\n\n\n\n<ul class=\"sera-block-list\">\n<li>PBKDF2 with 100K iterations (~50-100ms per attempt)<\/li>\n\n\n\n<li>Constant-time comparison<\/li>\n\n\n\n<li>Dummy hash for invalid usernames<\/li>\n\n\n\n<li>Recommended: Add account lockout and rate limiting<\/li>\n<\/ul>\n\n\n\n<h4 class=\"sera-block-heading\">6. Timing Attacks<\/h4>\n\n\n\n<p class=\"sera-block-paragraph\"><strong>Scenario<\/strong>: Attacker measures authentication timing to enumerate users<\/p>\n\n\n\n<p class=\"sera-block-paragraph\"><strong>Mitigation<\/strong>:<\/p>\n\n\n\n<ul class=\"sera-block-list\">\n<li>Constant-time password comparison<\/li>\n\n\n\n<li>Dummy hash performed for non-existent users<\/li>\n\n\n\n<li>Same code path for success\/failure<\/li>\n\n\n\n<li>Result: No timing difference between valid\/invalid users<\/li>\n<\/ul>\n\n\n\n<h3 class=\"sera-block-heading\">Compliance Considerations<\/h3>\n\n\n\n<h4 class=\"sera-block-heading\">GDPR (General Data Protection Regulation)<\/h4>\n\n\n\n<ul class=\"sera-block-list\">\n<li><strong>Encryption at Rest<\/strong>: Satisfied by AES-256-GCM<\/li>\n\n\n\n<li><strong>Right to Erasure<\/strong>: Support by securely deleting encrypted files<\/li>\n\n\n\n<li><strong>Data Portability<\/strong>: Users can download their files<\/li>\n\n\n\n<li><strong>Audit Logs<\/strong>: Implement logging of all file access<\/li>\n<\/ul>\n\n\n\n<h4 class=\"sera-block-heading\">HIPAA (Health Insurance Portability and Accountability Act)<\/h4>\n\n\n\n<ul class=\"sera-block-list\">\n<li><strong>Encryption<\/strong>: AES-256 satisfies encryption requirements<\/li>\n\n\n\n<li><strong>Access Controls<\/strong>: Per-user directories and authentication<\/li>\n\n\n\n<li><strong>Audit Trails<\/strong>: Event listener provides basic audit logging<\/li>\n\n\n\n<li><strong>Recommended<\/strong>: Add comprehensive audit logging for PHI<\/li>\n<\/ul>\n\n\n\n<h4 class=\"sera-block-heading\">PCI DSS (Payment Card Industry Data Security Standard)<\/h4>\n\n\n\n<ul class=\"sera-block-list\">\n<li><strong>Encryption<\/strong>: Requirement 3.4 satisfied<\/li>\n\n\n\n<li><strong>Access Control<\/strong>: Requirement 7 (per-user access)<\/li>\n\n\n\n<li><strong>Audit Logging<\/strong>: Requirement 10 (needs enhancement)<\/li>\n\n\n\n<li><strong>Key Management<\/strong>: Requirement 3.6 (needs KMS integration)<\/li>\n<\/ul>\n\n\n\n<h3 class=\"sera-block-heading\">Security Checklist for Production<\/h3>\n\n\n\n<ul class=\"sera-block-list\">\n<li>Replace hardcoded master key with KMS<\/li>\n\n\n\n<li>Implement key rotation policy<\/li>\n\n\n\n<li>Move user authentication to database\/LDAP<\/li>\n\n\n\n<li>Add multi-factor authentication (MFA)<\/li>\n\n\n\n<li>Implement comprehensive audit logging<\/li>\n\n\n\n<li>Set up file system permissions correctly<\/li>\n\n\n\n<li>Configure firewall rules<\/li>\n\n\n\n<li>Enable rate limiting on authentication<\/li>\n\n\n\n<li>Set up encrypted backups of keyset<\/li>\n\n\n\n<li>Document incident response procedures<\/li>\n\n\n\n<li>Conduct security audit\/penetration test<\/li>\n\n\n\n<li>Set up monitoring and alerting<\/li>\n\n\n\n<li>Implement account lockout policy<\/li>\n\n\n\n<li>Configure log retention and analysis<\/li>\n<\/ul>\n\n\n\n<hr class=\"sera-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h2 class=\"sera-block-heading\">Troubleshooting<\/h2>\n\n\n\n<h3 class=\"sera-block-heading\">Common Issues<\/h3>\n\n\n\n<h4 class=\"sera-block-heading\">1. Server Won&#8217;t Start &#8211; Port Already in Use<\/h4>\n\n\n\n<p class=\"sera-block-paragraph\"><strong>Error<\/strong>:<\/p>\n\n\n\n<div class=\"sera-block-kevinbatdorf-code-block-pro cbp-has-line-numbers\" data-code-block-pro-font-family=\"Code-Pro-JetBrains-Mono\" style=\"font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;--cbp-line-number-color:#abb2bf;--cbp-line-number-width:calc(1 * 0.6 * .875rem);line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)\"><span role=\"button\" tabindex=\"0\" style=\"color:#abb2bf;display:none\" aria-label=\"Copy\" class=\"code-block-pro-copy-button\"><pre class=\"code-block-pro-copy-button-pre\" aria-hidden=\"true\"><textarea class=\"code-block-pro-copy-button-textarea\" tabindex=\"-1\" aria-hidden=\"true\" readonly>java.net.BindException: Address already in use\n<\/textarea><\/pre><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" style=\"width:24px;height:24px\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" stroke-width=\"2\"><path class=\"with-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M4.5 12.75l6 6 9-13.5\"><\/path><path class=\"without-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M16.5 8.25V6a2.25 2.25 0 00-2.25-2.25H6A2.25 2.25 0 003.75 6v8.25A2.25 2.25 0 006 16.5h2.25m8.25-8.25H18a2.25 2.25 0 012.25 2.25V18A2.25 2.25 0 0118 20.25h-7.5A2.25 2.25 0 018.25 18v-1.5m8.25-8.25h-6a2.25 2.25 0 00-2.25 2.25v6\"><\/path><\/svg><\/span><pre class=\"shiki one-dark-pro\" style=\"background-color: #282c34\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color: #61AFEF\">java.net.BindException:<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">Address<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">already<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">in<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">use<\/span><\/span>\n<span class=\"line\"><\/span><\/code><\/pre><\/div>\n\n\n\n<p class=\"sera-block-paragraph\"><\/p>\n\n\n\n<p class=\"sera-block-paragraph\"><strong>Solution<\/strong>:<\/p>\n\n\n\n<div class=\"sera-block-kevinbatdorf-code-block-pro cbp-has-line-numbers\" data-code-block-pro-font-family=\"Code-Pro-JetBrains-Mono\" style=\"font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;--cbp-line-number-color:#abb2bf;--cbp-line-number-width:calc(1 * 0.6 * .875rem);line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)\"><span role=\"button\" tabindex=\"0\" style=\"color:#abb2bf;display:none\" aria-label=\"Copy\" class=\"code-block-pro-copy-button\"><pre class=\"code-block-pro-copy-button-pre\" aria-hidden=\"true\"><textarea class=\"code-block-pro-copy-button-textarea\" tabindex=\"-1\" aria-hidden=\"true\" readonly># Find process using port 2222\nlsof -i :2222\nnetstat -tulpn | grep 2222\n\n# Kill process or use different port\njava -Dsftp.port=2223 -jar sftp-server.jar\n<\/textarea><\/pre><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" style=\"width:24px;height:24px\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" stroke-width=\"2\"><path class=\"with-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M4.5 12.75l6 6 9-13.5\"><\/path><path class=\"without-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M16.5 8.25V6a2.25 2.25 0 00-2.25-2.25H6A2.25 2.25 0 003.75 6v8.25A2.25 2.25 0 006 16.5h2.25m8.25-8.25H18a2.25 2.25 0 012.25 2.25V18A2.25 2.25 0 0118 20.25h-7.5A2.25 2.25 0 018.25 18v-1.5m8.25-8.25h-6a2.25 2.25 0 00-2.25 2.25v6\"><\/path><\/svg><\/span><pre class=\"shiki one-dark-pro\" style=\"background-color: #282c34\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color: #7F848E; font-style: italic\"># Find process using port 2222<\/span><\/span>\n<span class=\"line\"><span style=\"color: #61AFEF\">lsof<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #D19A66\">-i<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">:2222<\/span><\/span>\n<span class=\"line\"><span style=\"color: #61AFEF\">netstat<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #D19A66\">-tulpn<\/span><span style=\"color: #ABB2BF\"> | <\/span><span style=\"color: #61AFEF\">grep<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #D19A66\">2222<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #7F848E; font-style: italic\"># Kill process or use different port<\/span><\/span>\n<span class=\"line\"><span style=\"color: #61AFEF\">java<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #D19A66\">-Dsftp.port=2223<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #D19A66\">-jar<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">sftp-server.jar<\/span><\/span>\n<span class=\"line\"><\/span><\/code><\/pre><\/div>\n\n\n\n<h4 class=\"sera-block-heading\">2. Connection Refused<\/h4>\n\n\n\n<p class=\"sera-block-paragraph\"><strong>Error<\/strong> (client):<\/p>\n\n\n\n<pre class=\"sera-block-code\"><code>ssh: connect to host localhost port 2222: Connection refused\n<\/code><\/pre>\n\n\n\n<p class=\"sera-block-paragraph\"><strong>Solutions<\/strong>:<\/p>\n\n\n\n<ol class=\"sera-block-list\">\n<li>Check server is running<\/li>\n\n\n\n<li>Check firewall rules: # Allow port 2222sudo ufw allow 2222\/tcpsudo firewall-cmd &#8211;add-port=2222\/tcp &#8211;permanent<\/li>\n\n\n\n<li>Verify correct port and hostname<\/li>\n<\/ol>\n\n\n\n<h4 class=\"sera-block-heading\">3. Authentication Failed<\/h4>\n\n\n\n<p class=\"sera-block-paragraph\"><strong>Error<\/strong>:<\/p>\n\n\n\n<pre class=\"sera-block-code\"><code>Permission denied (publickey,password).\n<\/code><\/pre>\n\n\n\n<p class=\"sera-block-paragraph\"><strong>Solutions<\/strong>:<\/p>\n\n\n\n<ol class=\"sera-block-list\">\n<li>Verify credentials (default: admin\/admin123)<\/li>\n\n\n\n<li>Check server logs for auth attempts<\/li>\n\n\n\n<li>Verify user exists: UserAuthenticationService.addUser(&#8220;username&#8221;, &#8220;password&#8221;);<\/li>\n<\/ol>\n\n\n\n<h4 class=\"sera-block-heading\">4. File Upload Fails Midway<\/h4>\n\n\n\n<p class=\"sera-block-paragraph\"><strong>Error<\/strong>:<\/p>\n\n\n\n<pre class=\"sera-block-code\"><code>Write failed: Broken pipe\n<\/code><\/pre>\n\n\n\n<p class=\"sera-block-paragraph\"><strong>Possible Causes<\/strong>:<\/p>\n\n\n\n<ol class=\"sera-block-list\">\n<li>Disk full<\/li>\n\n\n\n<li>Out of memory<\/li>\n\n\n\n<li>Network interruption<\/li>\n<\/ol>\n\n\n\n<p class=\"sera-block-paragraph\"><strong>Solutions<\/strong>:<\/p>\n\n\n\n<div class=\"sera-block-kevinbatdorf-code-block-pro cbp-has-line-numbers\" data-code-block-pro-font-family=\"Code-Pro-JetBrains-Mono\" style=\"font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;--cbp-line-number-color:#abb2bf;--cbp-line-number-width:calc(2 * 0.6 * .875rem);line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)\"><span role=\"button\" tabindex=\"0\" style=\"color:#abb2bf;display:none\" aria-label=\"Copy\" class=\"code-block-pro-copy-button\"><pre class=\"code-block-pro-copy-button-pre\" aria-hidden=\"true\"><textarea class=\"code-block-pro-copy-button-textarea\" tabindex=\"-1\" aria-hidden=\"true\" readonly># Check disk space\ndf -h \/data\/sftp-storage\n\n# Check memory\nfree -h\ntop\n\n# Increase memory if needed\njava -Xmx4G -jar sftp-server.jar\n<\/textarea><\/pre><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" style=\"width:24px;height:24px\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" stroke-width=\"2\"><path class=\"with-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M4.5 12.75l6 6 9-13.5\"><\/path><path class=\"without-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M16.5 8.25V6a2.25 2.25 0 00-2.25-2.25H6A2.25 2.25 0 003.75 6v8.25A2.25 2.25 0 006 16.5h2.25m8.25-8.25H18a2.25 2.25 0 012.25 2.25V18A2.25 2.25 0 0118 20.25h-7.5A2.25 2.25 0 018.25 18v-1.5m8.25-8.25h-6a2.25 2.25 0 00-2.25 2.25v6\"><\/path><\/svg><\/span><pre class=\"shiki one-dark-pro\" style=\"background-color: #282c34\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color: #7F848E; font-style: italic\"># Check disk space<\/span><\/span>\n<span class=\"line\"><span style=\"color: #61AFEF\">df<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #D19A66\">-h<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">\/data\/sftp-storage<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #7F848E; font-style: italic\"># Check memory<\/span><\/span>\n<span class=\"line\"><span style=\"color: #61AFEF\">free<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #D19A66\">-h<\/span><\/span>\n<span class=\"line\"><span style=\"color: #61AFEF\">top<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #7F848E; font-style: italic\"># Increase memory if needed<\/span><\/span>\n<span class=\"line\"><span style=\"color: #61AFEF\">java<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #D19A66\">-Xmx4G<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #D19A66\">-jar<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">sftp-server.jar<\/span><\/span>\n<span class=\"line\"><\/span><\/code><\/pre><\/div>\n\n\n\n<h4 class=\"sera-block-heading\">5. Encryption\/Decryption Errors<\/h4>\n\n\n\n<p class=\"sera-block-paragraph\"><strong>Error<\/strong>:<\/p>\n\n\n\n<div class=\"sera-block-kevinbatdorf-code-block-pro cbp-has-line-numbers\" data-code-block-pro-font-family=\"Code-Pro-JetBrains-Mono\" style=\"font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;--cbp-line-number-color:#abb2bf;--cbp-line-number-width:calc(1 * 0.6 * .875rem);line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)\"><span role=\"button\" tabindex=\"0\" style=\"color:#abb2bf;display:none\" aria-label=\"Copy\" class=\"code-block-pro-copy-button\"><pre class=\"code-block-pro-copy-button-pre\" aria-hidden=\"true\"><textarea class=\"code-block-pro-copy-button-textarea\" tabindex=\"-1\" aria-hidden=\"true\" readonly>GeneralSecurityException: decryption failed\n<\/textarea><\/pre><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" style=\"width:24px;height:24px\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" stroke-width=\"2\"><path class=\"with-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M4.5 12.75l6 6 9-13.5\"><\/path><path class=\"without-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M16.5 8.25V6a2.25 2.25 0 00-2.25-2.25H6A2.25 2.25 0 003.75 6v8.25A2.25 2.25 0 006 16.5h2.25m8.25-8.25H18a2.25 2.25 0 012.25 2.25V18A2.25 2.25 0 0118 20.25h-7.5A2.25 2.25 0 018.25 18v-1.5m8.25-8.25h-6a2.25 2.25 0 00-2.25 2.25v6\"><\/path><\/svg><\/span><pre class=\"shiki one-dark-pro\" style=\"background-color: #282c34\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color: #61AFEF\">GeneralSecurityException:<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">decryption<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">failed<\/span><\/span>\n<span class=\"line\"><\/span><\/code><\/pre><\/div>\n\n\n\n<p class=\"sera-block-paragraph\"><strong>Causes<\/strong>:<\/p>\n\n\n\n<ol class=\"sera-block-list\">\n<li>File corrupted on disk<\/li>\n\n\n\n<li>Wrong encryption key<\/li>\n\n\n\n<li>File modified outside SFTP<\/li>\n<\/ol>\n\n\n\n<p class=\"sera-block-paragraph\"><strong>Solutions<\/strong>:<\/p>\n\n\n\n<ol class=\"sera-block-list\">\n<li>Verify keyset.json not modified<\/li>\n\n\n\n<li>Check file integrity: # File should start with &#8220;CENC&#8221;xxd -l 4 \/data\/sftp-storage\/admin\/file.pdf<\/li>\n\n\n\n<li>Restore from backup if corrupted<\/li>\n<\/ol>\n\n\n\n<h4 class=\"sera-block-heading\">6. High Memory Usage<\/h4>\n\n\n\n<p class=\"sera-block-paragraph\"><strong>Symptom<\/strong>:<\/p>\n\n\n\n<div class=\"sera-block-kevinbatdorf-code-block-pro cbp-has-line-numbers\" data-code-block-pro-font-family=\"Code-Pro-JetBrains-Mono\" style=\"font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;--cbp-line-number-color:#abb2bf;--cbp-line-number-width:calc(1 * 0.6 * .875rem);line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)\"><span role=\"button\" tabindex=\"0\" style=\"color:#abb2bf;display:none\" aria-label=\"Copy\" class=\"code-block-pro-copy-button\"><pre class=\"code-block-pro-copy-button-pre\" aria-hidden=\"true\"><textarea class=\"code-block-pro-copy-button-textarea\" tabindex=\"-1\" aria-hidden=\"true\" readonly>Java heap space OutOfMemoryError\n<\/textarea><\/pre><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" style=\"width:24px;height:24px\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" stroke-width=\"2\"><path class=\"with-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M4.5 12.75l6 6 9-13.5\"><\/path><path class=\"without-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M16.5 8.25V6a2.25 2.25 0 00-2.25-2.25H6A2.25 2.25 0 003.75 6v8.25A2.25 2.25 0 006 16.5h2.25m8.25-8.25H18a2.25 2.25 0 012.25 2.25V18A2.25 2.25 0 0118 20.25h-7.5A2.25 2.25 0 018.25 18v-1.5m8.25-8.25h-6a2.25 2.25 0 00-2.25 2.25v6\"><\/path><\/svg><\/span><pre class=\"shiki one-dark-pro\" style=\"background-color: #282c34\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color: #61AFEF\">Java<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">heap<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">space<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">OutOfMemoryError<\/span><\/span>\n<span class=\"line\"><\/span><\/code><\/pre><\/div>\n\n\n\n<p class=\"sera-block-paragraph\"><strong>Solutions<\/strong>:<\/p>\n\n\n\n<ol class=\"sera-block-list\">\n<li>Reduce chunk size: java -Dsftp.chunk.size=32768 -jar sftp-server.jar<\/li>\n\n\n\n<li>Increase heap: java -Xmx4G -jar sftp-server.jar<\/li>\n\n\n\n<li>Limit concurrent connections (implement connection pooling)<\/li>\n<\/ol>\n\n\n\n<h4 class=\"sera-block-heading\">7. Slow Performance<\/h4>\n\n\n\n<p class=\"sera-block-paragraph\"><strong>Symptoms<\/strong>:<\/p>\n\n\n\n<ul class=\"sera-block-list\">\n<li>Slow uploads\/downloads<\/li>\n\n\n\n<li>High CPU usage<\/li>\n<\/ul>\n\n\n\n<p class=\"sera-block-paragraph\"><strong>Solutions<\/strong>:<\/p>\n\n\n\n<ol class=\"sera-block-list\">\n<li>Check disk I\/O: iostat -x 1 10<\/li>\n\n\n\n<li>Check CPU: top<\/li>\n\n\n\n<li>Optimize chunk size based on workload<\/li>\n\n\n\n<li>Use SSD instead of HDD<\/li>\n\n\n\n<li>Check network bandwidth: iperf3 -s # On server iperf3 -c server_ip # On client<\/li>\n<\/ol>\n\n\n\n<h3 class=\"sera-block-heading\">Debug Logging<\/h3>\n\n\n\n<p class=\"sera-block-paragraph\">Enable detailed logging:<\/p>\n\n\n\n<div class=\"sera-block-kevinbatdorf-code-block-pro cbp-has-line-numbers\" data-code-block-pro-font-family=\"Code-Pro-JetBrains-Mono\" style=\"font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;--cbp-line-number-color:#abb2bf;--cbp-line-number-width:calc(1 * 0.6 * .875rem);line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)\"><span role=\"button\" tabindex=\"0\" style=\"color:#abb2bf;display:none\" aria-label=\"Copy\" class=\"code-block-pro-copy-button\"><pre class=\"code-block-pro-copy-button-pre\" aria-hidden=\"true\"><textarea class=\"code-block-pro-copy-button-textarea\" tabindex=\"-1\" aria-hidden=\"true\" readonly># Set logging level\njava -Dorg.apache.sshd.common.util.logging=DEBUG \\\n     -jar sftp-server.jar\n<\/textarea><\/pre><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" style=\"width:24px;height:24px\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" stroke-width=\"2\"><path class=\"with-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M4.5 12.75l6 6 9-13.5\"><\/path><path class=\"without-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M16.5 8.25V6a2.25 2.25 0 00-2.25-2.25H6A2.25 2.25 0 003.75 6v8.25A2.25 2.25 0 006 16.5h2.25m8.25-8.25H18a2.25 2.25 0 012.25 2.25V18A2.25 2.25 0 0118 20.25h-7.5A2.25 2.25 0 018.25 18v-1.5m8.25-8.25h-6a2.25 2.25 0 00-2.25 2.25v6\"><\/path><\/svg><\/span><pre class=\"shiki one-dark-pro\" style=\"background-color: #282c34\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color: #7F848E; font-style: italic\"># Set logging level<\/span><\/span>\n<span class=\"line\"><span style=\"color: #61AFEF\">java<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #D19A66\">-Dorg.apache.sshd.common.util.logging=DEBUG<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #56B6C2\">\\<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">     <\/span><span style=\"color: #D19A66\">-jar<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">sftp-server.jar<\/span><\/span>\n<span class=\"line\"><\/span><\/code><\/pre><\/div>\n\n\n\n<p class=\"sera-block-paragraph\">Create <code>logback.xml<\/code>:<\/p>\n\n\n\n<div class=\"sera-block-kevinbatdorf-code-block-pro cbp-has-line-numbers\" data-code-block-pro-font-family=\"Code-Pro-JetBrains-Mono\" style=\"font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;--cbp-line-number-color:#abb2bf;--cbp-line-number-width:calc(2 * 0.6 * .875rem);line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)\"><span role=\"button\" tabindex=\"0\" style=\"color:#abb2bf;display:none\" aria-label=\"Copy\" class=\"code-block-pro-copy-button\"><pre class=\"code-block-pro-copy-button-pre\" aria-hidden=\"true\"><textarea class=\"code-block-pro-copy-button-textarea\" tabindex=\"-1\" aria-hidden=\"true\" readonly>&lt;configuration>\n    &lt;appender name=\"STDOUT\" class=\"ch.qos.logback.core.ConsoleAppender\">\n        &lt;encoder>\n            &lt;pattern>%d{HH:mm:ss.SSS} &#91;%thread&#93; %-5level %logger{36} - %msg%n&lt;\/pattern>\n        &lt;\/encoder>\n    &lt;\/appender>\n    \n    &lt;root level=\"DEBUG\">\n        &lt;appender-ref ref=\"STDOUT\" \/>\n    &lt;\/root>\n&lt;\/configuration>\n<\/textarea><\/pre><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" style=\"width:24px;height:24px\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" stroke-width=\"2\"><path class=\"with-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M4.5 12.75l6 6 9-13.5\"><\/path><path class=\"without-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M16.5 8.25V6a2.25 2.25 0 00-2.25-2.25H6A2.25 2.25 0 003.75 6v8.25A2.25 2.25 0 006 16.5h2.25m8.25-8.25H18a2.25 2.25 0 012.25 2.25V18A2.25 2.25 0 0118 20.25h-7.5A2.25 2.25 0 018.25 18v-1.5m8.25-8.25h-6a2.25 2.25 0 00-2.25 2.25v6\"><\/path><\/svg><\/span><pre class=\"shiki one-dark-pro\" style=\"background-color: #282c34\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color: #ABB2BF\">&lt;configuration&gt;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">    &lt;<\/span><span style=\"color: #61AFEF\">appender<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">name=&quot;STDOUT&quot;<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">class=&quot;ch.qos.logback.core.ConsoleAppender&quot;<\/span><span style=\"color: #ABB2BF\">&gt;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">        &lt;<\/span><span style=\"color: #61AFEF\">encoder&gt;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">            &lt;<\/span><span style=\"color: #61AFEF\">pattern&gt;%d<\/span><span style=\"color: #ABB2BF\">{HH:mm:ss.SSS} &#91;%thread&#93; %-5level %logger{<\/span><span style=\"color: #61AFEF\">36}<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">-<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">%msg%n<\/span><span style=\"color: #ABB2BF\">&lt;<\/span><span style=\"color: #98C379\">\/patter<\/span><span style=\"color: #ABB2BF\">n&gt;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">        &lt;<\/span><span style=\"color: #61AFEF\">\/encoder&gt;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">    &lt;<\/span><span style=\"color: #61AFEF\">\/appender&gt;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">    <\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">    &lt;<\/span><span style=\"color: #61AFEF\">root<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">level=&quot;DEBUG&quot;<\/span><span style=\"color: #ABB2BF\">&gt;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">        &lt;<\/span><span style=\"color: #61AFEF\">appender-ref<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">ref=&quot;STDOUT&quot;<\/span><span style=\"color: #ABB2BF\"> \/&gt;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">    &lt;<\/span><span style=\"color: #61AFEF\">\/root&gt;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">&lt;\/configuration&gt;<\/span><\/span>\n<span class=\"line\"><\/span><\/code><\/pre><\/div>\n\n\n\n<h3 class=\"sera-block-heading\">Monitoring<\/h3>\n\n\n\n<p class=\"sera-block-paragraph\"><strong>Key Metrics to Monitor<\/strong>:<\/p>\n\n\n\n<ol class=\"sera-block-list\">\n<li><strong>System Metrics<\/strong>:\n<ul class=\"sera-block-list\">\n<li>CPU usage<\/li>\n\n\n\n<li>Memory usage<\/li>\n\n\n\n<li>Disk I\/O<\/li>\n\n\n\n<li>Network throughput<\/li>\n<\/ul>\n<\/li>\n\n\n\n<li><strong>Application Metrics<\/strong>:\n<ul class=\"sera-block-list\">\n<li>Active connections<\/li>\n\n\n\n<li>Authentication failures<\/li>\n\n\n\n<li>File transfer rates<\/li>\n\n\n\n<li>Error rates<\/li>\n<\/ul>\n<\/li>\n\n\n\n<li><strong>Security Metrics<\/strong>:\n<ul class=\"sera-block-list\">\n<li>Failed login attempts<\/li>\n\n\n\n<li>Unusual file access patterns<\/li>\n\n\n\n<li>Encryption\/decryption errors<\/li>\n<\/ul>\n<\/li>\n<\/ol>\n\n\n\n<p class=\"sera-block-paragraph\"><strong>Example Monitoring Script<\/strong>:<\/p>\n\n\n\n<div class=\"sera-block-kevinbatdorf-code-block-pro cbp-has-line-numbers\" data-code-block-pro-font-family=\"Code-Pro-JetBrains-Mono\" style=\"font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;--cbp-line-number-color:#abb2bf;--cbp-line-number-width:calc(2 * 0.6 * .875rem);line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)\"><span role=\"button\" tabindex=\"0\" style=\"color:#abb2bf;display:none\" aria-label=\"Copy\" class=\"code-block-pro-copy-button\"><pre class=\"code-block-pro-copy-button-pre\" aria-hidden=\"true\"><textarea class=\"code-block-pro-copy-button-textarea\" tabindex=\"-1\" aria-hidden=\"true\" readonly>#!\/bin\/bash\n\n# Monitor SFTP server health\nwhile true; do\n    # Check if server is running\n    if ! pgrep -f \"ChunkedEncryptedSftpServer\" > \/dev\/null; then\n        echo \"ALERT: SFTP server is down!\" | mail -s \"SFTP Alert\" admin@example.com\n    fi\n    \n    # Check disk space\n    DISK_USAGE=$(df -h \/data\/sftp-storage | awk 'NR==2 {print $5}' | sed 's\/%\/\/')\n    if &#91; $DISK_USAGE -gt 90 &#93;; then\n        echo \"ALERT: Disk usage at ${DISK_USAGE}%\" | mail -s \"Disk Alert\" admin@example.com\n    fi\n    \n    # Check memory\n    MEM_USAGE=$(free | awk 'NR==2 {print $3\/$2 * 100.0}')\n    if (( $(echo \"$MEM_USAGE > 90\" | bc -l) )); then\n        echo \"ALERT: Memory usage at ${MEM_USAGE}%\" | mail -s \"Memory Alert\" admin@example.com\n    fi\n    \n    sleep 300  # Check every 5 minutes\ndone\n<\/textarea><\/pre><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" style=\"width:24px;height:24px\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" stroke-width=\"2\"><path class=\"with-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M4.5 12.75l6 6 9-13.5\"><\/path><path class=\"without-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M16.5 8.25V6a2.25 2.25 0 00-2.25-2.25H6A2.25 2.25 0 003.75 6v8.25A2.25 2.25 0 006 16.5h2.25m8.25-8.25H18a2.25 2.25 0 012.25 2.25V18A2.25 2.25 0 0118 20.25h-7.5A2.25 2.25 0 018.25 18v-1.5m8.25-8.25h-6a2.25 2.25 0 00-2.25 2.25v6\"><\/path><\/svg><\/span><pre class=\"shiki one-dark-pro\" style=\"background-color: #282c34\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color: #7F848E; font-style: italic\">#!\/bin\/bash<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #7F848E; font-style: italic\"># Monitor SFTP server health<\/span><\/span>\n<span class=\"line\"><span style=\"color: #C678DD\">while<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #56B6C2\">true<\/span><span style=\"color: #ABB2BF\">; <\/span><span style=\"color: #C678DD\">do<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">    <\/span><span style=\"color: #7F848E; font-style: italic\"># Check if server is running<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">    <\/span><span style=\"color: #C678DD\">if<\/span><span style=\"color: #ABB2BF\"> ! <\/span><span style=\"color: #61AFEF\">pgrep<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #D19A66\">-f<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">&quot;ChunkedEncryptedSftpServer&quot;<\/span><span style=\"color: #ABB2BF\"> &gt; <\/span><span style=\"color: #98C379\">\/dev\/null<\/span><span style=\"color: #ABB2BF\">; <\/span><span style=\"color: #C678DD\">then<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">        <\/span><span style=\"color: #56B6C2\">echo<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">&quot;ALERT: SFTP server is down!&quot;<\/span><span style=\"color: #ABB2BF\"> | <\/span><span style=\"color: #61AFEF\">mail<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #D19A66\">-s<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">&quot;SFTP Alert&quot;<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">admin@example.com<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">    <\/span><span style=\"color: #C678DD\">fi<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">    <\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">    <\/span><span style=\"color: #7F848E; font-style: italic\"># Check disk space<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">    <\/span><span style=\"color: #E06C75\">DISK_USAGE<\/span><span style=\"color: #56B6C2\">=<\/span><span style=\"color: #98C379\">$(<\/span><span style=\"color: #61AFEF\">df<\/span><span style=\"color: #98C379\"> <\/span><span style=\"color: #D19A66\">-h<\/span><span style=\"color: #98C379\"> \/data\/sftp-storage <\/span><span style=\"color: #ABB2BF\">|<\/span><span style=\"color: #98C379\"> <\/span><span style=\"color: #61AFEF\">awk<\/span><span style=\"color: #98C379\"> &#39;NR==2 {print $5}&#39; <\/span><span style=\"color: #ABB2BF\">|<\/span><span style=\"color: #98C379\"> <\/span><span style=\"color: #61AFEF\">sed<\/span><span style=\"color: #98C379\"> &#39;s\/%\/\/&#39;)<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">    <\/span><span style=\"color: #C678DD\">if<\/span><span style=\"color: #ABB2BF\"> &#91; <\/span><span style=\"color: #E06C75\">$DISK_USAGE<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #56B6C2\">-gt<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #D19A66\">90<\/span><span style=\"color: #ABB2BF\"> &#93;; <\/span><span style=\"color: #C678DD\">then<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">        <\/span><span style=\"color: #56B6C2\">echo<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">&quot;ALERT: Disk usage at ${<\/span><span style=\"color: #E06C75\">DISK_USAGE<\/span><span style=\"color: #98C379\">}%&quot;<\/span><span style=\"color: #ABB2BF\"> | <\/span><span style=\"color: #61AFEF\">mail<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #D19A66\">-s<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">&quot;Disk Alert&quot;<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">admin@example.com<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">    <\/span><span style=\"color: #C678DD\">fi<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">    <\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">    <\/span><span style=\"color: #7F848E; font-style: italic\"># Check memory<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">    <\/span><span style=\"color: #E06C75\">MEM_USAGE<\/span><span style=\"color: #56B6C2\">=<\/span><span style=\"color: #98C379\">$(<\/span><span style=\"color: #61AFEF\">free<\/span><span style=\"color: #98C379\"> <\/span><span style=\"color: #ABB2BF\">|<\/span><span style=\"color: #98C379\"> <\/span><span style=\"color: #61AFEF\">awk<\/span><span style=\"color: #98C379\"> &#39;NR==2 {print $3\/$2 * 100.0}&#39;)<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">    <\/span><span style=\"color: #C678DD\">if<\/span><span style=\"color: #ABB2BF\"> (( $(echo &quot;<\/span><span style=\"color: #E06C75\">$MEM_USAGE<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #56B6C2\">&gt;<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #D19A66\">90<\/span><span style=\"color: #ABB2BF\">&quot; <\/span><span style=\"color: #56B6C2\">|<\/span><span style=\"color: #ABB2BF\"> bc <\/span><span style=\"color: #56B6C2\">-<\/span><span style=\"color: #ABB2BF\">l) )); <\/span><span style=\"color: #C678DD\">then<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">        <\/span><span style=\"color: #56B6C2\">echo<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">&quot;ALERT: Memory usage at ${<\/span><span style=\"color: #E06C75\">MEM_USAGE<\/span><span style=\"color: #98C379\">}%&quot;<\/span><span style=\"color: #ABB2BF\"> | <\/span><span style=\"color: #61AFEF\">mail<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #D19A66\">-s<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">&quot;Memory Alert&quot;<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">admin@example.com<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">    <\/span><span style=\"color: #C678DD\">fi<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">    <\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">    <\/span><span style=\"color: #61AFEF\">sleep<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #D19A66\">300<\/span><span style=\"color: #ABB2BF\">  <\/span><span style=\"color: #7F848E; font-style: italic\"># Check every 5 minutes<\/span><\/span>\n<span class=\"line\"><span style=\"color: #C678DD\">done<\/span><\/span>\n<span class=\"line\"><\/span><\/code><\/pre><\/div>\n\n\n\n<hr class=\"sera-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h2 class=\"sera-block-heading\">API Reference<\/h2>\n\n\n\n<h3 class=\"sera-block-heading\">ChunkedEncryptionService<\/h3>\n\n\n\n<div class=\"sera-block-kevinbatdorf-code-block-pro cbp-has-line-numbers\" data-code-block-pro-font-family=\"Code-Pro-JetBrains-Mono\" style=\"font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;--cbp-line-number-color:#abb2bf;--cbp-line-number-width:calc(2 * 0.6 * .875rem);line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)\"><span role=\"button\" tabindex=\"0\" style=\"color:#abb2bf;display:none\" aria-label=\"Copy\" class=\"code-block-pro-copy-button\"><pre class=\"code-block-pro-copy-button-pre\" aria-hidden=\"true\"><textarea class=\"code-block-pro-copy-button-textarea\" tabindex=\"-1\" aria-hidden=\"true\" readonly>public class ChunkedEncryptionService {\n    \/**\n     * Constructor with default chunk size (64KB)\n     *\/\n    public ChunkedEncryptionService(Path keysetPath) \n        throws GeneralSecurityException, IOException\n    \n    \/**\n     * Constructor with custom chunk size\n     *\/\n    public ChunkedEncryptionService(Path keysetPath, int chunkSize) \n        throws GeneralSecurityException, IOException\n    \n    \/**\n     * Encrypt plaintext stream and write to output\n     *\/\n    public void encryptStream(byte[] plaintext, String filename, OutputStream output)\n        throws GeneralSecurityException, IOException\n    \n    \/**\n     * Decrypt stream from input and return plaintext\n     *\/\n    public byte[] decryptStream(InputStream input, String filename)\n        throws GeneralSecurityException, IOException\n    \n    \/**\n     * Get file header without decrypting content\n     *\/\n    public FileHeader getFileHeader(InputStream input) throws IOException\n    \n    \/**\n     * Decrypt specific chunk by index (for random access)\n     *\/\n    public byte[] decryptChunkByIndex(\n        RandomAccessFile input, \n        String filename, \n        int chunkIndex\n    ) throws IOException, GeneralSecurityException\n    \n    \/**\n     * Encrypt single chunk\n     *\/\n    public byte[] encryptChunk(byte[] chunk, String filename, int chunkIndex)\n        throws GeneralSecurityException\n    \n    \/**\n     * Decrypt single chunk\n     *\/\n    public byte[] decryptChunk(byte[] encryptedChunk, String filename, int chunkIndex)\n        throws GeneralSecurityException\n    \n    \/**\n     * Get configured chunk size\n     *\/\n    public int getChunkSize()\n    \n    \/**\n     * File header information\n     *\/\n    public static class FileHeader {\n        public final short version;\n        public final int chunkSize;\n        public final long originalSize;\n        \n        public int getTotalChunks()\n    }\n}\n<\/textarea><\/pre><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" style=\"width:24px;height:24px\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" stroke-width=\"2\"><path class=\"with-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M4.5 12.75l6 6 9-13.5\"><\/path><path class=\"without-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M16.5 8.25V6a2.25 2.25 0 00-2.25-2.25H6A2.25 2.25 0 003.75 6v8.25A2.25 2.25 0 006 16.5h2.25m8.25-8.25H18a2.25 2.25 0 012.25 2.25V18A2.25 2.25 0 0118 20.25h-7.5A2.25 2.25 0 018.25 18v-1.5m8.25-8.25h-6a2.25 2.25 0 00-2.25 2.25v6\"><\/path><\/svg><\/span><pre class=\"shiki one-dark-pro\" style=\"background-color: #282c34\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color: #61AFEF\">public<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">class<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">ChunkedEncryptionService<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">{<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">    <\/span><span style=\"color: #61AFEF\">\/**<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">     <\/span><span style=\"color: #61AFEF\">*<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">Constructor<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">with<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">default<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">chunk<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">size<\/span><span style=\"color: #ABB2BF\"> (64KB)<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">     <\/span><span style=\"color: #61AFEF\">*\/<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">    <\/span><span style=\"color: #61AFEF\">public<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">ChunkedEncryptionService<\/span><span style=\"color: #ABB2BF\">(<\/span><span style=\"color: #61AFEF\">Path<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">keysetPath<\/span><span style=\"color: #ABB2BF\">) <\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">        <\/span><span style=\"color: #61AFEF\">throws<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">GeneralSecurityException,<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">IOException<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">    <\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">    <\/span><span style=\"color: #61AFEF\">\/**<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">     <\/span><span style=\"color: #61AFEF\">*<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">Constructor<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">with<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">custom<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">chunk<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">size<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">     <\/span><span style=\"color: #61AFEF\">*\/<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">    <\/span><span style=\"color: #61AFEF\">public<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">ChunkedEncryptionService<\/span><span style=\"color: #ABB2BF\">(<\/span><span style=\"color: #61AFEF\">Path<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">keysetPath,<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">int<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">chunkSize<\/span><span style=\"color: #ABB2BF\">) <\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">        <\/span><span style=\"color: #61AFEF\">throws<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">GeneralSecurityException,<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">IOException<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">    <\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">    <\/span><span style=\"color: #61AFEF\">\/**<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">     <\/span><span style=\"color: #61AFEF\">*<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">Encrypt<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">plaintext<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">stream<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">and<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">write<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">to<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">output<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">     <\/span><span style=\"color: #61AFEF\">*\/<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">    <\/span><span style=\"color: #61AFEF\">public<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">void<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">encryptStream<\/span><span style=\"color: #ABB2BF\">(<\/span><span style=\"color: #61AFEF\">byte[]<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">plaintext,<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">String<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">filename,<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">OutputStream<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">output<\/span><span style=\"color: #ABB2BF\">)<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">        <\/span><span style=\"color: #61AFEF\">throws<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">GeneralSecurityException,<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">IOException<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">    <\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">    <\/span><span style=\"color: #61AFEF\">\/**<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">     <\/span><span style=\"color: #61AFEF\">*<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">Decrypt<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">stream<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">from<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">input<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">and<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">return<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">plaintext<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">     <\/span><span style=\"color: #61AFEF\">*\/<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">    <\/span><span style=\"color: #61AFEF\">public<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">byte[]<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">decryptStream<\/span><span style=\"color: #ABB2BF\">(<\/span><span style=\"color: #61AFEF\">InputStream<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">input,<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">String<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">filename<\/span><span style=\"color: #ABB2BF\">)<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">        <\/span><span style=\"color: #61AFEF\">throws<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">GeneralSecurityException,<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">IOException<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">    <\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">    <\/span><span style=\"color: #61AFEF\">\/**<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">     <\/span><span style=\"color: #61AFEF\">*<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">Get<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">file<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">header<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">without<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">decrypting<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">content<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">     <\/span><span style=\"color: #61AFEF\">*\/<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">    <\/span><span style=\"color: #61AFEF\">public<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">FileHeader<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">getFileHeader<\/span><span style=\"color: #ABB2BF\">(<\/span><span style=\"color: #61AFEF\">InputStream<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">input<\/span><span style=\"color: #ABB2BF\">) <\/span><span style=\"color: #98C379\">throws<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">IOException<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">    <\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">    <\/span><span style=\"color: #61AFEF\">\/**<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">     <\/span><span style=\"color: #61AFEF\">*<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">Decrypt<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">specific<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">chunk<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">by<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">index<\/span><span style=\"color: #ABB2BF\"> (for <\/span><span style=\"color: #98C379\">random<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">access<\/span><span style=\"color: #ABB2BF\">)<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">     <\/span><span style=\"color: #61AFEF\">*\/<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">    <\/span><span style=\"color: #61AFEF\">public<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">byte[]<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">decryptChunkByIndex<\/span><span style=\"color: #ABB2BF\">(<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">        <\/span><span style=\"color: #61AFEF\">RandomAccessFile<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">input,<\/span><span style=\"color: #ABB2BF\"> <\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">        <\/span><span style=\"color: #61AFEF\">String<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">filename,<\/span><span style=\"color: #ABB2BF\"> <\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">        <\/span><span style=\"color: #61AFEF\">int<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">chunkIndex<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">    ) <\/span><span style=\"color: #98C379\">throws<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">IOException,<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">GeneralSecurityException<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">    <\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">    <\/span><span style=\"color: #61AFEF\">\/**<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">     <\/span><span style=\"color: #61AFEF\">*<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">Encrypt<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">single<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">chunk<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">     <\/span><span style=\"color: #61AFEF\">*\/<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">    <\/span><span style=\"color: #61AFEF\">public<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">byte[]<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">encryptChunk<\/span><span style=\"color: #ABB2BF\">(<\/span><span style=\"color: #61AFEF\">byte[]<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">chunk,<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">String<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">filename,<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">int<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">chunkIndex<\/span><span style=\"color: #ABB2BF\">)<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">        <\/span><span style=\"color: #61AFEF\">throws<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">GeneralSecurityException<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">    <\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">    <\/span><span style=\"color: #61AFEF\">\/**<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">     <\/span><span style=\"color: #61AFEF\">*<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">Decrypt<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">single<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">chunk<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">     <\/span><span style=\"color: #61AFEF\">*\/<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">    <\/span><span style=\"color: #61AFEF\">public<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">byte[]<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">decryptChunk<\/span><span style=\"color: #ABB2BF\">(<\/span><span style=\"color: #61AFEF\">byte[]<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">encryptedChunk,<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">String<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">filename,<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">int<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">chunkIndex<\/span><span style=\"color: #ABB2BF\">)<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">        <\/span><span style=\"color: #61AFEF\">throws<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">GeneralSecurityException<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">    <\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">    <\/span><span style=\"color: #61AFEF\">\/**<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">     <\/span><span style=\"color: #61AFEF\">*<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">Get<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">configured<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">chunk<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">size<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">     <\/span><span style=\"color: #61AFEF\">*\/<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">    <\/span><span style=\"color: #61AFEF\">public<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">int<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">getChunkSize<\/span><span style=\"color: #ABB2BF\">()<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">    <\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">    <\/span><span style=\"color: #61AFEF\">\/**<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">     <\/span><span style=\"color: #61AFEF\">*<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">File<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">header<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">information<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">     <\/span><span style=\"color: #61AFEF\">*\/<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">    <\/span><span style=\"color: #61AFEF\">public<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">static<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">class<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">FileHeader<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">{<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">        <\/span><span style=\"color: #61AFEF\">public<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">final<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">short<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">version<\/span><span style=\"color: #ABB2BF\">;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">        <\/span><span style=\"color: #61AFEF\">public<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">final<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">int<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">chunkSize<\/span><span style=\"color: #ABB2BF\">;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">        <\/span><span style=\"color: #61AFEF\">public<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">final<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">long<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">originalSize<\/span><span style=\"color: #ABB2BF\">;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">        <\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">        <\/span><span style=\"color: #61AFEF\">public<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">int<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">getTotalChunks<\/span><span style=\"color: #ABB2BF\">()<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">    }<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">}<\/span><\/span>\n<span class=\"line\"><\/span><\/code><\/pre><\/div>\n\n\n\n<h3 class=\"sera-block-heading\">UserAuthenticationService<\/h3>\n\n\n\n<div class=\"sera-block-kevinbatdorf-code-block-pro cbp-has-line-numbers\" data-code-block-pro-font-family=\"Code-Pro-JetBrains-Mono\" style=\"font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;--cbp-line-number-color:#abb2bf;--cbp-line-number-width:calc(2 * 0.6 * .875rem);line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)\"><span role=\"button\" tabindex=\"0\" style=\"color:#abb2bf;display:none\" aria-label=\"Copy\" class=\"code-block-pro-copy-button\"><pre class=\"code-block-pro-copy-button-pre\" aria-hidden=\"true\"><textarea class=\"code-block-pro-copy-button-textarea\" tabindex=\"-1\" aria-hidden=\"true\" readonly>public class UserAuthenticationService {\n    \/**\n     * Authenticate user with username and password\n     * Returns true if credentials valid, false otherwise\n     *\/\n    public static boolean authenticate(String username, String password)\n    \n    \/**\n     * Add new user with password\n     * Minimum password length: 8 characters\n     *\/\n    public static void addUser(String username, String password) throws Exception\n}\n<\/textarea><\/pre><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" style=\"width:24px;height:24px\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" stroke-width=\"2\"><path class=\"with-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M4.5 12.75l6 6 9-13.5\"><\/path><path class=\"without-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M16.5 8.25V6a2.25 2.25 0 00-2.25-2.25H6A2.25 2.25 0 003.75 6v8.25A2.25 2.25 0 006 16.5h2.25m8.25-8.25H18a2.25 2.25 0 012.25 2.25V18A2.25 2.25 0 0118 20.25h-7.5A2.25 2.25 0 018.25 18v-1.5m8.25-8.25h-6a2.25 2.25 0 00-2.25 2.25v6\"><\/path><\/svg><\/span><pre class=\"shiki one-dark-pro\" style=\"background-color: #282c34\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color: #61AFEF\">public<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">class<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">UserAuthenticationService<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">{<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">    <\/span><span style=\"color: #61AFEF\">\/**<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">     <\/span><span style=\"color: #61AFEF\">*<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">Authenticate<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">user<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">with<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">username<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">and<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">password<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">     <\/span><span style=\"color: #61AFEF\">*<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">Returns<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #D19A66\">true<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">if<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">credentials<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">valid,<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #D19A66\">false<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">otherwise<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">     <\/span><span style=\"color: #61AFEF\">*\/<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">    <\/span><span style=\"color: #61AFEF\">public<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">static<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">boolean<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">authenticate<\/span><span style=\"color: #ABB2BF\">(<\/span><span style=\"color: #61AFEF\">String<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">username,<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">String<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">password<\/span><span style=\"color: #ABB2BF\">)<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">    <\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">    <\/span><span style=\"color: #61AFEF\">\/**<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">     <\/span><span style=\"color: #61AFEF\">*<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">Add<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">new<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">user<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">with<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">password<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">     <\/span><span style=\"color: #61AFEF\">*<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">Minimum<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">password<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">length:<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #D19A66\">8<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">characters<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">     <\/span><span style=\"color: #61AFEF\">*\/<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">    <\/span><span style=\"color: #61AFEF\">public<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">static<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">void<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">addUser<\/span><span style=\"color: #ABB2BF\">(<\/span><span style=\"color: #61AFEF\">String<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">username,<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">String<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">password<\/span><span style=\"color: #ABB2BF\">) <\/span><span style=\"color: #98C379\">throws<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">Exception<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">}<\/span><\/span>\n<span class=\"line\"><\/span><\/code><\/pre><\/div>\n\n\n\n<h3 class=\"sera-block-heading\">ChunkedEncryptedSftpServer<\/h3>\n\n\n\n<div class=\"sera-block-kevinbatdorf-code-block-pro cbp-has-line-numbers\" data-code-block-pro-font-family=\"Code-Pro-JetBrains-Mono\" style=\"font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;--cbp-line-number-color:#abb2bf;--cbp-line-number-width:calc(2 * 0.6 * .875rem);line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)\"><span role=\"button\" tabindex=\"0\" style=\"color:#abb2bf;display:none\" aria-label=\"Copy\" class=\"code-block-pro-copy-button\"><pre class=\"code-block-pro-copy-button-pre\" aria-hidden=\"true\"><textarea class=\"code-block-pro-copy-button-textarea\" tabindex=\"-1\" aria-hidden=\"true\" readonly>public class ChunkedEncryptedSftpServer {\n    \/**\n     * Create SFTP server with encryption\n     *\/\n    public ChunkedEncryptedSftpServer(\n        int port,\n        Path storageRoot,\n        Path keysetPath,\n        boolean useEncExtension,\n        int chunkSize\n    ) throws Exception\n    \n    \/**\n     * Start the SFTP server\n     *\/\n    public void start() throws IOException\n    \n    \/**\n     * Stop the SFTP server\n     *\/\n    public void stop() throws IOException\n    \n    \/**\n     * Check if server is running\n     *\/\n    public boolean isStarted()\n    \n    \/**\n     * Get server port\n     *\/\n    public int getPort()\n}\n<\/textarea><\/pre><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" style=\"width:24px;height:24px\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" stroke-width=\"2\"><path class=\"with-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M4.5 12.75l6 6 9-13.5\"><\/path><path class=\"without-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M16.5 8.25V6a2.25 2.25 0 00-2.25-2.25H6A2.25 2.25 0 003.75 6v8.25A2.25 2.25 0 006 16.5h2.25m8.25-8.25H18a2.25 2.25 0 012.25 2.25V18A2.25 2.25 0 0118 20.25h-7.5A2.25 2.25 0 018.25 18v-1.5m8.25-8.25h-6a2.25 2.25 0 00-2.25 2.25v6\"><\/path><\/svg><\/span><pre class=\"shiki one-dark-pro\" style=\"background-color: #282c34\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color: #61AFEF\">public<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">class<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">ChunkedEncryptedSftpServer<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">{<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">    <\/span><span style=\"color: #61AFEF\">\/**<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">     <\/span><span style=\"color: #61AFEF\">*<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">Create<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">SFTP<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">server<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">with<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">encryption<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">     <\/span><span style=\"color: #61AFEF\">*\/<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">    <\/span><span style=\"color: #61AFEF\">public<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">ChunkedEncryptedSftpServer<\/span><span style=\"color: #ABB2BF\">(<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">        <\/span><span style=\"color: #61AFEF\">int<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">port,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">        <\/span><span style=\"color: #61AFEF\">Path<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">storageRoot,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">        <\/span><span style=\"color: #61AFEF\">Path<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">keysetPath,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">        <\/span><span style=\"color: #61AFEF\">boolean<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">useEncExtension,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">        <\/span><span style=\"color: #61AFEF\">int<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">chunkSize<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">    ) <\/span><span style=\"color: #98C379\">throws<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">Exception<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">    <\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">    <\/span><span style=\"color: #61AFEF\">\/**<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">     <\/span><span style=\"color: #61AFEF\">*<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">Start<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">the<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">SFTP<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">server<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">     <\/span><span style=\"color: #61AFEF\">*\/<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">    <\/span><span style=\"color: #61AFEF\">public<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">void<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">start<\/span><span style=\"color: #ABB2BF\">() <\/span><span style=\"color: #98C379\">throws<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">IOException<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">    <\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">    <\/span><span style=\"color: #61AFEF\">\/**<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">     <\/span><span style=\"color: #61AFEF\">*<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">Stop<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">the<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">SFTP<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">server<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">     <\/span><span style=\"color: #61AFEF\">*\/<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">    <\/span><span style=\"color: #61AFEF\">public<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">void<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">stop<\/span><span style=\"color: #ABB2BF\">() <\/span><span style=\"color: #98C379\">throws<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">IOException<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">    <\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">    <\/span><span style=\"color: #61AFEF\">\/**<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">     <\/span><span style=\"color: #61AFEF\">*<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">Check<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">if<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">server<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">is<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">running<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">     <\/span><span style=\"color: #61AFEF\">*\/<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">    <\/span><span style=\"color: #61AFEF\">public<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">boolean<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">isStarted<\/span><span style=\"color: #ABB2BF\">()<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">    <\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">    <\/span><span style=\"color: #61AFEF\">\/**<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">     <\/span><span style=\"color: #61AFEF\">*<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">Get<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">server<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">port<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">     <\/span><span style=\"color: #61AFEF\">*\/<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">    <\/span><span style=\"color: #61AFEF\">public<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">int<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">getPort<\/span><span style=\"color: #ABB2BF\">()<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">}<\/span><\/span>\n<span class=\"line\"><\/span><\/code><\/pre><\/div>\n\n\n\n<hr class=\"sera-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h2 class=\"sera-block-heading\">Appendix<\/h2>\n\n\n\n<h3 class=\"sera-block-heading\">File Format Example<\/h3>\n\n\n\n<p class=\"sera-block-paragraph\">Hex dump of encrypted file header:<\/p>\n\n\n\n<div class=\"sera-block-kevinbatdorf-code-block-pro cbp-has-line-numbers\" data-code-block-pro-font-family=\"Code-Pro-JetBrains-Mono\" style=\"font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;--cbp-line-number-color:#abb2bf;--cbp-line-number-width:calc(1 * 0.6 * .875rem);line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)\"><span role=\"button\" tabindex=\"0\" style=\"color:#abb2bf;display:none\" aria-label=\"Copy\" class=\"code-block-pro-copy-button\"><pre class=\"code-block-pro-copy-button-pre\" aria-hidden=\"true\"><textarea class=\"code-block-pro-copy-button-textarea\" tabindex=\"-1\" aria-hidden=\"true\" readonly>00000000: 43 45 4e 43 00 01 00 01  00 00 28 9a 00 00 00 00  |CENC......(.....|\n00000010: 00 00 01 a4 f3 8e 2d 1c  9a 45 b2 73 c4 91 e8 2f  |......-..E.s...\/|\n00000020: 00 00 10 50 18 a3 f1 2c  ...                      |...P...,        |\n          ^magic ^ver ^chunk    ^original_size  ^padding\n<\/textarea><\/pre><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" style=\"width:24px;height:24px\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" stroke-width=\"2\"><path class=\"with-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M4.5 12.75l6 6 9-13.5\"><\/path><path class=\"without-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M16.5 8.25V6a2.25 2.25 0 00-2.25-2.25H6A2.25 2.25 0 003.75 6v8.25A2.25 2.25 0 006 16.5h2.25m8.25-8.25H18a2.25 2.25 0 012.25 2.25V18A2.25 2.25 0 0118 20.25h-7.5A2.25 2.25 0 018.25 18v-1.5m8.25-8.25h-6a2.25 2.25 0 00-2.25 2.25v6\"><\/path><\/svg><\/span><pre class=\"shiki one-dark-pro\" style=\"background-color: #282c34\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color: #61AFEF\">00000000:<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #D19A66\">43<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #D19A66\">45<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #D19A66\">4<\/span><span style=\"color: #98C379\">e<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #D19A66\">43<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #D19A66\">00<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #D19A66\">01<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #D19A66\">00<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #D19A66\">01<\/span><span style=\"color: #ABB2BF\">  <\/span><span style=\"color: #D19A66\">00<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #D19A66\">00<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #D19A66\">28<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #D19A66\">9<\/span><span style=\"color: #98C379\">a<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #D19A66\">00<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #D19A66\">00<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #D19A66\">00<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #D19A66\">00<\/span><span style=\"color: #ABB2BF\">  |<\/span><span style=\"color: #61AFEF\">CENC......(.....<\/span><span style=\"color: #ABB2BF\">|<\/span><\/span>\n<span class=\"line\"><span style=\"color: #61AFEF\">00000010:<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #D19A66\">00<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #D19A66\">00<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #D19A66\">01<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">a4<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">f3<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #D19A66\">8<\/span><span style=\"color: #98C379\">e<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #D19A66\">2<\/span><span style=\"color: #98C379\">d<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #D19A66\">1<\/span><span style=\"color: #98C379\">c<\/span><span style=\"color: #ABB2BF\">  <\/span><span style=\"color: #D19A66\">9<\/span><span style=\"color: #98C379\">a<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #D19A66\">45<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">b2<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #D19A66\">73<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">c4<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #D19A66\">91<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">e8<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #D19A66\">2<\/span><span style=\"color: #98C379\">f<\/span><span style=\"color: #ABB2BF\">  |<\/span><span style=\"color: #56B6C2\">......<\/span><span style=\"color: #ABB2BF\">-<\/span><span style=\"color: #56B6C2\">.<\/span><span style=\"color: #ABB2BF\">.E.s.<\/span><span style=\"color: #56B6C2\">.<\/span><span style=\"color: #ABB2BF\">.\/|<\/span><\/span>\n<span class=\"line\"><span style=\"color: #61AFEF\">00000020:<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #D19A66\">00<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #D19A66\">00<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #D19A66\">10<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #D19A66\">50<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #D19A66\">18<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">a3<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">f1<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #D19A66\">2<\/span><span style=\"color: #98C379\">c<\/span><span style=\"color: #ABB2BF\">  <\/span><span style=\"color: #98C379\">...<\/span><span style=\"color: #ABB2BF\">                      |<\/span><span style=\"color: #56B6C2\">..<\/span><span style=\"color: #ABB2BF\">.P.<\/span><span style=\"color: #56B6C2\">..<\/span><span style=\"color: #ABB2BF\">,        |<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">          <\/span><span style=\"color: #61AFEF\">^magic<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">^ver<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">^chunk<\/span><span style=\"color: #ABB2BF\">    <\/span><span style=\"color: #98C379\">^original_size<\/span><span style=\"color: #ABB2BF\">  <\/span><span style=\"color: #98C379\">^padding<\/span><\/span>\n<span class=\"line\"><\/span><\/code><\/pre><\/div>\n\n\n\n<p class=\"sera-block-paragraph\">Breakdown:<\/p>\n\n\n\n<ul class=\"sera-block-list\">\n<li><code>43 45 4e 43<\/code>: &#8220;CENC&#8221; magic bytes<\/li>\n\n\n\n<li><code>00 01<\/code>: Version 1<\/li>\n\n\n\n<li><code>00 01 00 00<\/code>: Chunk size 65536 (64KB)<\/li>\n\n\n\n<li><code>00 00 00 00 00 00 01 a4<\/code>: Original size 420 bytes<\/li>\n\n\n\n<li>Remaining: Random padding<\/li>\n<\/ul>\n\n\n\n<h3 class=\"sera-block-heading\">Chunk Encryption Example<\/h3>\n\n\n\n<div class=\"sera-block-kevinbatdorf-code-block-pro cbp-has-line-numbers\" data-code-block-pro-font-family=\"Code-Pro-JetBrains-Mono\" style=\"font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;--cbp-line-number-color:#abb2bf;--cbp-line-number-width:calc(2 * 0.6 * .875rem);line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)\"><span role=\"button\" tabindex=\"0\" style=\"color:#abb2bf;display:none\" aria-label=\"Copy\" class=\"code-block-pro-copy-button\"><pre class=\"code-block-pro-copy-button-pre\" aria-hidden=\"true\"><textarea class=\"code-block-pro-copy-button-textarea\" tabindex=\"-1\" aria-hidden=\"true\" readonly>Plaintext chunk:\n  Data: \"Hello, World!\" (13 bytes)\n  Filename: \"test.txt\"\n  Chunk index: 0\n\nAssociated Data (AAD):\n  \"test.txt:chunk:0\"\n\nEncryption:\n  Algorithm: AES-256-GCM\n  Input: plaintext + AAD\n  Output: ciphertext (13 bytes) + tag (16 bytes) = 29 bytes\n\nEncrypted chunk structure:\n  &#91;00 00 00 1D&#93;  # Chunk size: 29 bytes\n  &#91;&lt;29 bytes of encrypted data including 16-byte tag>&#93;\n<\/textarea><\/pre><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" style=\"width:24px;height:24px\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" stroke-width=\"2\"><path class=\"with-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M4.5 12.75l6 6 9-13.5\"><\/path><path class=\"without-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M16.5 8.25V6a2.25 2.25 0 00-2.25-2.25H6A2.25 2.25 0 003.75 6v8.25A2.25 2.25 0 006 16.5h2.25m8.25-8.25H18a2.25 2.25 0 012.25 2.25V18A2.25 2.25 0 0118 20.25h-7.5A2.25 2.25 0 018.25 18v-1.5m8.25-8.25h-6a2.25 2.25 0 00-2.25 2.25v6\"><\/path><\/svg><\/span><pre class=\"shiki one-dark-pro\" style=\"background-color: #282c34\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color: #61AFEF\">Plaintext<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">chunk:<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">  <\/span><span style=\"color: #61AFEF\">Data:<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">&quot;Hello, World!&quot;<\/span><span style=\"color: #ABB2BF\"> (13 <\/span><span style=\"color: #98C379\">bytes<\/span><span style=\"color: #ABB2BF\">)<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">  <\/span><span style=\"color: #61AFEF\">Filename:<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">&quot;test.txt&quot;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">  <\/span><span style=\"color: #61AFEF\">Chunk<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">index:<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #D19A66\">0<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #61AFEF\">Associated<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">Data<\/span><span style=\"color: #ABB2BF\"> (AAD):<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">  <\/span><span style=\"color: #61AFEF\">&quot;test.txt:chunk:0&quot;<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #61AFEF\">Encryption:<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">  <\/span><span style=\"color: #61AFEF\">Algorithm:<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">AES-256-GCM<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">  <\/span><span style=\"color: #61AFEF\">Input:<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">plaintext<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">+<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">AAD<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">  <\/span><span style=\"color: #61AFEF\">Output:<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">ciphertext<\/span><span style=\"color: #ABB2BF\"> (13 <\/span><span style=\"color: #98C379\">bytes<\/span><span style=\"color: #ABB2BF\">) + tag (<\/span><span style=\"color: #61AFEF\">16<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">bytes<\/span><span style=\"color: #ABB2BF\">) = 29 bytes<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #61AFEF\">Encrypted<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">chunk<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">structure:<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">  &#91;<\/span><span style=\"color: #D19A66\">00<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #D19A66\">00<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #D19A66\">00<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #D19A66\">1<\/span><span style=\"color: #ABB2BF\">D&#93;  <\/span><span style=\"color: #7F848E; font-style: italic\"># Chunk size: 29 bytes<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">  &#91;<\/span><span style=\"color: #56B6C2\">&lt;<\/span><span style=\"color: #ABB2BF\">29 bytes of encrypted data including <\/span><span style=\"color: #D19A66\">16<\/span><span style=\"color: #ABB2BF\">-byte tag<\/span><span style=\"color: #56B6C2\">&gt;<\/span><span style=\"color: #ABB2BF\">&#93;<\/span><\/span>\n<span class=\"line\"><\/span><\/code><\/pre><\/div>\n\n\n\n<h3 class=\"sera-block-heading\">Performance Benchmarks<\/h3>\n\n\n\n<p class=\"sera-block-paragraph\">Performance will vary based on your specific hardware configuration:<\/p>\n\n\n\n<p class=\"sera-block-paragraph\"><strong>Key Factors<\/strong>:<\/p>\n\n\n\n<ul class=\"sera-block-list\">\n<li>CPU performance and AES-NI support<\/li>\n\n\n\n<li>RAM availability<\/li>\n\n\n\n<li>Disk I\/O (SSD vs HDD)<\/li>\n\n\n\n<li>Network bandwidth<\/li>\n<\/ul>\n\n\n\n<p class=\"sera-block-paragraph\"><strong>Expected Characteristics<\/strong>:<\/p>\n\n\n\n<ul class=\"sera-block-list\">\n<li>Network bandwidth is typically the primary bottleneck<\/li>\n\n\n\n<li>AES-256-GCM is hardware-accelerated on modern CPUs (minimal overhead)<\/li>\n\n\n\n<li>Chunk size has minimal impact on throughput for most workloads<\/li>\n\n\n\n<li>Larger chunks may slightly reduce CPU usage<\/li>\n<\/ul>\n\n\n\n<p class=\"sera-block-paragraph\"><strong>Recommendation<\/strong>: Benchmark on your specific hardware to determine optimal chunk size and configuration.<\/p>\n\n\n\n<h3 class=\"sera-block-heading\">License<\/h3>\n\n\n\n<p class=\"sera-block-paragraph\"><strong>Educational and Development Use<\/strong><\/p>\n\n\n\n<p class=\"sera-block-paragraph\">This implementation is provided for educational, development, and testing purposes. It demonstrates encryption-at-rest concepts and is not intended for production use without significant security enhancements.<\/p>\n\n\n\n<p class=\"sera-block-paragraph\"><strong>Dependencies Licenses<\/strong>:<\/p>\n\n\n\n<ul class=\"sera-block-list\">\n<li>Apache MINA SSHD: Apache License 2.0<\/li>\n\n\n\n<li>Google Tink: Apache License 2.0<\/li>\n\n\n\n<li>SLF4J: MIT License<\/li>\n\n\n\n<li>Logback: Eclipse Public License 1.0 \/ LGPL 2.1<\/li>\n<\/ul>\n\n\n\n<p class=\"sera-block-paragraph\"><strong>Disclaimer<\/strong>: This software is provided &#8220;as-is&#8221; without warranty of any kind. See repository LICENSE file for details.<\/p>\n\n\n\n<h3 class=\"sera-block-heading\">Contributing<\/h3>\n\n\n\n<p class=\"sera-block-paragraph\">Contributions welcome! Please:<\/p>\n\n\n\n<ol class=\"sera-block-list\">\n<li>Fork the repository<\/li>\n\n\n\n<li>Create feature branch<\/li>\n\n\n\n<li>Add tests for new functionality<\/li>\n\n\n\n<li>Submit pull request<\/li>\n<\/ol>\n\n\n\n<h3 class=\"sera-block-heading\">Support<\/h3>\n\n\n\n<p class=\"sera-block-paragraph\">For issues and questions:<\/p>\n\n\n\n<ul class=\"sera-block-list\">\n<li>GitHub Issues: <a href=\"https:\/\/github.com\/PortaSFTPServer\/MinaSSHDDataAtRestEncryptionSample\/issues\">https:\/\/github.com\/PortaSFTPServer\/MinaSSHDDataAtRestEncryptionSample\/issues<\/a><\/li>\n\n\n\n<li>Documentation: This README<\/li>\n\n\n\n<li>Security Issues: Report privately via GitHub Security Advisories<\/li>\n<\/ul>\n\n\n\n<h3 class=\"sera-block-heading\">Changelog<\/h3>\n\n\n\n<p class=\"sera-block-paragraph\"><strong>Version 1.0.0<\/strong> (Current)<\/p>\n\n\n\n<ul class=\"sera-block-list\">\n<li>Initial release<\/li>\n\n\n\n<li>Apache MINA SSHD 2.17.1 support<\/li>\n\n\n\n<li>Google Tink 1.20.0 integration<\/li>\n\n\n\n<li>Chunk-based AES-256-GCM encryption<\/li>\n\n\n\n<li>Streaming architecture with random access<\/li>\n\n\n\n<li>PBKDF2 user authentication<\/li>\n\n\n\n<li>Event-based logging<\/li>\n<\/ul>\n\n\n\n<p class=\"sera-block-paragraph\"><strong>Planned Features<\/strong>:<\/p>\n\n\n\n<ul class=\"sera-block-list\">\n<li>Database-backed user authentication<\/li>\n\n\n\n<li>LDAP\/Active Directory integration<\/li>\n\n\n\n<li>Multi-factor authentication (MFA)<\/li>\n\n\n\n<li>Key rotation automation<\/li>\n\n\n\n<li>Comprehensive audit logging<\/li>\n\n\n\n<li>Web-based administration panel<\/li>\n\n\n\n<li>Metrics and monitoring dashboard<\/li>\n\n\n\n<li>Public key authentication<\/li>\n\n\n\n<li>SFTP command logging<\/li>\n\n\n\n<li>File versioning support<\/li>\n<\/ul>\n\n\n\n<hr class=\"sera-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h2 class=\"sera-block-heading\">Quick Reference Card<\/h2>\n\n\n\n<h3 class=\"sera-block-heading\">Server Commands<\/h3>\n\n\n\n<div class=\"sera-block-kevinbatdorf-code-block-pro cbp-has-line-numbers\" data-code-block-pro-font-family=\"Code-Pro-JetBrains-Mono\" style=\"font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;--cbp-line-number-color:#abb2bf;--cbp-line-number-width:calc(2 * 0.6 * .875rem);line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)\"><span role=\"button\" tabindex=\"0\" style=\"color:#abb2bf;display:none\" aria-label=\"Copy\" class=\"code-block-pro-copy-button\"><pre class=\"code-block-pro-copy-button-pre\" aria-hidden=\"true\"><textarea class=\"code-block-pro-copy-button-textarea\" tabindex=\"-1\" aria-hidden=\"true\" readonly># Start server (default config)\njava -jar sftp-server.jar\n\n# Start with custom port\njava -Dsftp.port=3333 -jar sftp-server.jar\n\n# Start with custom storage\njava -Dsftp.storage=\/data\/sftp -jar sftp-server.jar\n\n# Start with larger chunks (1MB)\njava -Dsftp.chunk.size=1048576 -jar sftp-server.jar\n\n# Enable .enc extension mode\njava -Dsftp.use.enc.extension=true -jar sftp-server.jar\n<\/textarea><\/pre><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" style=\"width:24px;height:24px\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" stroke-width=\"2\"><path class=\"with-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M4.5 12.75l6 6 9-13.5\"><\/path><path class=\"without-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M16.5 8.25V6a2.25 2.25 0 00-2.25-2.25H6A2.25 2.25 0 003.75 6v8.25A2.25 2.25 0 006 16.5h2.25m8.25-8.25H18a2.25 2.25 0 012.25 2.25V18A2.25 2.25 0 0118 20.25h-7.5A2.25 2.25 0 018.25 18v-1.5m8.25-8.25h-6a2.25 2.25 0 00-2.25 2.25v6\"><\/path><\/svg><\/span><pre class=\"shiki one-dark-pro\" style=\"background-color: #282c34\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color: #7F848E; font-style: italic\"># Start server (default config)<\/span><\/span>\n<span class=\"line\"><span style=\"color: #61AFEF\">java<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #D19A66\">-jar<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">sftp-server.jar<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #7F848E; font-style: italic\"># Start with custom port<\/span><\/span>\n<span class=\"line\"><span style=\"color: #61AFEF\">java<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #D19A66\">-Dsftp.port=3333<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #D19A66\">-jar<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">sftp-server.jar<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #7F848E; font-style: italic\"># Start with custom storage<\/span><\/span>\n<span class=\"line\"><span style=\"color: #61AFEF\">java<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #D19A66\">-Dsftp.storage=\/data\/sftp<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #D19A66\">-jar<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">sftp-server.jar<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #7F848E; font-style: italic\"># Start with larger chunks (1MB)<\/span><\/span>\n<span class=\"line\"><span style=\"color: #61AFEF\">java<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #D19A66\">-Dsftp.chunk.size=1048576<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #D19A66\">-jar<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">sftp-server.jar<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #7F848E; font-style: italic\"># Enable .enc extension mode<\/span><\/span>\n<span class=\"line\"><span style=\"color: #61AFEF\">java<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #D19A66\">-Dsftp.use.enc.extension=true<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #D19A66\">-jar<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">sftp-server.jar<\/span><\/span>\n<span class=\"line\"><\/span><\/code><\/pre><\/div>\n\n\n\n<h3 class=\"sera-block-heading\">SFTP Client Commands<\/h3>\n\n\n\n<div class=\"sera-block-kevinbatdorf-code-block-pro cbp-has-line-numbers\" data-code-block-pro-font-family=\"Code-Pro-JetBrains-Mono\" style=\"font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;--cbp-line-number-color:#abb2bf;--cbp-line-number-width:calc(2 * 0.6 * .875rem);line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)\"><span role=\"button\" tabindex=\"0\" style=\"color:#abb2bf;display:none\" aria-label=\"Copy\" class=\"code-block-pro-copy-button\"><pre class=\"code-block-pro-copy-button-pre\" aria-hidden=\"true\"><textarea class=\"code-block-pro-copy-button-textarea\" tabindex=\"-1\" aria-hidden=\"true\" readonly># Connect\nsftp -P 2222 admin@localhost\n\n# Upload\nput local.txt\nmput *.pdf\n\n# Download\nget remote.txt\nmget *.pdf\n\n# Delete\nrm file.txt\n\n# Rename\/Move\nrename old.txt new.txt\n\n# List\nls\nls -la\n\n# Change directory\ncd folder\npwd\n\n# Create directory\nmkdir newfolder\n\n# Disconnect\nbye\n<\/textarea><\/pre><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" style=\"width:24px;height:24px\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" stroke-width=\"2\"><path class=\"with-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M4.5 12.75l6 6 9-13.5\"><\/path><path class=\"without-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M16.5 8.25V6a2.25 2.25 0 00-2.25-2.25H6A2.25 2.25 0 003.75 6v8.25A2.25 2.25 0 006 16.5h2.25m8.25-8.25H18a2.25 2.25 0 012.25 2.25V18A2.25 2.25 0 0118 20.25h-7.5A2.25 2.25 0 018.25 18v-1.5m8.25-8.25h-6a2.25 2.25 0 00-2.25 2.25v6\"><\/path><\/svg><\/span><pre class=\"shiki one-dark-pro\" style=\"background-color: #282c34\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color: #7F848E; font-style: italic\"># Connect<\/span><\/span>\n<span class=\"line\"><span style=\"color: #61AFEF\">sftp<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #D19A66\">-P<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #D19A66\">2222<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">admin@localhost<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #7F848E; font-style: italic\"># Upload<\/span><\/span>\n<span class=\"line\"><span style=\"color: #61AFEF\">put<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">local.txt<\/span><\/span>\n<span class=\"line\"><span style=\"color: #61AFEF\">mput<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #E5C07B\">*<\/span><span style=\"color: #98C379\">.pdf<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #7F848E; font-style: italic\"># Download<\/span><\/span>\n<span class=\"line\"><span style=\"color: #61AFEF\">get<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">remote.txt<\/span><\/span>\n<span class=\"line\"><span style=\"color: #61AFEF\">mget<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #E5C07B\">*<\/span><span style=\"color: #98C379\">.pdf<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #7F848E; font-style: italic\"># Delete<\/span><\/span>\n<span class=\"line\"><span style=\"color: #61AFEF\">rm<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">file.txt<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #7F848E; font-style: italic\"># Rename\/Move<\/span><\/span>\n<span class=\"line\"><span style=\"color: #61AFEF\">rename<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">old.txt<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">new.txt<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #7F848E; font-style: italic\"># List<\/span><\/span>\n<span class=\"line\"><span style=\"color: #61AFEF\">ls<\/span><\/span>\n<span class=\"line\"><span style=\"color: #61AFEF\">ls<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #D19A66\">-la<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #7F848E; font-style: italic\"># Change directory<\/span><\/span>\n<span class=\"line\"><span style=\"color: #56B6C2\">cd<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">folder<\/span><\/span>\n<span class=\"line\"><span style=\"color: #56B6C2\">pwd<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #7F848E; font-style: italic\"># Create directory<\/span><\/span>\n<span class=\"line\"><span style=\"color: #61AFEF\">mkdir<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">newfolder<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #7F848E; font-style: italic\"># Disconnect<\/span><\/span>\n<span class=\"line\"><span style=\"color: #61AFEF\">bye<\/span><\/span>\n<span class=\"line\"><\/span><\/code><\/pre><\/div>\n\n\n\n<h3 class=\"sera-block-heading\">Default Configuration<\/h3>\n\n\n\n<div class=\"sera-block-kevinbatdorf-code-block-pro cbp-has-line-numbers\" data-code-block-pro-font-family=\"Code-Pro-JetBrains-Mono\" style=\"font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;--cbp-line-number-color:#abb2bf;--cbp-line-number-width:calc(1 * 0.6 * .875rem);line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)\"><span role=\"button\" tabindex=\"0\" style=\"color:#abb2bf;display:none\" aria-label=\"Copy\" class=\"code-block-pro-copy-button\"><pre class=\"code-block-pro-copy-button-pre\" aria-hidden=\"true\"><textarea class=\"code-block-pro-copy-button-textarea\" tabindex=\"-1\" aria-hidden=\"true\" readonly>Port: 2222\nStorage: .\/sftp-storage\nKeyset: .\/keyset.json\nChunk Size: 64 KB\nExtension Mode: Disabled\nUsers: admin\/admin123, testuser\/password123\n<\/textarea><\/pre><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" style=\"width:24px;height:24px\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" stroke-width=\"2\"><path class=\"with-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M4.5 12.75l6 6 9-13.5\"><\/path><path class=\"without-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M16.5 8.25V6a2.25 2.25 0 00-2.25-2.25H6A2.25 2.25 0 003.75 6v8.25A2.25 2.25 0 006 16.5h2.25m8.25-8.25H18a2.25 2.25 0 012.25 2.25V18A2.25 2.25 0 0118 20.25h-7.5A2.25 2.25 0 018.25 18v-1.5m8.25-8.25h-6a2.25 2.25 0 00-2.25 2.25v6\"><\/path><\/svg><\/span><pre class=\"shiki one-dark-pro\" style=\"background-color: #282c34\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color: #61AFEF\">Port:<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #D19A66\">2222<\/span><\/span>\n<span class=\"line\"><span style=\"color: #61AFEF\">Storage:<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">.\/sftp-storage<\/span><\/span>\n<span class=\"line\"><span style=\"color: #61AFEF\">Keyset:<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">.\/keyset.json<\/span><\/span>\n<span class=\"line\"><span style=\"color: #61AFEF\">Chunk<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">Size:<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #D19A66\">64<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">KB<\/span><\/span>\n<span class=\"line\"><span style=\"color: #61AFEF\">Extension<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">Mode:<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">Disabled<\/span><\/span>\n<span class=\"line\"><span style=\"color: #61AFEF\">Users:<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">admin\/admin123,<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">testuser\/password123<\/span><\/span>\n<span class=\"line\"><\/span><\/code><\/pre><\/div>\n\n\n\n<h3 class=\"sera-block-heading\">File Locations<\/h3>\n\n\n\n<div class=\"sera-block-kevinbatdorf-code-block-pro cbp-has-line-numbers\" data-code-block-pro-font-family=\"Code-Pro-JetBrains-Mono\" style=\"font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;--cbp-line-number-color:#abb2bf;--cbp-line-number-width:calc(1 * 0.6 * .875rem);line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)\"><span role=\"button\" tabindex=\"0\" style=\"color:#abb2bf;display:none\" aria-label=\"Copy\" class=\"code-block-pro-copy-button\"><pre class=\"code-block-pro-copy-button-pre\" aria-hidden=\"true\"><textarea class=\"code-block-pro-copy-button-textarea\" tabindex=\"-1\" aria-hidden=\"true\" readonly>.\/keyset.json           # Encryption keyset (encrypted)\n.\/hostkey.ser           # SSH host key\n.\/sftp-storage\/         # Storage root\n.\/sftp-storage\/admin\/   # Admin user files\n.\/sftp-storage\/testuser\/# Test user files\n<\/textarea><\/pre><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" style=\"width:24px;height:24px\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" stroke-width=\"2\"><path class=\"with-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M4.5 12.75l6 6 9-13.5\"><\/path><path class=\"without-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M16.5 8.25V6a2.25 2.25 0 00-2.25-2.25H6A2.25 2.25 0 003.75 6v8.25A2.25 2.25 0 006 16.5h2.25m8.25-8.25H18a2.25 2.25 0 012.25 2.25V18A2.25 2.25 0 0118 20.25h-7.5A2.25 2.25 0 018.25 18v-1.5m8.25-8.25h-6a2.25 2.25 0 00-2.25 2.25v6\"><\/path><\/svg><\/span><pre class=\"shiki one-dark-pro\" style=\"background-color: #282c34\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color: #61AFEF\">.\/keyset.json<\/span><span style=\"color: #ABB2BF\">           <\/span><span style=\"color: #7F848E; font-style: italic\"># Encryption keyset (encrypted)<\/span><\/span>\n<span class=\"line\"><span style=\"color: #61AFEF\">.\/hostkey.ser<\/span><span style=\"color: #ABB2BF\">           <\/span><span style=\"color: #7F848E; font-style: italic\"># SSH host key<\/span><\/span>\n<span class=\"line\"><span style=\"color: #61AFEF\">.\/sftp-storage\/<\/span><span style=\"color: #ABB2BF\">         <\/span><span style=\"color: #7F848E; font-style: italic\"># Storage root<\/span><\/span>\n<span class=\"line\"><span style=\"color: #61AFEF\">.\/sftp-storage\/admin\/<\/span><span style=\"color: #ABB2BF\">   <\/span><span style=\"color: #7F848E; font-style: italic\"># Admin user files<\/span><\/span>\n<span class=\"line\"><span style=\"color: #61AFEF\">.\/sftp-storage\/testuser\/#<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">Test<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">user<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #98C379\">files<\/span><\/span>\n<span class=\"line\"><\/span><\/code><\/pre><\/div>\n\n\n\n<hr class=\"sera-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h2 class=\"sera-block-heading\">Conclusion<\/h2>\n\n\n\n<p class=\"sera-block-paragraph\">This Data At Rest Encryption (DARE) SFTP server implementation demonstrates how to build a secure file transfer server with transparent encryption using modern Java libraries. Key takeaways:<\/p>\n\n\n\n<ul class=\"sera-block-list\">\n<li><strong>Transparency<\/strong>: Encryption happens behind the scenes\u2014SFTP clients work normally<\/li>\n\n\n\n<li><strong>Efficiency<\/strong>: Chunk-based architecture handles large files with minimal memory<\/li>\n\n\n\n<li><strong>Security<\/strong>: Multiple layers of defense including AES-256-GCM encryption<\/li>\n\n\n\n<li><strong>Flexibility<\/strong>: Configurable chunk sizes and storage modes<\/li>\n\n\n\n<li><strong>Production-Ready Architecture<\/strong>: With proper security enhancements, suitable for real-world use<\/li>\n<\/ul>\n\n\n\n<h3 class=\"sera-block-heading\">Remember<\/h3>\n\n\n\n<p class=\"sera-block-paragraph\">This is an&nbsp;<strong>educational implementation<\/strong>. Before production use, you must address the security items outlined in this article, particularly key management, user authentication, and audit logging. The hardcoded master key and default credentials are intentionally insecure for demonstration purposes only.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>DARE w\/ Apache Mina SSHD This code demonstrates Data at Rest Encryption concepts with Apache MINA SSHD and Google Tink. Before using in production (on your own discretion): IMPORTANT NOTICE This implementation is intended for educational, development, and testing purposes only. Repository: https:\/\/github.com\/PortaSFTPServer\/MinaSSHDDataAtRestEncryptionSample Overview SFTP server with transparent Data at Rest Encryption (DARE) using Apache [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":25641,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[122,143,306,124,142,253,305,189,206,1],"tags":[],"class_list":["post-25601","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-business","category-computer-protections","category-cybersecurity-for-critical-infrastructure","category-data-information-security","category-data-science-analytics","category-emails-files-security","category-engineering","category-free-software","category-learning-educations","category-programming-software"],"_links":{"self":[{"href":"https:\/\/portasftpserver.com\/sera-json\/wp\/v2\/posts\/25601","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/portasftpserver.com\/sera-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/portasftpserver.com\/sera-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/portasftpserver.com\/sera-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/portasftpserver.com\/sera-json\/wp\/v2\/comments?post=25601"}],"version-history":[{"count":45,"href":"https:\/\/portasftpserver.com\/sera-json\/wp\/v2\/posts\/25601\/revisions"}],"predecessor-version":[{"id":25658,"href":"https:\/\/portasftpserver.com\/sera-json\/wp\/v2\/posts\/25601\/revisions\/25658"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/portasftpserver.com\/sera-json\/wp\/v2\/media\/25641"}],"wp:attachment":[{"href":"https:\/\/portasftpserver.com\/sera-json\/wp\/v2\/media?parent=25601"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/portasftpserver.com\/sera-json\/wp\/v2\/categories?post=25601"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/portasftpserver.com\/sera-json\/wp\/v2\/tags?post=25601"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}