1 <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
5 <script type="text/javascript"
6 src="../../../../dojo/dojo.js" djConfig="isDebug: false"></script>
7 <script type="text/javascript" src="../../../../dojox/off/offline.js"></script>
9 <style type="text/css">
41 #numRowsContainer input{
52 dojo.require("dojox.sql");
54 dojo.connect(window, "onload", function(){
55 // draw our customer table on the screen
58 // create our customer table in the database
59 dojox.sql("DROP TABLE IF EXISTS CUSTOMERS");
60 dojox.sql("CREATE TABLE CUSTOMERS ("
63 + "social_security TEXT"
68 function createTable(){
69 // get number of rows to create
70 var NUM_ROWS = document.getElementById("numRows").value;
72 alert("Please enter the number of "
73 + "customer rows the table should have");
77 var table = document.getElementById("dataTable");
79 table.parentNode.removeChild(table);
82 table = document.createElement("table");
83 table.setAttribute("id", "dataTable");
84 table.setAttribute("border", 1);
86 // if we don't use IE's craptacular proprietary table methods
87 // we get strange display glitches
88 var tr = (dojo.isIE) ? table.insertRow() : document.createElement("tr");
89 tr.className = "table-columns";
90 var th = (dojo.isIE) ? tr.insertCell() : document.createElement("th");
91 th.appendChild(document.createTextNode("Last Name"));
95 th = (dojo.isIE) ? tr.insertCell() : document.createElement("th");
96 th.appendChild(document.createTextNode("First Name"));
100 th = (dojo.isIE) ? tr.insertCell() : document.createElement("th");
101 th.appendChild(document.createTextNode("Social Security"));
105 table.appendChild(tr);
108 for(var i = 1; i <= NUM_ROWS; i++){
109 tr = (dojo.isIE) ? table.insertRow() : document.createElement("tr");
110 tr.className = "data-item";
112 var elem = (dojo.isIE) ? tr.insertCell() : document.createElement("td");
113 elem.className = "last-name";
114 var lastName = "Doe" + i;
115 elem.appendChild(document.createTextNode(lastName));
117 tr.appendChild(elem);
120 elem = (dojo.isIE) ? tr.insertCell() : document.createElement("td");
121 elem.className = "first-name";
122 var firstName = "John" + i;
123 elem.appendChild(document.createTextNode(firstName));
125 tr.appendChild(elem);
128 elem = elem = (dojo.isIE) ? tr.insertCell() : document.createElement("td");
129 elem.className = "social-security";
130 var ss = 513121500 + i;
132 ss = ss.slice(0, 3) + "-" + ss.slice(3, 5) + "-" + ss.slice(5);
133 elem.appendChild(document.createTextNode(ss));
135 tr.appendChild(elem);
137 table.appendChild(tr);
141 document.body.appendChild(table);
143 // reset button state
144 dojo.byId("encrypt").disabled = false;
145 dojo.byId("decrypt").disabled = true;
148 function readTable(){
150 var rows = dojo.query(".data-item");
151 dojo.forEach(rows, function(row){
152 var td = row.getElementsByTagName("td");
154 var lastName = td[0].childNodes[0].nodeValue;
155 var firstName = td[1].childNodes[0].nodeValue;
156 var ssNumber = td[2].childNodes[0].nodeValue;
158 data.push({lastName: lastName, firstName: firstName, ssNumber: ssNumber,
159 toString: function(){
160 return "{lastName: " + lastName
161 + ", firstName: " + firstName
162 + ", ssNumber: " + ssNumber
170 function setData(data){
171 var rows = document.getElementsByTagName("tr");
172 for(var i = 1; i < rows.length; i++){
173 var customer = data[i - 1];
174 var td = rows[i].getElementsByTagName("td");
175 td[2].childNodes[0].nodeValue = customer.social_security;
180 // disable our buttons
181 dojo.byId("encrypt").disabled = true;
182 dojo.byId("decrypt").disabled = true;
184 var data = readTable();
186 var password = document.getElementById("password").value;
188 // delete any old data
189 dojox.sql("DELETE FROM CUSTOMERS");
192 insertCustomers(data, 0, password);
195 function insertCustomers(data, i, password){
196 var nextIndex = i + 1;
198 if(i >= data.length){
199 var savedRows = dojox.sql("SELECT * FROM CUSTOMERS");
203 dojox.sql("INSERT INTO CUSTOMERS VALUES (?, ?, ENCRYPT(?))",
204 data[i].lastName, data[i].firstName,
207 function(results, error, errorMsg){
208 // enable our buttons
209 dojo.byId("encrypt").disabled = true;
210 dojo.byId("decrypt").disabled = false;
217 insertCustomers(data, nextIndex, password);
223 // disable our buttons
224 dojo.byId("encrypt").disabled = true;
225 dojo.byId("decrypt").disabled = true;
227 var password = document.getElementById("password").value;
229 dojox.sql("SELECT last_name, first_name, DECRYPT(social_security) FROM CUSTOMERS",
231 function(results, error, errorMsg){
232 // enable our buttons
233 dojo.byId("encrypt").disabled = false;
234 dojo.byId("decrypt").disabled = true;
249 <h1>Dojo SQL Cryptography</h1>
251 <h2>Instructions</h2>
253 <p>This demo shows Dojo Offline's SQL encryption technologies. In the table below, we have a
254 sample SQL table that has three columns of data: a last name, a first name, and
255 a social security number. We don't want to store the social security numbers
256 in the clear, just in case they are downloaded for offline use to a laptop and the
257 laptop is stolen.</p>
259 <p>To use this demo, enter a password and press the ENCRYPT button to see the Social Security column encrypt. Enter
260 the same password and press DECRYPT to see it decrypt. If you enter an incorrect password and
261 press DECRYPT, the Social Security column will remain encrypted and only show gibberish.</p>
263 <p>Under the covers we use 256-bit AES encryption and your password to derive the crypto key; we use
264 a facility in Google Gears to do the cryptography in such a way that the browser does not lock up
265 during processing. Dojo Offline ties this cryptography into Dojo SQL, providing convenient ENCRYPT()
266 and DECRYPT() SQL keywords you can use to easily have this functionality in your
267 own offline applications. To learn how you can use this feature
268 <a href="http://docs.google.com/View?docid=dhkhksk4_8gdp9gr#crypto" target="_blank">see here</a>.</p>
270 <div id="cryptoContainer">
271 <label for="password">
275 <input type="input" name="password" id="password" value="sample_password">
277 <button id="encrypt" onclick="window.setTimeout(encrypt, 1)">Encrypt</button>
279 <button id="decrypt" onclick="window.setTimeout(decrypt, 1)" disabled="true">Decrypt</button>
282 <div id="numRowsContainer">
283 <label for="numRows">
284 Number of Customer Rows in Table:
287 <input id="numRows" type="input" value="30">
289 <button onclick="createTable()">Update</button>