In a nutshell, my goal is to transfer encrypted string of messages between one SQL Server database to another. The databases are residing in the same server, however I have this very exact design requirement.
I use few tables in both the database to send and receive (encrypted)messages.
The strange issue i am stumbled upon is that, I am not able to decipher(Decrypt) the message back at the other database. I get a NULL while doing so. It is very strange and i don't know what is going wrong as my knowledge is limited on this topic though i managed to lead this far.
At first I was using the sql server certificate based encryption and decryption. The DBA had to create the symmetric key and certificate in the two different databases individually. It made me think this could be the cause the decryption is not successful at the other end.
But, then i wanted to try something simple so i played with using the SQL Server's passphrase functions. The result is still the same, the decryption returned NULL.
Here is the code
First, I created the functions in both the databases. Please note that the passphrase is the same.
<?php
session_start();
require_once("dbcontroller.php");
$db_handle = new DBController();
if(!empty($_GET["action"])) {
switch($_GET["action"]) {
case "add":
if(!empty($_POST["quantity"])) {
$productByCode = $db_handle->runQuery("SELECT * FROM tblproduct WHERE code='" . $_GET["code"] . "'");
$itemArray = array($productByCode[0]["code"]=>array('name'=>$productByCode[0]["name"], 'code'=>$productByCode[0]["code"], 'quantity'=>$_POST["quantity"], 'price'=>$productByCode[0]["price"]));
if(!empty($_SESSION["cart_item"])) {
if(in_array($productByCode[0]["code"],array_keys($_SESSION["cart_item"]))) {
foreach($_SESSION["cart_item"] as $k => $v) {
if($productByCode[0]["code"] == $k) {
if(empty($_SESSION["cart_item"][$k]["quantity"])) {
$_SESSION["cart_item"][$k]["quantity"] = 0;
}
$_SESSION["cart_item"][$k]["quantity"] += $_POST["quantity"];
}
}
} else {
$_SESSION["cart_item"] = array_merge($_SESSION["cart_item"],$itemArray);
}
} else {
$_SESSION["cart_item"] = $itemArray;
}
}
break;
case "remove":
if(!empty($_SESSION["cart_item"])) {
foreach($_SESSION["cart_item"] as $k => $v) {
if($_GET["code"] == $k)
unset($_SESSION["cart_item"][$k]);
if(empty($_SESSION["cart_item"]))
unset($_SESSION["cart_item"]);
}
}
break;
case "empty":
unset($_SESSION["cart_item"]);
break;
}
}
?>
<HTML>
<HEAD>
<TITLE>Simple PHP Shopping Cart</TITLE>
<link href="style.css" type="text/css" rel="stylesheet" />
</HEAD>
<BODY>
<div id="product-grid">
<div class="txt-heading">Products</div>
<?php
$product_array = $db_handle->runQuery("SELECT * FROM tblproduct ORDER BY id ASC");
if (!empty($product_array)) {
foreach($product_array as $key=>$value){
?>
<div class="product-item">
<form method="post" action="index.php?action=add&code=<?php echo $product_array[$key]["code"]; ?>">
<div class="product-image"><img src="<?php echo $product_array[$key]["image"]; ?>"></div>
<div><strong><?php echo $product_array[$key]["name"]; ?></strong></div>
<div class="product-price"><?php echo "$".$product_array[$key]["price"]; ?></div>
<div><input type="text" name="quantity" value="1" size="2" /><input type="submit" value="Add to cart" class="btnAddAction" /></div>
</form>
</div>
<?php
}
}
?>
</div>
<div id="shopping-cart">
<div class="txt-heading">Shopping Cart <a id="btnEmpty" href="index.php?action=empty">Empty Cart</a></div>
<?php
if(isset($_SESSION["cart_item"])){
$item_total = 0;
?>
<form method="post" action="process_insert.php">
<table cellpadding="10" cellspacing="1">
<tbody>
<tr>
<th style="text-align:left;"><strong>Name</strong></th>
<th style="text-align:left;"><strong>Code</strong></th>
<th style="text-align:right;"><strong>Quantity</strong></th>
<th style="text-align:right;"><strong>Price</strong></th>
<th style="text-align:center;"><strong>Action</strong></th>
</tr>
<?php
foreach ($_SESSION["cart_item"] as $item){
?>
<tr>
<td style="text-align:left;border-bottom:#F0F0F0 1px solid;" ><input type="text" name="name" value="<?php echo $item["name"]; ?>"></td>
<td style="text-align:left;border-bottom:#F0F0F0 1px solid;"><input type="text" name="code" value="<?php echo $item["code"]; ?>"></td>
<td style="text-align:right;border-bottom:#F0F0F0 1px solid;"><input type="text" name="quantity" value="<?php echo $item["quantity"]; ?>"></td>
<td style="text-align:right;border-bottom:#F0F0F0 1px solid;"><input type="text" name="price" value="<?php echo $item["price"]; ?>"></td>
<td style="text-align:center;border-bottom:#F0F0F0 1px solid;"><a href="index.php?action=remove&code=<?php echo $item["code"]; ?>" class="btnRemoveAction">Remove Item</a></td>
</tr>
<?php
$item_total += ($item["price"]*$item["quantity"]);
}
?>
<tr>
<td colspan="5" align=right><strong>Total:</strong> <?php echo "$".$item_total; ?></td>
</tr>
</tbody>
</table>
<?php
}
?>
<input type="submit" name="submit" value="submit">
</form>
</div>
</BODY>
</HTML>
Here are the tables:
<html>
<head>
<title></title>
</head>
<body>
<?php
ini_set('display_errors', 1);
error_reporting(~0);
$serverName = "localhost";
$userName = "root";
$userPassword = "";
$dbName = "blog_samples";
$conn = mysqli_connect($serverName,$userName,$userPassword,$dbName);
$sql = "INSERT INTO order_table (name, code, quantity, price)
VALUES ('".$_POST["name"]."','".$_POST["code"]."'
,'".$_POST["quantity"]."','".$_POST["price"]."')";
$query = mysqli_query($conn,$sql);
if($query) {
echo "Record add successfully";
}
mysqli_close($conn);
?>
</body>
</html>
This is the usecase:
#import "C:\\Path_To_Exe\\the.exe" rename_namespace ("exe_namespace");
this returns NULL
Note: These functions are created in both the databases Database1 and Database2
CREATE FUNCTION [dbo].[Fn_EncryptByPassphrase] (@PlaintextMessage NVARCHAR(Max))
RETURNS VARBINARY(Max)
AS
BEGIN
DECLARE @Passphrase NVARCHAR(Max) = 'testpassphrase'
,@EncryptedMessage VARBINARY(Max)
SET @EncryptedMessage = EncryptByPassphrase(@Passphrase, @PlaintextMessage)
RETURN @EncryptedMessage
END
CREATE FUNCTION [dbo].[Fn_DecryptByPassphrase] (@EncryptedMessage VARBINARY(Max))
RETURNS NVARCHAR(Max)
AS
BEGIN
DECLARE @Passphrase NVARCHAR(Max) = 'testpassphrase'
,@PlaintextMessage NVARCHAR(Max)
SET @PlaintextMessage = CONVERT(NVARCHAR(MAX), DecryptByPassphrase(@Passphrase, @EncryptedMessage))
RETURN @PlaintextMessage
END
this returns NULL either. Despite that i used the same passphrase i used for encryption. The only difference is, I used the passphrase to encrypt the message from Database1 and then I use the same passphrase to decrypt at Database2 which yields a NULL.
Database1
Create Table [dbo].[Outbound]
(Id INT,
Message NVARCHAR(Max),
EncryptedMessage VARBINARY(Max))
Database2
Create Table [dbo].[Inbound]
(Id INT,
InboundMessageId INT,
EncryptedMessage VARBINARY(Max))
This appears strange! I am not sure if this is normal behavior and if so, is there a workaround?.
Update:
Does anybody think the usecase I mentioned does not work between two databases.? because i am able to decrypt the contents if the decryption is done from within the same database. strange!!
Update 2
The DBA has got the certificate based encryption - decryption working. However, the passphrase based code mentioned in this post is still not working. Though i got one issue off my plate, I would still be looking for a solution for the passphrase based decryption.. kindly post your solution.