Class StreamingArtifactCipher
java.lang.Object
com.kingsrook.qqq.backend.core.crypto.StreamingArtifactCipher
Streaming authenticated encryption of large artifacts (e.g., backup files),
built on Google Tink's StreamingAead (AES256_GCM_HKDF_1MB), which
authenticates every segment and detects truncation.
Each artifact gets a FRESH data key. That data key is wrapped (AES-256-GCM)
by the key-encryption key (KEK) from a QKeyProviderInterface, and the wrapped
data key, the KEK's id and its version are written in a header at the start
of the stream:
"QSC1" | UTF keyId | UTF keyVersion | int wrappedLength | wrappedDataKey | tink stream...The whole header is also bound into the stream as associated data, so any change to it makes decryption fail. Decrypting reads the key id and version from the header and asks the provider for exactly that version, so data written under an old key version stays readable after rotation. Key material is never logged and never put in an exception message.
-
Constructor Summary
Constructors -
Method Summary
Modifier and TypeMethodDescriptionnewDecryptingStream(InputStream source) Wrap an input stream of encrypted data (as written by newEncryptingStream) so that reading from it yields the plaintext.newEncryptingStream(String keyRef, OutputStream destination) Wrap an output stream so that what is written to it is encrypted (under a new data key, wrapped by the CURRENT version of keyRef) into the destination.static String[]readKeyIdAndVersion(InputStream source) Read just the key id and version named in the header of an encrypted stream (consumes the header from the stream).
-
Constructor Details
-
StreamingArtifactCipher
Constructor
-
-
Method Details
-
newEncryptingStream
Wrap an output stream so that what is written to it is encrypted (under a new data key, wrapped by the CURRENT version of keyRef) into the destination. The header is written immediately. The returned stream MUST be closed to finish the encryption (an unclosed stream is a truncated one, and will fail to decrypt); closing it also closes the destination.- Throws:
QException
-
newDecryptingStream
Wrap an input stream of encrypted data (as written by newEncryptingStream) so that reading from it yields the plaintext. Reads the header now, and gets the named key version from the provider. Throws QException if the header is malformed, the key is unavailable, or the data key cannot be unwrapped (wrong key). Reading the returned stream throws IOException if the content has been altered or truncated.- Throws:
QException
-
readKeyIdAndVersion
Read just the key id and version named in the header of an encrypted stream (consumes the header from the stream). Useful for finding which runs still need an old key version.- Throws:
QException
-