Author: Dave Smith
Viewers: 114
Last month viewers: 1
Package: Image Key Cypher
Contents
Introduction
The Code
Settings
The User Interface
How Does it Work
Download Conclusion
Introduction
Have you ever watched a spy movie where the operative goes to a profile and using the picture there, extracts a secret message? This is called steganography, concealing information inside something else.
While there are many ways to accomplish this, one of the most used is exploiting the least significant bits of an image which allows a message to be embedded without any perceptible changes visible to the human eye.
Steganography comes with its own set of limitations, for example you need a large image file and there is software available that can scan images to detect the concealment.
Instead of hiding messages inside an image, steganography, we will be using an image as the encryption key. The image itself is not changed in any way so it has no secrets to exploit and it can be much smaller, even icons can work. We will accomplish this using the Image Key Cypher package.
The Code
We will be using the following code as our user interface for both encrypting and decrypting messages. You can find a fully commented version located in the msg-crypt folder of the Image Key Cypher package, or just copy and paste this into your favorite text editor and save it in a sub folder off of where you have the package installed.
<?php
$usecurl = true;
$verify = false;
$errortext = '';
if( isset( $_REQUEST['submitted'] ) ) {
require_once( '../imagekey.class.php' );
$ikey = new imageKey();
$src = $_REQUEST['img_src'];
$msg = $_REQUEST['msg_text'];
if( empty($src) ){
$errortext .= 'You must enter a URL to the source image<br>';
}
if( empty($msg) ) {
$errortext .= 'You must enter a message<br>';
}
if( empty($errortext) ) {
$ikey->imgPath = '';
$ikey->createKey($src, '', $usecurl, $verify);
if( !empty( $ikey->errorText ) ){
$errortext .= $ikey->errorText;
}
$pattern = "/{$ikey->msgDelim}[0-9]+{$ikey->msgDelim}/";
$msgtext = ( preg_match($pattern, $msg) ) ? trim( $ikey->decryptMsg( $msg ) ) : trim( $ikey->encryptMsg( $msg ) );
if( empty($msgtext) ) {
$errortext .= 'There was a problem processing your request';
}
}
}else{
$src = '';
$msg = '';
$msgtext = '';
}
?>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Image Key Encryption</title>
</head>
<style>
.form-label, .form-submit, .msg-result, .msg-return {
margin-top: 20px;
}
input[type="text"] {
width: 600px;
}
textarea {
width: 600px;
height: 150px;
}
a {
color: blue;
text-decoration: none;
}
a:hover {
color: red;
}
.error-text {
border: thin solid red;
padding: 20px;
}
.msg-result {
border: thin solid black;
padding: 20px;
}
</style>
<body>
<?php
if( !empty($errortext) ){
?>
<div class="error-text"><?php echo $errortext; ?></div>
<?php
}
if( empty($msgtext) ) {
?>
<form method="POST">
<div class="form-label"><label for="img_src">Enter full URL to the image</label></div>
<div class="form-input"><input type="text" name="img_src" id="img_src" value="<?php echo $src;?>" autocomplete="off"></div>
<div class="form-label"><label for="msg_text">Enter message</label></div>
<div class="form-input"><textarea name="msg_text" id="msg_text"><?php echo $msg;?></textarea></div>
<div class="form-submit">
<input type="hidden" name="submitted" value="1">
<input type="submit" name="form_submit" value="Go">
</div>
</form>
<?php
} else {
?>
<div class="msg-result"><?php echo $msgtext;?></div>
<div class="msg-return"><a href="">Return</a></div>
<?php
}
?>
</body>
</html>
Settings
We have 2 settings at the top...
$usecurl is set to true so that the image is fetched remotely using the curl library. If this is set to false, the system will attempt to use file_get_contents which requires that the fopen URL wrappers are turned on in your PHP installation.
$verify is set to false which instructs curl not to verify the peer when fetching the image over ssl (URL's that start with https). If this is set to true, curl will need to be properly set up to handle security certificates and certifying authorities. Setting this up is outside the scope of this article, however making sure that curl.cainfo points to the folder on the server containing the certs in php.ini should do the trick. Not verifying leaves a small security hole where men in the middle can intercept the binary for the image. Since we are not really international spies, we don't need to worry too much about this.
The User Interface
When a browser is pointed at the file, or folder if the file is named index.php inside the folder, users will be presented with a form requesting the full URL to the image and the text for the message. This multipurpose form can be used to encrypt plain text messages or decrypt messages already encrypted.
In this scenario I have already talked to my buddy and they are aware that any encrypted message I send them will be using their small profile picture on their facebook page. Since we both secretly know which image is used, I can generate a message.
I open up my friends Facebook page and right click on the small profile picture. I select 'copy image address' from my choices. Your options may be different depending on the browser you are using, what we are after here is the full URL to the image, not the link to a page. I paste that URL into the input field on the form. I then type in the message I want to send and click 'Go' to generate the encrypted message.
If all went well, you will see the encrypted message. If something went wrong, you should see a message indicating what the problem is and your 'encrypted' message will be pretty easy to decipher. In some cases you may not get an error message, however there is an obvious problem. This happens when you provided a good URL which points to a page instead of an image.
Highlight, copy and paste the message into an e-mail to your friend. Or just pretend you did this and return to the form to decrypt the message.
Your friend, or you, just needs to paste the encrypted message into the message box, paste in the image URL from his profile pic and press 'Go' to decrypt the message. If all went well the message will now be readable.
How Does it Work
If you refer to the code section which process the user's request, the imagekey.class.php file is included and instantiated. This class has 3 methods...
The createKey method fetches the requested image and uses base 64 encoding to turn it into the encryption key. Since we are using base 64, only latin characters and numerals are encrypted, anything else will be left in its original state. This means it will not be very useful to languages which do not use a latin character set, sorry my Russian friends.
The encryptMsg method uses the encryption key to generate an encrypted message which consists of pointers to the correct character in the key. Since the key can contain many duplicates of the same character, the pointers randomly select one to use. This makes deciphering the message with normal text replacement methods extremely difficult since a character can have any number of different pointers.
The decryptMsg method reverses the encryption process by replacing the pointers with the characters that they point to in the encryption key. As long as the same image is used for the key to encrypt and decrypt, the result will be a readable message, otherwise the result will be gibberish.
Once a user submits their request, it is checked to ensure that fields where not blank. It then creates the encryption key from the requested image and depending on if the message contains plain or encrypted text it encrypts or decrypts it. Finally displaying the end result.
Download and Conclusion
One of the biggest hurdles in history with encryption is the need to deliver an encryption key. Modern techniques using private and public keys, or multiple keys have dealt well with the problem and certainly have their place in cryptography. Having a certifying authority that both parties trust is not always needed though, sometimes just having a single image of the billions to choose from will be enough.
Before I hear about it, I admit that having the recipient use their own public profile image is not the most secure approach. It certainly would be more secure if the image could not be associated with anyone. I use it in this scenario because... it is much more fun.
The Image Key Cypher package can be obtained from the download page in the ZIP format or be installed with the Composer tool from the same page.
You need to be a registered user or login to post a comment
Login Immediately with your account on:
Comments:
No comments were submitted yet.