From c4a9c5fddd38f8c932b3b82361d1b50b95c3ab81 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andreas=20Kr=C3=BChlmann?= Date: Mon, 12 Jan 2026 17:49:28 +0100 Subject: [PATCH] Document encryption key --- Makefile | 4 +++- README.md | 2 +- .../imgfloat/config/OAuthTokenCipher.java | 18 +++++++++++++++++- 3 files changed, 21 insertions(+), 3 deletions(-) diff --git a/Makefile b/Makefile index bf742ea..31c3368 100644 --- a/Makefile +++ b/Makefile @@ -7,6 +7,7 @@ IMGFLOAT_DB_PATH ?= ./imgfloat.db IMGFLOAT_GITHUB_CLIENT_OWNER ?= imgfloat IMGFLOAT_GITHUB_CLIENT_REPO ?= client IMGFLOAT_GITHUB_CLIENT_VERSION ?= 1.0.0 +IMGFLOAT_TOKEN_ENCRYPTION_KEY ?= x5A8tS8Lk4q2qY0xRkz8r9bq2bx0R4A9a0m0k5Y8mCk= IMGFLOAT_ASSETS_PATH ?= ./assets IMGFLOAT_PREVIEWS_PATH ?= ./previews IMGFLOAT_COMMIT_URL_PREFIX ?= https://github.com/imgfloat/server/commit/ @@ -21,7 +22,8 @@ RUNTIME_ENV = IMGFLOAT_ASSETS_PATH=$(IMGFLOAT_ASSETS_PATH) \ IMGFLOAT_COMMIT_URL_PREFIX=$(IMGFLOAT_COMMIT_URL_PREFIX) \ IMGFLOAT_DB_PATH=$(IMGFLOAT_DB_PATH) \ SPRING_SERVLET_MULTIPART_MAX_FILE_SIZE=$(SPRING_SERVLET_MULTIPART_MAX_FILE_SIZE) \ - SPRING_SERVLET_MULTIPART_MAX_REQUEST_SIZE=$(SPRING_SERVLET_MULTIPART_MAX_REQUEST_SIZE) + SPRING_SERVLET_MULTIPART_MAX_REQUEST_SIZE=$(SPRING_SERVLET_MULTIPART_MAX_REQUEST_SIZE) \ + IMGFLOAT_TOKEN_ENCRYPTION_KEY=$(IMGFLOAT_TOKEN_ENCRYPTION_KEY) .PHONY: build build: diff --git a/README.md b/README.md index ba9a808..c3bee19 100644 --- a/README.md +++ b/README.md @@ -17,7 +17,7 @@ Define the following required environment variables: | `IMGFLOAT_GITHUB_CLIENT_OWNER` | GitHub user or org which has the client repository | imgfloat | | `IMGFLOAT_GITHUB_CLIENT_REPO` | Client repository name | client | | `IMGFLOAT_GITHUB_CLIENT_VERSION` | Client release version used for download links | 1.2.3 | -| `IMGFLOAT_TOKEN_ENCRYPTION_KEY` | Base64-encoded 256-bit (32 byte) key used to encrypt OAuth tokens at rest (store in a secret manager or KMS) | x5A8tS8Lk4q2qY0xRkz8r9bq2bx0R4A9a0m0k5Y8mCk= | +| `IMGFLOAT_TOKEN_ENCRYPTION_KEY` | Base64/Base64URL-encoded 256-bit (32 byte) key used to encrypt OAuth tokens at rest (store in a secret manager or KMS) | x5A8tS8Lk4q2qY0xRkz8r9bq2bx0R4A9a0m0k5Y8mCk= | | `SPRING_SERVLET_MULTIPART_MAX_FILE_SIZE` | Maximum upload file size | 10MB | | `SPRING_SERVLET_MULTIPART_MAX_REQUEST_SIZE` | Maximum upload request size | 10MB | | `TWITCH_CLIENT_ID` | Oauth2 client id | i1bjnh4whieht5kzn307nvu3rn5pqi | diff --git a/src/main/java/dev/kruhlmann/imgfloat/config/OAuthTokenCipher.java b/src/main/java/dev/kruhlmann/imgfloat/config/OAuthTokenCipher.java index d12a3b9..b82d774 100644 --- a/src/main/java/dev/kruhlmann/imgfloat/config/OAuthTokenCipher.java +++ b/src/main/java/dev/kruhlmann/imgfloat/config/OAuthTokenCipher.java @@ -126,7 +126,7 @@ public class OAuthTokenCipher { } private static SecretKey decodeKey(String base64Key, String source) { - byte[] decoded = Base64.getDecoder().decode(base64Key); + byte[] decoded = decodeBase64(base64Key, source); if (decoded.length != 32) { throw new IllegalArgumentException( source + " must be a base64-encoded 256-bit (32 byte) key" @@ -134,4 +134,20 @@ public class OAuthTokenCipher { } return new SecretKeySpec(decoded, "AES"); } + + private static byte[] decodeBase64(String base64Key, String source) { + try { + return Base64.getDecoder().decode(base64Key); + } catch (IllegalArgumentException ex) { + try { + return Base64.getUrlDecoder().decode(base64Key); + } catch (IllegalArgumentException urlEx) { + ex.addSuppressed(urlEx); + throw new IllegalArgumentException( + source + " must be a base64-encoded 256-bit (32 byte) key", + ex + ); + } + } + } }