Home > Tips > Defeat “Print Screen” with Visual Cryptography

Defeat “Print Screen” with Visual Cryptography

August 1st, 2012

Time for some summer fun! Someone asked in the delphi win32 newsgroup how to prevent users from doing a “Print Screen”. The answer to that is that you can’t really, since screen capture can be invoked from other applications, or your app can be hosted in a Virtual Machine, accessed over RDP, or a frame can be grabbed directly from the screen cable.

However all hope is not lost! Even if you can’t defeat a “Print Screen” or screen capture, it’s possible to make such a capture useless.

Defeating any casual PrintScreen

Any worthy accomplishment requires sacrifices, and this one is no different. Assuming inducing end-user headaches or epileptic seizures is acceptable, you can defeat any single casual “Print Screen”, screen capture or frame grab with the help of visual cryptography and retinal persistence.

The trick is that a “Print Screen” will capture exactly what’s on the screen at a given time, so if you ensure that at any time, you only have random noise on the screen, then the screen capture is possible, but useless as only random noise will be captured. This is where visual cryptography comes in.

The idea is to generate two (or more) images that will individually be random noise, with no information as to the content they crypt, and when combined the information becomes visible again.

Classic Visual Cryptography

Visual cryptography does it by superposing two (or more) transparent slides (see the wikipedia article for details), and using transparency, that approach isn’t directly applicable to our “Print Screen” problem, but a variation can be devised where instead of using transparency (an “OR” operator), we’ll be using retinal persistence (an “AVERAGE” operator).

Show me the code!

To achieve that we only need to tweak slightly the Virtual Cryptography image generation, for instance the following code will take a black/white image in bmpOrig and generate two “crypted” images in bmpOne and bmpTwo:

const
   BoolToColor : array [False..True] of TColor = ( clBlack, clWhite );
...
for y := 0 to bmpOrig.Height-1 do begin
   for x := 0 to bmpOne.Width-1 do begin
      b := (Random(255) and 8) <> 0;
      bmpOne.Canvas.Pixels[x, y] := BoolToColor[b];
      if bmpOrig.Canvas.Pixels[x, y] = clWhite then
         b := not b;
      bmpTwo.Canvas.Pixels[x, y] := BoolToColor[b];
   end;
end;

Basically the first image is pure random, the second is a variation of the first with colors flipped depending on the original image. So taken in isolations, both images are effectively random, and provide zero information about the original image (assuming your Random function is not predictable enough, which isn’t the case with Delphi’s Random, but let’s ignore that).

What happens in detail is that:

  • White becomes either Black + White or White + Black
  • Black becomes either Black + Black or White + White

So White becomes perceptual Gray, and Black becomes a static White or static Black. Obviously, that’s not too pretty and will only gain you appreciation from the denizens of the MoMA, but that’s enough information for the eye to figure things out.

What does it look like?

bmpOrig

Original Image

Will thus results in the following two “crypted” images

bmpOne

bmpOne

bmpTwo

bmpTwo

Which are only what a PrintScreen could capture if you were to flip the display madly between bmpOne and bmpTwo.

The perceptual image, assuming you were to flip at a high enough frequency will be:

Perceptual image

Perceptual image, visible but never displayed

If your hardware and screen display (LCD) are fast enough, the above image is what your eyes will see. In practice, you’re more likely to have at least occasional frame skips, which will make the image flicker.

Since the technique only requires generating two images and flipping between them at high frequency, it will “work” on any platform, native apps, web apps, etc. and will defeat casual PrintScreen even when hosted in a VM or viewed over RDP.

Making it work in the real world

The key to making it work is to be able to flip fast enough between the images, preferably at each screen refresh (VSync) to minimize user discomfort. On Windows, you have access to VSync through OpenGL or DirectX, on web browsers, that’s through requestAnimationFrame.

When you don’t have access to VSync (such as in a normal VCL app), you’ll have to use a timer, but that won’t be very precise, can be subject to stroboscopic effect, so may have to aim for a lower flipping frequency than theoretically possible, which will increase discomfort.

I’ve made a small SmartMS app for your consumption’s, er… pleasure?

Consider yourself warned against epileptic seizures and headaches, then click on the link below, and hit Print Screen to your heart’s content!

VisualCryptoGraphy Demo
http://bit.ly/vcrypto

My PC and iPad don’t seem to have any trouble displaying a rather stable perceptual image. If you don’t see it working on mobile Android browsers, try touching and dragging the screen (it allows higher screen refresh rates).

As a final note, remember that this technique does not work against eye-like devices, like… cameras. It defeats PrintScreen only, and only against casual print-screeners.

As an exercise left to the astute reader, there is very simple way to decrypt with non-casual Print-screening and the help of a Paint program, but shhh! ;-)

Tips , , , ,

  1. August 1st, 2012 at 10:53 | #1

    :)

  2. JC Chu
    August 1st, 2012 at 12:48 | #2

    I guess I can take multiple screenshots…

  3. August 1st, 2012 at 14:02 | #3

    I like that post. Really interesting. I guess it’s mostly for fun. Maybe it can also be good as some captcha variant.

  4. Nelson Chu
    August 1st, 2012 at 14:04 | #4

    Reminds me of “Emerging Images” from SIGGRAPH Asia 2009: http://www.youtube.com/watch?feature=player_embedded&v=z7bbU5VOfHY

  5. August 1st, 2012 at 16:30 | #5

    People still print stuff?

  6. August 1st, 2012 at 17:18 | #6

    @QualityCoding.info
    “Print Screen” copies the screen to the clipboard, you can then paste it wherever you wish (mail, word doc, etc.)

    @Nelson Chu
    Interesting application!

    @JC Chu
    Yep, you’ve got to grab at least the two images, then combine them in a paint program.
    Another way is to capture a screen video (with FRAPS f.i.), and play it back through with de-interlacing forced one (which will perform the average). Also video compression algorithms can also result in making the hidden image visible on their own (without requiring de-interlacing).

  7. August 1st, 2012 at 20:07 | #7

    Summer fun indeed ^.^

  8. August 7th, 2012 at 01:20 | #8

    Why do this at all, though?

    Remember, folks, your software is running on other people’s property. They are the owner of the computer they’re running it on. You are not. Your software should behave itself as a guest in someone else’s home. If it barges in like it owns the place and starts trying to restrict what the computer’s owner can do, it’s no different from malware and the user has every justification to treat it as such.

  9. August 9th, 2012 at 10:34 | #9

    Mason Wheeler :
    Your software should behave itself as a guest in someone else’s home.

    Not all computer and sofwtare uses happen at home ;-)

    I’ve definetely seen that kind of functionality requested in corporate and military environments, where the user is an employee/soldier, and owns neither the machine nor the data.

    The treshold then is for the limiter to be strong enough that the user can’t casual capture sensitive data by mistake or inattention, and has to demonstrate malicious intent.

Comments are closed.