Wednesday, January 25, 2012

Encrypting Transmissions between JavaScript and PHP Part 3: Decrypting with PHP

Welcome to Part3 of Encrypting Transmissions between JavaScript and PHP.  You can see the previous parts at: Part 1 Part 2

There are just four easy steps to go through in order to decrypt the string from Part 2.
As with JavaScript, let's start off by getting the private key loaded into PHP.  Oddly enough, you can do it exactly the same way:


$key = "-----BEGIN RSA PRIVATE KEY-----
MIIEowIBAAKCAQEA3sZto3ZI4vmtMv0Vx+OaliJ/EeVnQ7R+rX8bya+zzoI/S2f7
gD+K/xNK/AD6RZ0Q1dgJ8+Nl1N+DLyDzWvLoFTNbmNJeo+j3VM5I0xXpWeETMtRG
cYysogZILprICezZM5CfC7awAh36xJD35v6mXkwWkAq2QShQDApMJyoFJI2x9DeD
oRIwgMh5pWSaNsfFRJqGaNhWHPZNILkc/PfEeI3JZEjYO7+Bpdgo7VD5jbbPv7R1
xtwko1IClhgPA3jizuQJQnaJL9G6T+MjStXG5mdfnz2oTKBOIFMzblHSlqOYDnhP
7Jbh0x0xE5dPaQQ0fsMxJqWEkDNIcfhWv8BkfQIDAQABAoIBAQCf1AcXDqcOSQlN
GqyEw7PF4Sv/f/GNbrKv8RDTq346O9IDXK/g/DXR+VqD4IOubBiHA79oPg5yIoXw
yxgteTau9zDRPKTvvhWsv28aGo9Xj5aBkjCUCNRWTmF9Jkk8bbQLPcgN1F0Et9OR
MVzaWnqsDrTlVPobVzvO15h5RLl51eOZDHZ1enrIR6gqVksloyVfoWY15Vhdx89k
jbcJ7EMvhQRLZZwIWoP1YIeP/JkREiMju8dMFGazhagZ/ejScCXy+M0LdHMe0Ow2
g5Sx9XYTxCBDj2ReONzVxiih7ZfB0QBT3+ITZIHkEbmXx93azZ98C5v5txTfxBLO
gIN0k1QBAoGBAP8t27t5qMwpEo8dZADo0NC7+qCusENMo4v2YWkyqdYTH2tLNwFK
PpbDuYuqqBClpbKKgUvQOsVaIWRM8Y58r9LiOQTHRfOmYI5W7b9uAj4t2DXP35wj
SdoSV8cBusf/bHd1w8nSAf16e2d5LmFnvIg5zmad8m5vyiWYjE64/8d9AoGBAN99
4pDXrmJ1yMNQVCeT9X2UxG56T18JnxCywE5rSJK5/uPnAGi6d20FV/JDpPe07hOv
lvJzcbYYWvPB0bVw1TkteJsVRmGWo7rwqBpNkofcBNOaEQivOYwv5Yiz97OB5URR
umYauFGI4PUrDH+jn+rlIW/TNtIpkwHqzKgzZ6EBAoGAR4bRKrGlUOTKYPc6Cs83
iOrIC7YrjhGzXg4Hq/cZh/oAOpDwsBnhhV0Da1TAmznzQiJ0r42Ei8EBzx2KMAhf
OFtU5DP/NZaTRhKzvY7WbhtnmV3VLezuTIQLuqqPcnP0MV//K1kEWcq1QIHFMGRl
gkHByx3G0JHhNbyWx5Ivj/kCgYBh5F/zFaXalsDjXDIgS9zBrwIDaiuN80brJ4C4
WKGnMzUEWlCBjvt0k1ycTyjZHzURBl5VwF9UZYKhNopGsS+UJein9T+oyzTYU0Uu
kD/YpnSuwtMnPKk2UFx37mxXAlSMAkhlJNsLS6tNeBe3aNJJLyfgNWHT2EX+Fvyh
yDJiAQKBgFnLzyAWgIECvCmBGmwAl/QK6/6w0P4CEBBt2lBTFB0dFrlkuVC2/DSY
ZLhUMtynmYZEaEreIOJqMXQfHbTUODRVrTfyKVdjvExS5SiwWENYLY/5n+lacZ/b
7iUXpuQdQPttce9IKxqo0DVg7dy7WzmFYGwCfTBTAxvaWvwFc6Pu
-----END RSA PRIVATE KEY-----";
I probably should have used a shorter key length for the demo.  Oh well.  Oh, a word on security.  Embedding your private key actually is a problem if you aren't being extra careful.  It might be wiser to read your key in from a file.  You can find documentation on how to do this in the PHP OpenSSL Documentation.

Next we utilize the PHP OpenSSL library to convert the key string into a resource.
$res=openssl_pkey_get_private($key); 
If you chose to password protect your key, the syntax would instead be:
$res=openssl_pkey_get_private($key,'password'); 
The final two steps are to Base64 decode and decrypt the encrypted text.

$text=base64_decode($_POST['encryptMe']);
openssl_private_decrypt($text,$decryptedText,$res);
That is it folks.  Your decrypted text is now in $decryptedText. Unless something went wrong.  In which case, good luck.

Encrypting Transmissions between JavaScript and PHP Part 2: Making JavaScript encrypt the right thing using the right thing

So now that we have the keys from Part 1 we can start setting up the JavaScript portion of our party.  If you have done a search for "Javascript RSA" you have probably found several different libraries that will implement it for you.  Of particular note are:
https://ziyan.info/2008/10/javascript-rsa/ and http://www-cs-students.stanford.edu/~tjw/jsbn/
The former is a modified implementation of the latter.  For the sake of this post we are going to use the former. For my own personal use I modified the code a little bit to make it more readable and so I could understand it better, but it doesn't change the way anything works so I'm not going to include it unless anyone wants it.

You will want to download the files rsa.js and jsbn.js and include them on your web page the way you normally do such things (i.e. <script language="JavaScript" type="text/javascript" src="jsbn.js"> and <script language="JavaScript" type="text/javascript" src="rsa.js">).

First and foremost we need to set things up to use the key.  How do we read that into JavaScript? Nice and simple, we cut and paste.


var pem="-----BEGIN PUBLIC KEY-----\
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA3sZto3ZI4vmtMv0Vx+Oa\
liJ/EeVnQ7R+rX8bya+zzoI/S2f7gD+K/xNK/AD6RZ0Q1dgJ8+Nl1N+DLyDzWvLo\
FTNbmNJeo+j3VM5I0xXpWeETMtRGcYysogZILprICezZM5CfC7awAh36xJD35v6m\
XkwWkAq2QShQDApMJyoFJI2x9DeDoRIwgMh5pWSaNsfFRJqGaNhWHPZNILkc/PfE\
eI3JZEjYO7+Bpdgo7VD5jbbPv7R1xtwko1IClhgPA3jizuQJQnaJL9G6T+MjStXG\
5mdfnz2oTKBOIFMzblHSlqOYDnhP7Jbh0x0xE5dPaQQ0fsMxJqWEkDNIcfhWv8Bk\
fQIDAQAB\
-----END PUBLIC KEY-----";
You will note the \ at the end of each line.  Since the key is so long you will most likely want to use a line break so you can have it on multiple lines.  I recommend not having any white space before or after the \.
Lest anyone worry about having the public key in the actual code, remember that it is the public key.  People are supposed to know it. You could theoretically have the server generate a new public key with each request and embed it in the JavaScript for you, but in my opinion there is very little reason to do so unless you are super hyper paranoid or are protecting something more exciting than a user's blog.  You can check out the PHP OpenSSL documentation if you would like to pursue something more in depth.

Next, we load the key into the library with:
var key = RSA.getPublicKey(pem);
Now things are ready to go.  The actual code to encrypt something is :
encryptedText=RSA.encrypt(stringToBeEncrypted, key);
 How you choose to go about implementing that is up to you since there are quite a few usable ways, but here is a simple example:


<SCRIPT>
function encryptData(){
element=document.getElementById('encryptMe');
element.value=RSA.encrypt(element.value, key);
}
</SCRIPT>
<FORM ACTION='decrypt.php' METHOD='POST' id='txtAuth' onsubmit='encryptData()'>";
<INPUT type='text' name='encryptMe' id='encryptMe'></INPUT>
<input name='txtSubmit' type='submit' id='txtSubmit' value='Submit'>"; </FORM>";

I hope that this will save someone some trouble! Here is Part 3!




Encrypting Transmissions between JavaScript and PHP Part 1: Creating a useful OpenSSL RSA private/public key pair

I am working on configuring my web pages to encrypt a user's password when they log in to a web page.  At the moment I do not have the luxury of using HTTPS so I am focusing on using JavaScript to encrypt just the password using a RSA public key and decrypting it on the server side in PHP using the private key.

I had a hard time finding instructions for creating OpenSSL private/public key pairs that covered everything all in one place so I figured I would document what I have learned so I don't have to search for it again in 4 years the next time I need to do it.

Assuming you already have the latest version of OpenSSL installed, run the following commands from the command line.  I am using 2048 bit keys, if you wish you may substitute a different number in the instructions below. Also, I am not encrypting the keys.  For my purposes it is pointless as the password would be stored with the key.

1.  openssl genrsa -out privateKey.pem -f4 2048

  • This creates the initial private key.  the -f4 option signifies that the public exponent should be 10001
2. openssl rsa -in privateKey.pem -out publicKey.pem -pubout

  • This derives a public key from our private key
3. openssl rsa -in privateKey.pem -out publicKey.modulus -modulus -noout

  • This derives the modulus from the private key

4. openssl req -new -x509 -key privateKey.pem -out privateKey.x509 -days 1095

  • x509 self signed certificate
5. openssl req -new -key privateKey.pem -out privateKey.csr

  • normal certificate request for if you need to get an official certificate


As a quick refresher, you use the private key for the following:

  • decrypt content encrypted with your public key
  • sign (encrypt) content to be verified with your public key
You use the public key for the following:

  • encrypt content to be decrypted by the private key
  • verify content signed by the private key
For my purposes, I will be using the public key to encrypt content sent from a user's web browser via javascript, and using the public key to decrypt it on the server side via PHP. Check out Part 2 Next!

Wednesday, January 18, 2012

window.getSelection()

This post will focus on test cases for the javascript (well, DOM) function window.getSelection().

Test case:  <DIV id="edit" contenteditable>One Two Three Four</DIV>
1.

  1.  Select "Two".  
    1. window.getSelection().anchorNode.nodeValue="One Two Three Four"
    2. window.getSelection().baseNode.nodeValue="One Two Three Four"
    3. window.getSelection().extentNode.nodeValue="One Two Three Four"
    4. window.getSelection().focusNode.nodeValue="One Two Three Four"
    5. window.getSelection().anchorOffset=4
    6. window.getSelection().baseOffset=4
    7. window.getSelection().extentOffset=7
    8. window.getSelection().focusOffset=7
  2. With "Two" Selected, run document.execCommand('bold').
    1. window.getSelection().anchorNode.nodeValue="Two"
    2. window.getSelection().baseNode.nodeValue="One "
    3. window.getSelection().extentNode.nodeValue="Two"
    4. window.getSelection().focusNode.nodeValue="Two"
    5. window.getSelection().anchorOffset=0
    6. window.getSelection().baseOffset=4
    7. window.getSelection().extentOffset=3
    8. window.getSelection().focusOffset=3
  3. Select "Three".
    1. window.getSelection().anchorNode.nodeValue=" Three Four"
    2. window.getSelection().baseNode.nodeValue=" Three Four"
    3. window.getSelection().extentNode.nodeValue=" Three Four"
    4. window.getSelection().focusNode.nodeValue=" Three Four"
    5. window.getSelection().anchorOffset=1
    6. window.getSelection().baseOffset=1
    7. window.getSelection().extentOffset=6
    8. window.getSelection().focusOffset=6
  4. Select "Four" and run document.execCommand('bold').
    1. window.getSelection().anchorNode.nodeValue="Four"
    2. window.getSelection().baseNode.nodeValue=" Three "
    3. window.getSelection().extentNode.nodeValue=" Four "
    4. window.getSelection().focusNode.nodeValue=" Four "
    5. window.getSelection().anchorOffset=0
    6. window.getSelection().baseOffset=7
    7. window.getSelection().extentOffset=4
    8. window.getSelection().focusOffset=4
  5. Position cursor immediately after "Four" and press enter. Then Select "Four"
    1. window.getSelection().anchorNode.nodeValue="Four"
    2. window.getSelection().baseNode.nodeValue=" Three "
    3. window.getSelection().extentNode.nodeValue=" Four "
    4. window.getSelection().focusNode.nodeValue=" Four "
    5. window.getSelection().anchorOffset=0
    6. window.getSelection().baseOffset=7
    7. window.getSelection().extentOffset=4
    8. window.getSelection().focusOffset=4


Javascript execCommand()

I am writing a program (don't want to say what yet) that is largely reinventing many wheels in the programming world.  I know I am making my life harder than it needs to be, but I am gaining the following:

1. I am learning way more than I would have other wise.
2. I know exactly how every part of my program works, and why it works the way it does.
3. I don't have to pay anyone for anything.
4. I avoid situations like what I encountered tonight.

One of the components of my program is a rich text editor.  I did my research, and basically gave up to download a pre-built editor.  I started in on implementing it, when I discovered the cost to use it was going to be $300ish a year.  Given the budgetary concerns listed in point 3 I went back to the idea of doing it myself.  What I discovered is that all the tutorials I could find were making things way harder than they needed to be.  I started over from scratch and very quickly made a working prototype.  Is it perfect? No.  Do I still need to work through a lot of issues I wouldn't have had to otherwise? Yes.  Would I still be sitting in a corner crying if I hadn't? Yes.

Of interesting note is the fact that one of the top results for execCommand returned a javascript reference for IE 4.

Anyway,  here is some useful reference I've compiled for execCommand() in javascript that doesn't seem to be put in one place in a simple manor anywhere else.  Hope it saves someone the hours it would have saved me.  These are all valid for Chrome 16.  Your mileage will vary with other browsers.

The phrase "current selection" can refer to any length of selection, even 0.  In other words it can also mean current cursor (caret) position.

All references below assume the use of a <DIV> tag with contenteditable set such as:
<DIV id="imeditable" contenteditable></DIV>

All references below to using the default UI need to be updated as they don't work in Chrome. Bah.

The method itself:

execCommand(String aCommandName, Boolean aShowDefaultUI, String aValueArgument)

-returns true on success, false on failure

Commands:

BackColor - Sets the background color of the current selection.

document.execCommand('BackColor', false, '#333333')

Bold - Toggles the current selection between bold and non-bold OR Toggles bold/non-bold for future typing at cursor position.  *note: depending on implementation, the former case will continue in bold for future typing if it is not toggled off, or if the cursor is placed back on a bold section or immediately adjacent.

document.execCommand('Bold')

CreateLink - Inserts a hyperlink on the current selection, or displays a dialog box enabling the user to specify a URL to insert as a hyperlink on the current selection.

document.execCommand('CreateLink', false, 'http://www.example.com')


document.execCommand('CreateLink', true)     //displays user dialog

Delete - Deletes current selection.

document.execCommand('Delete')

FontName - Sets the font family for the current selection OR future typing

document.execCommand('FontName',false,'font name')

FontSize - Sets the font size for the current selection OR future typing

document.execCommand('FontSize',false,'font size')

ForeColor - Sets the foreground (i.e. font) color of the current selection

document.execCommand('ForeColor',false,'#333333')

FormatBlock - Sets the current block format tag. Possible Values: "address", "div", "h1", "h2", "h3", "h4", "h5", "h6", "listing", "p", "pre", "xmp","li", "dt", "dd", "p"

document.execCommand('FormatBlock',false,'pre')

Indent - Increases the indent of the selected text by one indent increment

document.execCommand('Indent')

InsertHorizontalRule - Inserts a Horizontal Rule

document.execCommand('insertHorizontalRule','id for new hr')

InsertImage - Inserts an Image

document.execCommand('InsertImage',true)


document.execCommand('InsertImage',false,'path/filename/image')

InsertOrderedList - Toggles the text selection between an ordered list and a normal block

document.execCommand('InsertOrderedList',false,'id for new ol')

InsertParagraph - Inserts a paragraph break

document.execCommand('InsertParagraph',false,'id for new p')


InsertUnorderedList - Toggles the text selection between an unordered list and a normal block

document.execCommand('InsertUnorderedList',false,'id for new ul')


Italic - Toggles the current selection between italic and non-italic

document.execCommand('Italic')

JustifyCenter - Aligns the current selection to the center

document.execCommand('JustifyCenter')


JustifyFull - Aligns the current selection to be fully justified

document.execCommand('JustifyFull')

JustifyNone - Aligns the current selection to the nothing

document.execCommand('JustifyNone')

JustifyLeft - Aligns the current selection to the left

document.execCommand('JustifyLeft')

JustifyRight - Aligns the current selection to the center

document.execCommand('JustifyRight')

Outdent - Decreases the indentation of the current selection by one indentation increment (i.e. the opposite of indent)

document.execCommand('Outdent')

Print - Opens the print dialog

document.execCommand('Print', true)

Redo - Steps forward one step in the undo history

document.execCommand('Redo')

RemoveFormat - Removes the formatting tags from the current selection

document.execCommand('RemoveFormat')

SelectAll - Selects All

document.execCommand('SelectAll')

Strikethrough - Draws a line through the middle of the current selection

document.execCommand('StrikeThrough')

Subscript - Lowers the current selection to the subscript position

document.execCommand('Subscript')

Superscript - Raises the current selection to the superscript position

document.execCommand('Superscript')

Underline - Toggles the current selection between underlined and not underlined

document.execCommand('Underline')

Undo - Undo the previous action

document.execCommand('Undo')

Unlink - Removes any hyperlink from the current selection

document.execCommand('Unlink')

Unselect - Clears the current selection

document.execCommand('Unselect')



Useful Reference:
Rich-Text Editing in Mozilla
https://developer.mozilla.org/en/Rich-Text_Editing_in_Mozilla

MSDN Command Identifiers
http://msdn.microsoft.com/en-us/library/ms533049(v=vs.85).aspx

WHATWG Dev guide for execCommand
http://developers.whatwg.org/dnd.html#execCommand

HTML Editing APIs
http://dvcs.w3.org/hg/editing/raw-file/tip/editing.html


Welcome Back

I have been wanting to return to blogging for quite some time but have been putting it off as I am in the middle of writing some software that will include blogging capabilities.  However, today it occurred to me that it really is rather silly to not use this blog for at least some of my content given the level of integration with Picasa and G+ that it has.  So here I am.  Hopefully this won't be the only post on here for the next year!