Dynamic Watermarking of Bitmaps in Databases
Learn how to make the bitmaps in your database traceable, without changing your database or your applications.
Join the DZone community and get the full member experience.
Join For FreeSynopsis
Many databases contain bitmaps stored as blobs or files: photos, document scans, medical images, etc. When these bitmaps are retrieved by various database clients and applications, it is sometimes desirable to uniquely watermark them as they are being retrieved, so that they can be identified later. In some cases, you may even want to make this watermark invisible.
This kind of dynamic bitmap manipulation can easily be done by a programmable database proxy, without changing the persisted bitmaps.
This approach has the following benefits:
- The watermark can be customized for each retrieval and can contain information about the date, time, user identity, IP address, etc.
- The image processing is done by the proxy, which puts no extra load on the database.
- This requires no changes to the database or to the database clients.
The End Result
Given a bitmap stored in a database, such as:
a programmable database proxy can modify the bitmap on its way to the client to include a watermark containing any desired information, such as:
How This Works
The architecture is simple: instead of the normal connection between database clients and servers:
the clients connect to the proxy, and the proxy connects to the server:
The proxy can then manipulate the bitmaps as needed when they are retrieved. For instance, it can watermark only some bitmaps, or it can use different styles of watermarks, depending on the circumstances.
The bitmaps stored in the database are completely unaffected: they are modified on the fly as they are forwarded to the clients.
Advantages
- The clients and the database are blissfully unaware - this is completely transparent to them.
- Each image can be watermarked uniquely when it is retrieved (e.g., date/time, user name, IP address of client, etc.).
- No additional load is put on the database server(s).
Disadvantages
- The system is more complex with the addition of the proxy.
- There will be (typically modest) an increase in latency, depending mostly on the size of the images, but this should be compared to the alternatives.
Example
Using a proxy, we can create a simple filter to add a watermark to certain bitmaps.
If we assume that our database contains a table called images, with a column called bitmap of type blob or varbinary (depending on your database), we can create a result set filter in the proxy with the following parameter:
Query pattern: regex:select.*from.*images.*
and a bit of JavaScript code (which also uses the underlying Java engine):
// Get the value of the bitmap column as a byte stream
let stream = context.packet.getJavaStream("bitmap");
if (stream === null) {
return;
}
// The text to use as watermark
const now = new Date();
const watermark = "Retrieved by " + context.connectionContext.userName +
" on " + now.getFullYear() + "/" + (now.getMonth()+1) + "/" + now.getDate();
// Read the bitmap
const ImageIO = Java.type("javax.imageio.ImageIO");
let img = ImageIO.read(stream);
// Create the Graphics to draw the text
let g = img.createGraphics();
const Color = Java.type("java.awt.Color");
g.setColor(new Color(255, 255, 0, 150));
const Font = Java.type("java.awt.Font");
g.setFont(new Font("sans-serif", Font.BOLD, 16));
// Draw the text at the bottom of the bitmap
let textRect = textFont.getStringBounds(watermark, g.getFontRenderContext());
g.drawString(watermark, (img.getWidth() / 2) - (textRect.getWidth() / 2),
img.getHeight() - (textRect.getHeight() / 2));
// Write the bitmap to the column value
const ByteArrayOutputStream = Java.type("java.io.ByteArrayOutputStream");
let outStream = new ByteArrayOutputStream();
ImageIO.write(img, "png", outStream);
context.packet.bitmap = outStream.toByteArray();
With this filter in place, bitmaps retrieved from this table will include a watermark containing the name of the database user, and a timestamp.
The database is never affected: the bitmaps stored in the database are completely unchanged. They are modified on the fly as they are delivered to the client.
Obviously, we can watermark bitmaps selectively, we can change the text of the watermark depending on any relevant factors, and we can play with fonts, colors, positioning, transparency, etc. See this example for details.
Secret Watermarks
In some cases, it might be desirable to mark the bitmaps in a way that is not visible to the naked eye. One trivial way to do this would be to edit the image's metadata, but if we need something more subtle, we can use steganography to distribute a secret message among the bitmap in a way that makes it difficult to detect.
The example above can be modified to use the Adumbra library:
// Get the value of the bitmap column as a byte stream let inStream = context.packet.getJavaStream("bitmap"); if (inStream === null) { return; } // The hidden message const now = new Date(); const message = "Retrieved by " + context.connectionContext.userName + " on " + now.getFullYear() + "/" + (now.getMonth()+1) + "/" + now.getDate(); const messageBytes = context.utils.getUTF8BytesForString(message); const keyBytes = context.utils.getUTF8BytesForString("This is my secret key"); // Hide the message in the bitmap const Encoder = Java.type("com.galliumdata.adumbra.Encoder"); const ByteArrayOutputStream = Java.type("java.io.ByteArrayOutputStream"); let outStream = new ByteArrayOutputStream(); let encoder = new Encoder(1); encoder.encode(inStream, outStream, "png", messageBytes, keyBytes); context.packet.bitmap = outStream.toByteArray();
With this in place, the modified bitmaps served to the clients will contain a secret watermark that will be difficult to detect, and almost impossible to extract without the secret key.
What Else Can You Do With This?
This watermarking technique can also be applied to documents other than bitmaps:
- Documents such as PDF and MS Word can be given some extra metadata on the fly, or they can be given a visible or invisible watermark - see this example for PDF documents.
- All text documents can be subtly marked using techniques such as altering spacing, spelling, layout, fonts and colors, zero-width characters, etc.
- All digital documents that can sustain minor changes without losing any significant meaning, such as bitmaps, audio files, and sample sets, can be altered in a similar way.
- In fact, entire data sets can be watermarked by subtly modifying some non-critical aspects of the data, making it possible to identify these datasets later on and know exactly their origin. This is beyond the scope of this article, but there are many ways to make data traceable back to its origin.
Conclusion
When you need to have a custom watermark for every retrieval of some bitmaps or documents from a database, the technique shown here is a solid approach that avoids any additional load on the database and requires no changes to the clients or servers.
Opinions expressed by DZone contributors are their own.
Comments