<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Brandon Sterne &#187; Security</title>
	<atom:link href="http://brandon.sternefamily.net/posts/category/security/feed/" rel="self" type="application/rss+xml" />
	<link>http://brandon.sternefamily.net/posts</link>
	<description>The Whole Brevity Thing</description>
	<lastBuildDate>Mon, 14 Mar 2011 22:52:08 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3.1</generator>
		<item>
		<title>Update to CSP Bookmarklet</title>
		<link>http://brandon.sternefamily.net/posts/2011/01/update-to-csp-bookmarklet/</link>
		<comments>http://brandon.sternefamily.net/posts/2011/01/update-to-csp-bookmarklet/#comments</comments>
		<pubDate>Thu, 20 Jan 2011 16:43:10 +0000</pubDate>
		<dc:creator>bsterne</dc:creator>
				<category><![CDATA[Mozilla]]></category>
		<category><![CDATA[Security]]></category>
		<category><![CDATA[Web Development]]></category>

		<guid isPermaLink="false">http://brandon.sternefamily.net/posts/?p=434</guid>
		<description><![CDATA[It was pointed out to me that my CSP bookmarklet was using a feature added in ECMAScript 5, Object.keys, and thus did not work in older browsers. I added a bit of code to address this: Object.keys = Object.keys &#124;&#124; function(obj) { var keys = []; for (var key in obj) { if (obj.hasOwnProperty(key)) keys.push(key); [...]]]></description>
			<content:encoded><![CDATA[<p>It was pointed out to me that my <a href="/posts/2010/10/content-security-policy-recommendation-bookmarklet/">CSP bookmarklet</a> was using a feature added in ECMAScript 5, <a href="https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Object/keys">Object.keys</a>, and thus did not work in older browsers.  I added a bit of code to address this:</p>
<pre class="brush: javascript; gutter: false">
Object.keys = Object.keys || function(obj) {
  var keys = [];
  for (var key in obj) {
    if (obj.hasOwnProperty(key))
      keys.push(key);
  }
  return keys;
}</pre>
<p>Browsers that don&#8217;t natively support <code>Object.keys</code> will now have that functionality added when the bookmarklet runs.  Go ahead, give it a try: <a href="javascript:function%20getElements%28tags%29%7Bvar%20arr%3D%5B%5D%3Btags%3Dtags.split%28%22%2C%22%29%3Bfor%28var%20i%3D0%3Bi%3Ctags.length%3Bi%2B%2B%29%7Bvar%20elems%3Ddocument.getElementsByTagName%28tags%5Bi%5D%29%3Bfor%28var%20j%3D0%3Bj%3Celems.length%3Bj%2B%2B%29arr.push%28elems%5Bj%5D%29%7D%0Areturn%20arr%3B%7D%0Afunction%20parseUri%28str%29%7Bvar%20o%3DparseUri.options%2Cm%3Do.parser%5Bo.strictMode%3F%22strict%22%3A%22loose%22%5D.exec%28str%29%2Curi%3D%7B%7D%2Ci%3D14%3Bwhile%28i--%29uri%5Bo.key%5Bi%5D%5D%3Dm%5Bi%5D%7C%7C%22%22%3Buri%5Bo.q.name%5D%3D%7B%7D%3Buri%5Bo.key%5B12%5D%5D.replace%28o.q.parser%2Cfunction%28%240%2C%241%2C%242%29%7Bif%28%241%29uri%5Bo.q.name%5D%5B%241%5D%3D%242%3B%7D%29%3Breturn%20uri%3B%7D%3BparseUri.options%3D%7BstrictMode%3Afalse%2Ckey%3A%5B%22source%22%2C%22protocol%22%2C%22authority%22%2C%22userInfo%22%2C%22user%22%2C%22password%22%2C%22host%22%2C%22port%22%2C%22relative%22%2C%22path%22%2C%22directory%22%2C%22file%22%2C%22query%22%2C%22anchor%22%5D%2Cq%3A%7Bname%3A%22queryKey%22%2Cparser%3A/%28%3F%3A%5E%7C%26%29%28%5B%5E%26%3D%5D%2A%29%3D%3F%28%5B%5E%26%5D%2A%29/g%7D%2Cparser%3A%7Bstrict%3A/%5E%28%3F%3A%28%5B%5E%3A%5C/%3F%23%5D%2B%29%3A%29%3F%28%3F%3A%5C/%5C/%28%28%3F%3A%28%28%5B%5E%3A%40%5D%2A%29%28%3F%3A%3A%28%5B%5E%3A%40%5D%2A%29%29%3F%29%3F%40%29%3F%28%5B%5E%3A%5C/%3F%23%5D%2A%29%28%3F%3A%3A%28%5Cd%2A%29%29%3F%29%29%3F%28%28%28%28%3F%3A%5B%5E%3F%23%5C/%5D%2A%5C/%29%2A%29%28%5B%5E%3F%23%5D%2A%29%29%28%3F%3A%5C%3F%28%5B%5E%23%5D%2A%29%29%3F%28%3F%3A%23%28.%2A%29%29%3F%29/%2Cloose%3A/%5E%28%3F%3A%28%3F%21%5B%5E%3A%40%5D%2B%3A%5B%5E%3A%40%5C/%5D%2A%40%29%28%5B%5E%3A%5C/%3F%23.%5D%2B%29%3A%29%3F%28%3F%3A%5C/%5C/%29%3F%28%28%3F%3A%28%28%5B%5E%3A%40%5D%2A%29%28%3F%3A%3A%28%5B%5E%3A%40%5D%2A%29%29%3F%29%3F%40%29%3F%28%5B%5E%3A%5C/%3F%23%5D%2A%29%28%3F%3A%3A%28%5Cd%2A%29%29%3F%29%28%28%28%5C/%28%3F%3A%5B%5E%3F%23%5D%28%3F%21%5B%5E%3F%23%5C/%5D%2A%5C.%5B%5E%3F%23%5C/.%5D%2B%28%3F%3A%5B%3F%23%5D%7C%24%29%29%29%2A%5C/%3F%29%3F%28%5B%5E%3F%23%5C/%5D%2A%29%29%28%3F%3A%5C%3F%28%5B%5E%23%5D%2A%29%29%3F%28%3F%3A%23%28.%2A%29%29%3F%29/%7D%7D%3Bvar%20sources%3D%7B%27images%27%3A%7B%7D%2C%27media%27%3A%7B%7D%2C%27script%27%3A%7B%7D%2C%27object%27%3A%7B%7D%2C%27frame%27%3A%7B%7D%2C%27font%27%3A%7B%7D%2C%27style%27%3A%7B%7D%7D%3Bvar%20directives%3D%7B%27images%27%3A%27img-src%27%2C%27media%27%3A%27media-src%27%2C%27script%27%3A%27script-src%27%2C%27object%27%3A%27object-src%27%2C%27frame%27%3A%27frame-src%27%2C%27font%27%3A%27font-src%27%2C%27style%27%3A%27style-src%27%7D%3Bvar%20violations%3D%5B%5D%3Bfunction%20capWord%28w%29%7Breturn%20w.charAt%280%29.toUpperCase%28%29%2Bw.slice%281%29%3B%7D%0Afunction%20objIsEmpty%28obj%29%7Bfor%28var%20prop%20in%20obj%29%7Bif%28obj.hasOwnProperty%28prop%29%29%0Areturn%20false%3B%7D%0Areturn%20true%3B%7D%0Afunction%20generatePolicyFromSources%28sourceList%2Cviolations%29%7Bvar%20policy%3D%22Recommended%20Policy%3A%5Cn%22%3Bpolicy%2B%3D%22allow%20%27self%27%3B%22%3Bfor%28type%20in%20sourceList%29%7Bif%28objIsEmpty%28sourceList%5Btype%5D%29%29%0Acontinue%3Bpolicy%2B%3D%22%20%22%2Bdirectives%5Btype%5D%2B%22%20%22%2B%0AObject.keys%28sourceList%5Btype%5D%29.join%28%22%20%22%29%2B%22%3B%22%3B%7D%0Aif%28violations.length%29%7Bpolicy%2B%3D%22%5Cn%5Cn%22%3Bpolicy%2B%3D%28violations.length%3D%3D1%29%3F%22Inline%20Script%20Violation%3A%22%3A%22Inline%20Script%20Violations%3A%22%3Bfor%28var%20v%3D0%3Bv%3Cviolations.length%3Bv%2B%2B%29%0Apolicy%2B%3D%22%5Cn%22%2B%28v%2B1%29%2B%22%3A%20%22%2Bviolations%5Bv%5D%3B%7D%0Areturn%20policy%3B%7D%0AObject.keys%3DObject.keys%7C%7Cfunction%28obj%29%7Bvar%20keys%3D%5B%5D%3Bfor%28var%20key%20in%20obj%29%7Bif%28obj.hasOwnProperty%28key%29%29%0Akeys.push%28key%29%3B%7D%0Areturn%20keys%3B%7D%0Afunction%20analyzeContent%28%29%7Bvar%20myHost%3DparseUri%28window.location.href%29.host%3Bvar%20images%3DgetElements%28%22img%22%29%3Bfor%28var%20i%3D0%3Bi%3Cimages.length%3Bi%2B%2B%29%7Bvar%20uriParts%3DparseUri%28images%5Bi%5D.src%29%3Bvar%20host%3D%28uriParts%5B%22protocol%22%5D%3D%3D%22data%22%29%3F%22data%3A%22%3AuriParts%5B%22host%22%5D%3Bif%28host%3D%3Dnull%29%7Bif%28%21%28host%20in%20sources.images%29%29%0Asources.images%5B%22%27self%27%22%5D%3Dnull%3B%7D%0Aelse%7Bif%28host%3D%3DmyHost%29%0Ahost%3D%22%27self%27%22%3Bif%28%21%28host%20in%20sources.images%29%29%0Asources.images%5Bhost%5D%3Dnull%3B%7D%7D%0Avar%20linkElems%3DgetElements%28%22link%22%29%3Bfor%28var%20i%3D0%3Bi%3ClinkElems.length%3Bi%2B%2B%29%7Bif%28linkElems%5Bi%5D.getAttribute%28%22rel%22%29%3D%3D%22shortcut%20icon%22%29%7Bvar%20uriParts%3DparseUri%28linkElems%5Bi%5D.href%29%3Bvar%20host%3D%28uriParts%5B%22protocol%22%5D%3D%3D%22data%22%29%3F%22data%3A%22%3AuriParts%5B%22host%22%5D%3Bif%28host%3D%3Dnull%29%7Bif%28%21%28host%20in%20sources.images%29%29%0Asources.images%5B%22%27self%27%22%5D%3Dnull%3B%7D%0Aelse%7Bif%28host%3D%3DmyHost%29%0Ahost%3D%22%27self%27%22%3Bif%28%21%28host%20in%20sources.images%29%29%0Asources.images%5Bhost%5D%3Dnull%3B%7D%7D%7D%0Avar%20media%3DgetElements%28%22video%2Caudio%22%29%3Bfor%28var%20i%3D0%3Bi%3Cmedia.length%3Bi%2B%2B%29%7Bvar%20uriParts%3DparseUri%28media%5Bi%5D.src%29%3Bvar%20host%3D%28uriParts%5B%22protocol%22%5D%3D%3D%22data%22%29%3F%22data%3A%22%3AuriParts%5B%22host%22%5D%3Bif%28host%3D%3Dnull%29%7Bif%28%21%28host%20in%20sources.media%29%29%0Asources.media%5B%22%27self%27%22%5D%3Dnull%3B%7D%0Aelse%7Bif%28host%3D%3DmyHost%29%0Ahost%3D%22%27self%27%22%3Bif%28%21%28host%20in%20sources.media%29%29%0Asources.media%5Bhost%5D%3Dnull%3B%7D%7D%0Avar%20scripts%3DgetElements%28%22script%22%29%3Bfor%28var%20i%3D0%3Bi%3Cscripts.length%3Bi%2B%2B%29%7Bvar%20uriParts%3DparseUri%28scripts%5Bi%5D.src%29%3Bvar%20host%3D%28uriParts%5B%22protocol%22%5D%3D%3D%22data%22%29%3F%22data%3A%22%3AuriParts%5B%22host%22%5D%3Bif%28host%3D%3Dnull%29%7Bif%28%21%28host%20in%20sources.script%29%29%0Asources.script%5B%22%27self%27%22%5D%3Dnull%3B%7D%0Aelse%7Bif%28host%3D%3DmyHost%29%0Ahost%3D%22%27self%27%22%3Bif%28%21%28host%20in%20sources.script%29%29%0Asources.script%5Bhost%5D%3Dnull%3B%7D%7D%0Avar%20objAppl%3DgetElements%28%22object%2Capplet%22%29%3Bfor%28var%20i%3D0%3Bi%3CobjAppl.length%3Bi%2B%2B%29%7Bif%28objAppl%5Bi%5D.hasAttribute%28%22codebase%22%29%29%7Bvar%20uriParts%3DparseUri%28objAppl%5Bi%5D.getAttribute%28%22codebase%22%29%29%3Bvar%20host%3D%28uriParts%5B%22protocol%22%5D%3D%3D%22data%22%29%3F%22data%3A%22%3AuriParts%5B%22host%22%5D%3Bif%28host%3D%3Dnull%29%7Bif%28%21%28host%20in%20sources.object%29%29%0Asources.object%5B%22%27self%27%22%5D%3Dnull%3B%7D%0Aelse%7Bif%28host%3D%3DmyHost%29%0Ahost%3D%22%27self%27%22%3Bif%28%21%28host%20in%20sources.object%29%29%0Asources.object%5Bhost%5D%3Dnull%3B%7D%7D%0Aif%28objAppl%5Bi%5D.hasAttribute%28%22classid%22%29%29%7Bvar%20uriParts%3DparseUri%28objAppl%5Bi%5D.getAttribute%28%22classid%22%29%29%3Bif%28%5B%22http%22%2C%22https%22%2C%22ftp%22%2Cnull%5D.indexOf%28uriParts%5B%22protocol%22%5D%29%21%3D-1%29%7Bvar%20host%3DuriParts%5B%22host%22%5D%3Bif%28host%3D%3Dnull%29%7Bif%28%21%28host%20in%20sources.object%29%29%0Asources.object%5B%22%27self%27%22%5D%3Dnull%3B%7D%0Aelse%7Bif%28host%3D%3DmyHost%29%0Ahost%3D%22%27self%27%22%3Bif%28%21%28host%20in%20sources.object%29%29%0Asources.object%5Bhost%5D%3Dnull%3B%7D%7D%7D%0Aif%28objAppl%5Bi%5D.hasAttribute%28%22data%22%29%29%7Bvar%20uriParts%3DparseUri%28objAppl%5Bi%5D.getAttribute%28%22data%22%29%29%3Bvar%20host%3D%28uriParts%5B%22protocol%22%5D%3D%3D%22data%22%29%3F%22data%3A%22%3AuriParts%5B%22host%22%5D%3Bif%28host%3D%3Dnull%29%7Bif%28%21%28host%20in%20sources.object%29%29%0Asources.object%5B%22%27self%27%22%5D%3Dnull%3B%7D%0Aelse%7Bif%28host%3D%3DmyHost%29%0Ahost%3D%22%27self%27%22%3Bif%28%21%28host%20in%20sources.object%29%29%0Asources.object%5Bhost%5D%3Dnull%3B%7D%7D%0Aif%28objAppl%5Bi%5D.hasAttribute%28%22archive%22%29%29%7Bvar%20uriParts%3DparseUri%28objAppl%5Bi%5D.getAttribute%28%22archive%22%29%29%3Bvar%20host%3D%28uriParts%5B%22protocol%22%5D%3D%3D%22data%22%29%3F%22data%3A%22%3AuriParts%5B%22host%22%5D%3Bif%28host%3D%3Dnull%29%7Bif%28%21%28host%20in%20sources.object%29%29%0Asources.object%5B%22%27self%27%22%5D%3Dnull%3B%7D%0Aelse%7Bif%28host%3D%3DmyHost%29%0Ahost%3D%22%27self%27%22%3Bif%28%21%28host%20in%20sources.object%29%29%0Asources.object%5Bhost%5D%3Dnull%3B%7D%7D%7D%0Avar%20embeds%3DgetElements%28%22embed%22%29%3Bfor%28var%20i%3D0%3Bi%3Cembeds.length%3Bi%2B%2B%29%7Bvar%20uriParts%3DparseUri%28embeds%5Bi%5D.src%29%3Bvar%20host%3D%28uriParts%5B%22protocol%22%5D%3D%3D%22data%22%29%3F%22data%3A%22%3AuriParts%5B%22host%22%5D%3Bif%28host%3D%3Dnull%29%7Bif%28%21%28host%20in%20sources.object%29%29%0Asources.object%5B%22%27self%27%22%5D%3Dnull%3B%7D%0Aelse%7Bif%28host%3D%3DmyHost%29%0Ahost%3D%22%27self%27%22%3Bif%28%21%28host%20in%20sources.object%29%29%0Asources.object%5Bhost%5D%3Dnull%3B%7D%7D%0Avar%20frameElems%3DgetElements%28%22frame%2Ciframe%22%29%3Bfor%28var%20i%3D0%3Bi%3CframeElems.length%3Bi%2B%2B%29%7Bvar%20uriParts%3DparseUri%28frameElems%5Bi%5D.src%29%3Bvar%20host%3D%28uriParts%5B%22protocol%22%5D%3D%3D%22data%22%29%3F%22data%3A%22%3AuriParts%5B%22host%22%5D%3Bif%28host%3D%3Dnull%29%7Bif%28%21%28host%20in%20sources.frame%29%29%0Asources.frame%5B%22%27self%27%22%5D%3Dnull%3B%7D%0Aelse%7Bif%28host%3D%3DmyHost%29%0Ahost%3D%22%27self%27%22%3Bif%28%21%28host%20in%20sources.frame%29%29%0Asources.frame%5Bhost%5D%3Dnull%3B%7D%7D%0Avar%20stylesheets%3D%7B%7D%3Btry%7Bvar%20stylesheets%3Ddocument.styleSheets%3B%7D%0Acatch%28e%29%7B%7D%0Afor%28var%20i%3D0%3Bi%3Cstylesheets.length%3Bi%2B%2B%29%7Bvar%20rules%3D%7B%7D%3Btry%7Brules%3Dstylesheets%5Bi%5D.cssRules%3B%7D%0Acatch%28e%29%7Bcontinue%3B%7D%0Aif%28%21rules%29%7Bcontinue%3B%7D%0Afor%28var%20j%3D0%3Bj%3Crules.length%3Bj%2B%2B%29%7Bif%28rules%5Bj%5D.type%3D%3Drules%5Bj%5D.FONT_FACE_RULE%29%7Bvar%20src%3Drules%5Bj%5D.style.getPropertyValue%28%22src%22%29%3Bif%28src%29%7Bvar%20url%3Dsrc.replace%28/%5Eurl%5B%27%22%5D%2A/%2C%22%22%29.replace%28/%5B%27%22%5D%2A%5C%29%24/%2C%22%22%29%3Bvar%20uriParts%3DparseUri%28url%29%3Bvar%20host%3D%28uriParts%5B%22protocol%22%5D%3D%3D%22data%22%29%3F%22data%3A%22%3AuriParts%5B%22host%22%5D%3Bif%28host%3D%3Dnull%29%7Bif%28%21%28host%20in%20sources.font%29%29%0Asources.font%5B%22%27self%27%22%5D%3Dnull%3B%7D%0Aelse%7Bif%28host%3D%3DmyHost%29%0Ahost%3D%22%27self%27%22%3Bif%28%21%28host%20in%20sources.font%29%29%0Asources.font%5Bhost%5D%3Dnull%3B%7D%7D%7D%7D%7D%0Avar%20linkElems%3DgetElements%28%22link%22%29%3Bfor%28var%20i%3D0%3Bi%3ClinkElems.length%3Bi%2B%2B%29%7Bif%28linkElems%5Bi%5D.getAttribute%28%22rel%22%29%3D%3D%22stylesheet%22%29%7Bvar%20uriParts%3DparseUri%28linkElems%5Bi%5D.href%29%3Bvar%20host%3D%28uriParts%5B%22protocol%22%5D%3D%3D%22data%22%29%3F%22data%3A%22%3AuriParts%5B%22host%22%5D%3Bif%28host%3D%3Dnull%29%7Bif%28%21%28host%20in%20sources.style%29%29%0Asources.style%5B%22%27self%27%22%5D%3Dnull%3B%7D%0Aelse%7Bif%28host%3D%3DmyHost%29%0Ahost%3D%22%27self%27%22%3Bif%28%21%28host%20in%20sources.style%29%29%0Asources.style%5Bhost%5D%3Dnull%3B%7D%7D%7D%0Avar%20allElems%3DgetElements%28%22%2A%22%29%3Bfor%28var%20e%3D0%3Be%3CallElems.length%3Be%2B%2B%29%7Bvar%20elem%3DallElems%5Be%5D%3Bvar%20attrs%3D%5B%5D%3Bfor%28var%20key%20in%20elem.attributes%29%7Bif%28%21isNaN%28key%29%29%7Battrs.push%28elem.attributes%5Bkey%5D.name%29%3B%7D%7D%0Afor%28var%20i%3D0%3Bi%3Cattrs.length%3Bi%2B%2B%29%7Bif%28attrs%5Bi%5D.match%28/%5Eon/%29%29%7Bvar%20attr_pairs%3D%5B%5D%0Afor%28var%20j%3D0%3Bj%3Cattrs.length%3Bj%2B%2B%29%7Bvar%20attr_val%3Delem.attributes%5Battrs%5Bj%5D%5D.nodeValue.replace%28/%5Cs%2B/g%2C%22%20%22%29%3Battr_pairs.push%28attrs%5Bj%5D%2B%27%3D%22%27%2Battr_val%2B%27%22%27%29%3B%7D%0Avar%20error%3Dattrs%5Bi%5D%2B%22%20on%20element%20%3C%22%2Belem.nodeName%2B%22%20%22%2B%0Aattr_pairs.join%28%22%20%22%29%2B%22%3E%22%3Bviolations.push%28%22event%20handling%20attribute%3A%20%22%2Berror%29%3B%7D%7D%0Aif%28elem.nodeName%3D%3D%3D%22SCRIPT%22%26%26elem.text.length%29%7Bvar%20script%3D%28elem.text.length%3E100%29%3Felem.text.substr%280%2C100%29%2B%22%20...%20%22%3Aelem.text%3Bviolations.push%28%22internal%20script%20node%3A%20%22%2Bscript%29%3B%7D%7D%0Aalert%28generatePolicyFromSources%28sources%2Cviolations%29%29%3B%7D%0AanalyzeContent%28%29%3B" class="bookmarklet">Recommend CSP</a></p>
<p>As before, the <a href="https://github.com/bsterne/bsterne-tools/blob/master/csp-bookmarklet/csp-bookmarklet.js">full source</a> is posted for you to browse as well.</p>
<p><script type="text/javascript" src="/posts/syntax/src/shCore.js"></script><br />
<script type="text/javascript" src="/posts/syntax/scripts/shBrushJScript.js"></script></p>
<link rel="stylesheet" type="text/css" href="/posts/syntax/styles/shCore.css" />
<link type="text/css" rel="Stylesheet" href="/posts/syntax/styles/shThemeDefault.css"/>
<script type="text/javascript">SyntaxHighlighter.all()</script></p>
<style type="text/css">
a.bookmarklet {
  text-decoration: none;
  display: inline-block;
  border: 1px solid #bbb;
  padding: .25em .5em;
  margin: .5em;
  -moz-border-radius: .5em;
  -webkit-border-radius: .5em;
}
</style>
]]></content:encoded>
			<wfw:commentRss>http://brandon.sternefamily.net/posts/2011/01/update-to-csp-bookmarklet/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Content Security Policy Recommendation Bookmarklet</title>
		<link>http://brandon.sternefamily.net/posts/2010/10/content-security-policy-recommendation-bookmarklet/</link>
		<comments>http://brandon.sternefamily.net/posts/2010/10/content-security-policy-recommendation-bookmarklet/#comments</comments>
		<pubDate>Thu, 14 Oct 2010 23:02:51 +0000</pubDate>
		<dc:creator>bsterne</dc:creator>
				<category><![CDATA[Mozilla]]></category>
		<category><![CDATA[Security]]></category>
		<category><![CDATA[Web Development]]></category>

		<guid isPermaLink="false">http://brandon.sternefamily.net/posts/?p=414</guid>
		<description><![CDATA[I wrote a bookmarklet that analyzes the content on the current page and recommends a Content Security Policy based on the types of content it finds on the page and the sources of that content. The implementation also takes into account resources that are dynamically added to the page by JavaScript. For instance, today I [...]]]></description>
			<content:encoded><![CDATA[<p>I wrote a bookmarklet that analyzes the content on the current page and recommends a Content Security Policy based on the types of content it finds on the page and the sources of that content.  The implementation also takes into account resources that are dynamically added to the page by JavaScript.</p>
<p style="margin:1em">For instance, today I learned that ReCAPTCHA loads script both from api.recaptcha.net, but also from www.google.com.  <em>Note to self: figure out why Google needs to know about every ReCAPTCHA load.</em></p>
<p>You can test it out by clicking the following bookmarklet: <a href="javascript:function%20getElements%28tags%29%7Bvar%20arr%3D%5B%5D%3Btags%3Dtags.split%28%22%2C%22%29%3Bfor%28var%20i%3D0%3Bi%3Ctags.length%3Bi%2B%2B%29%7Bvar%20elems%3Ddocument.getElementsByTagName%28tags%5Bi%5D%29%3Bfor%28var%20j%3D0%3Bj%3Celems.length%3Bj%2B%2B%29arr.push%28elems%5Bj%5D%29%7D%0Areturn%20arr%3B%7D%0Afunction%20parseUri%28str%29%7Bvar%20o%3DparseUri.options%2Cm%3Do.parser%5Bo.strictMode%3F%22strict%22%3A%22loose%22%5D.exec%28str%29%2Curi%3D%7B%7D%2Ci%3D14%3Bwhile%28i--%29uri%5Bo.key%5Bi%5D%5D%3Dm%5Bi%5D%7C%7C%22%22%3Buri%5Bo.q.name%5D%3D%7B%7D%3Buri%5Bo.key%5B12%5D%5D.replace%28o.q.parser%2Cfunction%28%240%2C%241%2C%242%29%7Bif%28%241%29uri%5Bo.q.name%5D%5B%241%5D%3D%242%3B%7D%29%3Breturn%20uri%3B%7D%3BparseUri.options%3D%7BstrictMode%3Afalse%2Ckey%3A%5B%22source%22%2C%22protocol%22%2C%22authority%22%2C%22userInfo%22%2C%22user%22%2C%22password%22%2C%22host%22%2C%22port%22%2C%22relative%22%2C%22path%22%2C%22directory%22%2C%22file%22%2C%22query%22%2C%22anchor%22%5D%2Cq%3A%7Bname%3A%22queryKey%22%2Cparser%3A/%28%3F%3A%5E%7C%26%29%28%5B%5E%26%3D%5D%2A%29%3D%3F%28%5B%5E%26%5D%2A%29/g%7D%2Cparser%3A%7Bstrict%3A/%5E%28%3F%3A%28%5B%5E%3A%5C/%3F%23%5D%2B%29%3A%29%3F%28%3F%3A%5C/%5C/%28%28%3F%3A%28%28%5B%5E%3A%40%5D%2A%29%28%3F%3A%3A%28%5B%5E%3A%40%5D%2A%29%29%3F%29%3F%40%29%3F%28%5B%5E%3A%5C/%3F%23%5D%2A%29%28%3F%3A%3A%28%5Cd%2A%29%29%3F%29%29%3F%28%28%28%28%3F%3A%5B%5E%3F%23%5C/%5D%2A%5C/%29%2A%29%28%5B%5E%3F%23%5D%2A%29%29%28%3F%3A%5C%3F%28%5B%5E%23%5D%2A%29%29%3F%28%3F%3A%23%28.%2A%29%29%3F%29/%2Cloose%3A/%5E%28%3F%3A%28%3F%21%5B%5E%3A%40%5D%2B%3A%5B%5E%3A%40%5C/%5D%2A%40%29%28%5B%5E%3A%5C/%3F%23.%5D%2B%29%3A%29%3F%28%3F%3A%5C/%5C/%29%3F%28%28%3F%3A%28%28%5B%5E%3A%40%5D%2A%29%28%3F%3A%3A%28%5B%5E%3A%40%5D%2A%29%29%3F%29%3F%40%29%3F%28%5B%5E%3A%5C/%3F%23%5D%2A%29%28%3F%3A%3A%28%5Cd%2A%29%29%3F%29%28%28%28%5C/%28%3F%3A%5B%5E%3F%23%5D%28%3F%21%5B%5E%3F%23%5C/%5D%2A%5C.%5B%5E%3F%23%5C/.%5D%2B%28%3F%3A%5B%3F%23%5D%7C%24%29%29%29%2A%5C/%3F%29%3F%28%5B%5E%3F%23%5C/%5D%2A%29%29%28%3F%3A%5C%3F%28%5B%5E%23%5D%2A%29%29%3F%28%3F%3A%23%28.%2A%29%29%3F%29/%7D%7D%3Bvar%20sources%3D%7B%27images%27%3A%7B%7D%2C%27media%27%3A%7B%7D%2C%27script%27%3A%7B%7D%2C%27object%27%3A%7B%7D%2C%27frame%27%3A%7B%7D%2C%27font%27%3A%7B%7D%2C%27style%27%3A%7B%7D%7D%3Bvar%20directives%3D%7B%27images%27%3A%27img-src%27%2C%27media%27%3A%27media-src%27%2C%27script%27%3A%27script-src%27%2C%27object%27%3A%27object-src%27%2C%27frame%27%3A%27frame-src%27%2C%27font%27%3A%27font-src%27%2C%27style%27%3A%27style-src%27%7D%3Bfunction%20capWord%28w%29%7Breturn%20w.charAt%280%29.toUpperCase%28%29%2Bw.slice%281%29%3B%7D%0Afunction%20objIsEmpty%28obj%29%7Bfor%28var%20prop%20in%20obj%29%7Bif%28obj.hasOwnProperty%28prop%29%29%0Areturn%20false%3B%7D%0Areturn%20true%3B%7D%0Afunction%20generatePolicyFromSources%28sourceList%29%7Bvar%20policy%3D%22allow%20%27self%27%3B%22%3Bfor%28type%20in%20sourceList%29%7Bif%28objIsEmpty%28sourceList%5Btype%5D%29%29%0Acontinue%3Bpolicy%2B%3D%22%20%22%2Bdirectives%5Btype%5D%2B%22%20%22%2B%0AObject.keys%28sourceList%5Btype%5D%29.join%28%22%20%22%29%2B%22%3B%22%3B%7D%0Areturn%20policy%3B%7D%0AObject.keys%3DObject.keys%7C%7Cfunction%28obj%29%7Bvar%20keys%3D%5B%5D%3Bfor%28var%20key%20in%20obj%29%7Bif%28obj.hasOwnProperty%28key%29%29%0Akeys.push%28key%29%3B%7D%0Areturn%20keys%3B%7D%0Afunction%20analyzeContent%28%29%7Bvar%20myHost%3DparseUri%28location.href%29.host%3Bvar%20images%3DgetElements%28%22img%22%29%3Bfor%28var%20i%3D0%3Bi%3Cimages.length%3Bi%2B%2B%29%7Bvar%20uriParts%3DparseUri%28images%5Bi%5D.src%29%3Bvar%20host%3D%28uriParts%5B%22protocol%22%5D%3D%3D%22data%22%29%3F%22data%3A%22%3AuriParts%5B%22host%22%5D%3Bif%28host%3D%3Dnull%29%7Bif%28%21%28host%20in%20sources.images%29%29%0Asources.images%5B%22%27self%27%22%5D%3Dnull%3B%7D%0Aelse%7Bif%28host%3D%3DmyHost%29%0Ahost%3D%22%27self%27%22%3Bif%28%21%28host%20in%20sources.images%29%29%0Asources.images%5Bhost%5D%3Dnull%3B%7D%7D%0Avar%20linkElems%3DgetElements%28%22link%22%29%3Bfor%28var%20i%3D0%3Bi%3ClinkElems.length%3Bi%2B%2B%29%7Bif%28linkElems%5Bi%5D.getAttribute%28%22rel%22%29%3D%3D%22shortcut%20icon%22%29%7Bvar%20uriParts%3DparseUri%28linkElems%5Bi%5D.href%29%3Bvar%20host%3D%28uriParts%5B%22protocol%22%5D%3D%3D%22data%22%29%3F%22data%3A%22%3AuriParts%5B%22host%22%5D%3Bif%28host%3D%3Dnull%29%7Bif%28%21%28host%20in%20sources.images%29%29%0Asources.images%5B%22%27self%27%22%5D%3Dnull%3B%7D%0Aelse%7Bif%28host%3D%3DmyHost%29%0Ahost%3D%22%27self%27%22%3Bif%28%21%28host%20in%20sources.images%29%29%0Asources.images%5Bhost%5D%3Dnull%3B%7D%7D%7D%0Avar%20media%3DgetElements%28%22video%2Caudio%22%29%3Bfor%28var%20i%3D0%3Bi%3Cmedia.length%3Bi%2B%2B%29%7Bvar%20uriParts%3DparseUri%28media%5Bi%5D.src%29%3Bvar%20host%3D%28uriParts%5B%22protocol%22%5D%3D%3D%22data%22%29%3F%22data%3A%22%3AuriParts%5B%22host%22%5D%3Bif%28host%3D%3Dnull%29%7Bif%28%21%28host%20in%20sources.media%29%29%0Asources.media%5B%22%27self%27%22%5D%3Dnull%3B%7D%0Aelse%7Bif%28host%3D%3DmyHost%29%0Ahost%3D%22%27self%27%22%3Bif%28%21%28host%20in%20sources.media%29%29%0Asources.media%5Bhost%5D%3Dnull%3B%7D%7D%0Avar%20scripts%3DgetElements%28%22script%22%29%3Bfor%28var%20i%3D0%3Bi%3Cscripts.length%3Bi%2B%2B%29%7Bvar%20uriParts%3DparseUri%28scripts%5Bi%5D.src%29%3Bvar%20host%3D%28uriParts%5B%22protocol%22%5D%3D%3D%22data%22%29%3F%22data%3A%22%3AuriParts%5B%22host%22%5D%3Bif%28host%3D%3Dnull%29%7Bif%28%21%28host%20in%20sources.script%29%29%0Asources.script%5B%22%27self%27%22%5D%3Dnull%3B%7D%0Aelse%7Bif%28host%3D%3DmyHost%29%0Ahost%3D%22%27self%27%22%3Bif%28%21%28host%20in%20sources.script%29%29%0Asources.script%5Bhost%5D%3Dnull%3B%7D%7D%0Avar%20objAppl%3DgetElements%28%22object%2Capplet%22%29%3Bfor%28var%20i%3D0%3Bi%3CobjAppl.length%3Bi%2B%2B%29%7Bif%28objAppl%5Bi%5D.hasAttribute%28%22codebase%22%29%29%7Bvar%20uriParts%3DparseUri%28objAppl%5Bi%5D.getAttribute%28%22codebase%22%29%29%3Bvar%20host%3D%28uriParts%5B%22protocol%22%5D%3D%3D%22data%22%29%3F%22data%3A%22%3AuriParts%5B%22host%22%5D%3Bif%28host%3D%3Dnull%29%7Bif%28%21%28host%20in%20sources.object%29%29%0Asources.object%5B%22%27self%27%22%5D%3Dnull%3B%7D%0Aelse%7Bif%28host%3D%3DmyHost%29%0Ahost%3D%22%27self%27%22%3Bif%28%21%28host%20in%20sources.object%29%29%0Asources.object%5Bhost%5D%3Dnull%3B%7D%7D%0Aif%28objAppl%5Bi%5D.hasAttribute%28%22classid%22%29%29%7Bvar%20uriParts%3DparseUri%28objAppl%5Bi%5D.getAttribute%28%22classid%22%29%29%3Bif%28%5B%22http%22%2C%22https%22%2C%22ftp%22%2Cnull%5D.indexOf%28uriParts%5B%22protocol%22%5D%29%21%3D-1%29%7Bvar%20host%3DuriParts%5B%22host%22%5D%3Bif%28host%3D%3Dnull%29%7Bif%28%21%28host%20in%20sources.object%29%29%0Asources.object%5B%22%27self%27%22%5D%3Dnull%3B%7D%0Aelse%7Bif%28host%3D%3DmyHost%29%0Ahost%3D%22%27self%27%22%3Bif%28%21%28host%20in%20sources.object%29%29%0Asources.object%5Bhost%5D%3Dnull%3B%7D%7D%7D%0Aif%28objAppl%5Bi%5D.hasAttribute%28%22data%22%29%29%7Bvar%20uriParts%3DparseUri%28objAppl%5Bi%5D.getAttribute%28%22data%22%29%29%3Bvar%20host%3D%28uriParts%5B%22protocol%22%5D%3D%3D%22data%22%29%3F%22data%3A%22%3AuriParts%5B%22host%22%5D%3Bif%28host%3D%3Dnull%29%7Bif%28%21%28host%20in%20sources.object%29%29%0Asources.object%5B%22%27self%27%22%5D%3Dnull%3B%7D%0Aelse%7Bif%28host%3D%3DmyHost%29%0Ahost%3D%22%27self%27%22%3Bif%28%21%28host%20in%20sources.object%29%29%0Asources.object%5Bhost%5D%3Dnull%3B%7D%7D%0Aif%28objAppl%5Bi%5D.hasAttribute%28%22archive%22%29%29%7Bvar%20uriParts%3DparseUri%28objAppl%5Bi%5D.getAttribute%28%22archive%22%29%29%3Bvar%20host%3D%28uriParts%5B%22protocol%22%5D%3D%3D%22data%22%29%3F%22data%3A%22%3AuriParts%5B%22host%22%5D%3Bif%28host%3D%3Dnull%29%7Bif%28%21%28host%20in%20sources.object%29%29%0Asources.object%5B%22%27self%27%22%5D%3Dnull%3B%7D%0Aelse%7Bif%28host%3D%3DmyHost%29%0Ahost%3D%22%27self%27%22%3Bif%28%21%28host%20in%20sources.object%29%29%0Asources.object%5Bhost%5D%3Dnull%3B%7D%7D%7D%0Avar%20embeds%3DgetElements%28%22embed%22%29%3Bfor%28var%20i%3D0%3Bi%3Cembeds.length%3Bi%2B%2B%29%7Bvar%20uriParts%3DparseUri%28embeds%5Bi%5D.src%29%3Bvar%20host%3D%28uriParts%5B%22protocol%22%5D%3D%3D%22data%22%29%3F%22data%3A%22%3AuriParts%5B%22host%22%5D%3Bif%28host%3D%3Dnull%29%7Bif%28%21%28host%20in%20sources.object%29%29%0Asources.object%5B%22%27self%27%22%5D%3Dnull%3B%7D%0Aelse%7Bif%28host%3D%3DmyHost%29%0Ahost%3D%22%27self%27%22%3Bif%28%21%28host%20in%20sources.object%29%29%0Asources.object%5Bhost%5D%3Dnull%3B%7D%7D%0Avar%20frameElems%3DgetElements%28%22frame%2Ciframe%22%29%3Bfor%28var%20i%3D0%3Bi%3CframeElems.length%3Bi%2B%2B%29%7Bvar%20uriParts%3DparseUri%28frameElems%5Bi%5D.src%29%3Bvar%20host%3D%28uriParts%5B%22protocol%22%5D%3D%3D%22data%22%29%3F%22data%3A%22%3AuriParts%5B%22host%22%5D%3Bif%28host%3D%3Dnull%29%7Bif%28%21%28host%20in%20sources.frame%29%29%0Asources.frame%5B%22%27self%27%22%5D%3Dnull%3B%7D%0Aelse%7Bif%28host%3D%3DmyHost%29%0Ahost%3D%22%27self%27%22%3Bif%28%21%28host%20in%20sources.frame%29%29%0Asources.frame%5Bhost%5D%3Dnull%3B%7D%7D%0Avar%20stylesheets%3D%7B%7D%3Btry%7Bvar%20stylesheets%3Ddocument.styleSheets%3B%7D%0Acatch%28e%29%7B%7D%0Afor%28var%20i%3D0%3Bi%3Cstylesheets.length%3Bi%2B%2B%29%7Bvar%20rules%3D%7B%7D%3Btry%7Brules%3Dstylesheets%5Bi%5D.cssRules%3B%7D%0Acatch%28e%29%7Bcontinue%3B%7D%0Aif%28%21rules%29%7Bcontinue%3B%7D%0Afor%28var%20j%3D0%3Bj%3Crules.length%3Bj%2B%2B%29%7Bif%28rules%5Bj%5D.type%3D%3Drules%5Bj%5D.FONT_FACE_RULE%29%7Bvar%20src%3Drules%5Bj%5D.style.getPropertyValue%28%22src%22%29%3Bif%28src%29%7Bvar%20url%3Dsrc.replace%28/%5Eurl%5B%27%22%5D%2A/%2C%22%22%29.replace%28/%5B%27%22%5D%2A%5C%29%24/%2C%22%22%29%3Bvar%20uriParts%3DparseUri%28url%29%3Bvar%20host%3D%28uriParts%5B%22protocol%22%5D%3D%3D%22data%22%29%3F%22data%3A%22%3AuriParts%5B%22host%22%5D%3Bif%28host%3D%3Dnull%29%7Bif%28%21%28host%20in%20sources.font%29%29%0Asources.font%5B%22%27self%27%22%5D%3Dnull%3B%7D%0Aelse%7Bif%28host%3D%3DmyHost%29%0Ahost%3D%22%27self%27%22%3Bif%28%21%28host%20in%20sources.font%29%29%0Asources.font%5Bhost%5D%3Dnull%3B%7D%7D%7D%7D%7D%0Avar%20linkElems%3DgetElements%28%22link%22%29%3Bfor%28var%20i%3D0%3Bi%3ClinkElems.length%3Bi%2B%2B%29%7Bif%28linkElems%5Bi%5D.getAttribute%28%22rel%22%29%3D%3D%22stylesheet%22%29%7Bvar%20uriParts%3DparseUri%28linkElems%5Bi%5D.href%29%3Bvar%20host%3D%28uriParts%5B%22protocol%22%5D%3D%3D%22data%22%29%3F%22data%3A%22%3AuriParts%5B%22host%22%5D%3Bif%28host%3D%3Dnull%29%7Bif%28%21%28host%20in%20sources.style%29%29%0Asources.style%5B%22%27self%27%22%5D%3Dnull%3B%7D%0Aelse%7Bif%28host%3D%3DmyHost%29%0Ahost%3D%22%27self%27%22%3Bif%28%21%28host%20in%20sources.style%29%29%0Asources.style%5Bhost%5D%3Dnull%3B%7D%7D%7D%0Aalert%28generatePolicyFromSources%28sources%29%29%3B%7D%0AanalyzeContent%28%29%3B" class="bookmarklet">Recommend CSP</a></p>
<p>If you find it useful, drag it to your <a href="http://support.mozilla.com/en-us/kb/bookmarks#Where_to_find_bookmarks">bookmarks toolbar</a> and you can use it from any web page.  Feel free to check out the <a href="https://github.com/bsterne/bsterne-tools/blob/master/csp-bookmarklet/csp-bookmarklet.js">bookmarklet source</a> as well.</p>
<p>In the future, I would like to add notifications for potential <a href="https://developer.mozilla.org/en/Security/CSP/Default_CSP_restrictions#Restricted_scripts">inline script violations</a>.</p>
<style type="text/css">
a.bookmarklet {
  text-decoration: none;
  display: inline-block;
  border: 1px solid #bbb;
  padding: .25em .5em;
  margin: .5em;
  -moz-border-radius: .5em;
  -webkit-border-radius: .5em;
}
</style>
]]></content:encoded>
			<wfw:commentRss>http://brandon.sternefamily.net/posts/2010/10/content-security-policy-recommendation-bookmarklet/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Hacked my DEF CON 18 badge</title>
		<link>http://brandon.sternefamily.net/posts/2010/07/hacked-my-def-con-18-badge/</link>
		<comments>http://brandon.sternefamily.net/posts/2010/07/hacked-my-def-con-18-badge/#comments</comments>
		<pubDate>Sat, 31 Jul 2010 00:11:40 +0000</pubDate>
		<dc:creator>bsterne</dc:creator>
				<category><![CDATA[Programming]]></category>
		<category><![CDATA[Security]]></category>

		<guid isPermaLink="false">http://brandon.sternefamily.net/posts/?p=366</guid>
		<description><![CDATA[I was only able willing to stay for part of the first day of DEF CON this year, but I&#8217;m glad I did. One of the things they&#8217;ve done for the last five years or so is put microcontrollers in the badges, and put in little Easter eggs for people to search for. This year&#8217;s [...]]]></description>
			<content:encoded><![CDATA[<p>I was only <del datetime="2010-07-30T23:36:03+00:00">able</del> willing to stay for part of the first day of <a href="http://www.defcon.org/html/defcon-18/dc-18-index.html">DEF CON</a> this year, but I&#8217;m glad I did.  One of the things they&#8217;ve done for the last five years or so is put microcontrollers in the badges, and put in little Easter eggs for people to search for.  This year&#8217;s had a Ninja Party mode which was locked by default, but you could unlock it by placing a series of 15 tumblers in the correct position.</p>
<p>They published the source code for the badges on the CD they gave out at registration (so perhaps I&#8217;m stupid for loading the CD on my laptop rather than smart for reverse engineering the badge).  I opened up DC18_Badge.c and, searching for &#8220;Ninja&#8221; (the code was commented nicely), quickly found the following two C functions:</p>
<pre class="brush: cpp; gutter: false">
/**************************************************************/
/* NINJA ROUTINES
/**************************************************************/

int dc18_ninja_validate(uint32_t val)
{
    uint16_t a, b;

    a = (uint16_t)(val &#038; 0xfff);
    b = (uint16_t)(val >> 12);

    if((a ^ b) == 0x916)
    {
        return 1;
    }
    return 0;
}

// encode tumbler states into 24-bit value
uint32_t dc18_encode_tumblers(tumbler_state_type *tumblers)
{
    uint32_t x = 0, j = 1;
    uint16_t i;

    for(i = 0; i < TUMBLERS_PER_IMAGE; i++)
    {
        x += tumblers[i] * j;
        j *= 3;
    }

    return x;
}
</pre>
<p>So the trick was to find the number that made <code>(a ^ b) == 0x916</code> and then figure out the tumbler positions to represent that number.  I wrote two small Python functions to automate those tasks.  To find the number that would unlock Ninja Mode, I wrote this loop.  I added a print statement to show how far into the search we were, thinking it might take some time to find it, but it popped out 6423 in no time at all:
<pre class="brush: python; gutter: false">while 1:
	a = i &#038; 0xfff
	b = i >> 12
	if i % 10000 == 0:
		print "# a: %d, b: %d, i: %d" % (a, b, i)
	if a ^ b == 0x916:
		print "DONE: %d" % (i)
		break
	i += 1

DONE: 6423
</pre>
<p>Now all that was left was to figure out the tumbler positions to represent 6423.  Clearly, <code>dc18_encode_tumblers</code> tells us how to do that.  I whipped up this little function to convert the tumbler positions to a decimal number:</p>
<pre class="brush: python; gutter: false">def enc_tumblers(tum):
	x = 0; j = 1;
	for i in range(15):
		x += tum[i] * j
		j *= 3
	return x

>>> enc_tumblers([1,1,1,1,1,2,2,2,0,0,0,0,0,0,0])
6439
</pre>
<p>I was going to write another loop to increment the tumbler array I was passing to <code>enc_tumblers</code>, but my first guess was so close that I just manually entered the settings until I found the winning configuration:</p>
<pre class="brush: python; gutter: false">>>> enc_tumblers([0,2,2,0,1,2,2,2,0,0,0,0,0,0,0])
6423
</pre>
<p>Once I had the configuration, I put the tumblers in the appropriate positions: 0 - up, 1 - middle, 2 - down.  After that, well, I guess I'm a ninja now:</p>
<p><a href="http://brandon.sternefamily.net/posts/wp-content/uploads/2010/07/def-con.jpg"><img src="http://brandon.sternefamily.net/posts/wp-content/uploads/2010/07/def-con.jpg" alt="" title="Ninja Party Unlocked" width="80%" class="aligncenter size-full wp-image-380" /></a><br />
<script type="text/javascript" src="/posts/syntax/src/shCore.js"></script><br />
<script type="text/javascript" src="/posts/syntax/scripts/shBrushCpp.js"></script><br />
<script type="text/javascript" src="/posts/syntax/scripts/shBrushPython.js"></script></p>
<link rel="stylesheet" type="text/css" href="/posts/syntax/styles/shCore.css" />
<link type="text/css" rel="Stylesheet" href="/posts/syntax/styles/shThemeDefault.css"/>
<script type="text/javascript">SyntaxHighlighter.all()</script></p>
]]></content:encoded>
			<wfw:commentRss>http://brandon.sternefamily.net/posts/2010/07/hacked-my-def-con-18-badge/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>WordPress and Content Security Policy</title>
		<link>http://brandon.sternefamily.net/posts/2010/04/wordpress-and-content-security-policy/</link>
		<comments>http://brandon.sternefamily.net/posts/2010/04/wordpress-and-content-security-policy/#comments</comments>
		<pubDate>Tue, 13 Apr 2010 03:54:15 +0000</pubDate>
		<dc:creator>bsterne</dc:creator>
				<category><![CDATA[Mozilla]]></category>
		<category><![CDATA[Security]]></category>
		<category><![CDATA[Web Security]]></category>

		<guid isPermaLink="false">http://brandon.sternefamily.net/posts/?p=198</guid>
		<description><![CDATA[Lately, I have been implementing the server logic for <a href="http://people.mozilla.org/~bsterne/content-security-policy/">Content Security Policy</a> in <a href="http://wordpress.org/">WordPress</a>.  Today, I posted my first <a href="http://core.trac.wordpress.org/attachment/ticket/10237/csp-wip-v1.patch">patch to WordPress</a>, still a work in progress, which adds an administration panel for configuring CSP.  One of the features I'm rather happy with is "Suggest Policy", which analyzes the content in the user's blog and recommends a policy based on the content types and sources it finds.</p>]]></description>
			<content:encoded><![CDATA[<p>Lately, I have been implementing the server logic for <a href="http://people.mozilla.org/~bsterne/content-security-policy/">Content Security Policy</a> in <a href="http://wordpress.org/">WordPress</a>.  I was very pleased to see that the WordPress community opened up the <a href="http://core.trac.wordpress.org/ticket/10237">tracking bug</a> for this feature around the time we first <a href="http://blog.mozilla.com/security/2009/06/19/shutting-down-xss-with-content-security-policy/">blogged</a> about it.  One of the neat things about working for Mozilla is that contributions to other important <a href="http://www.catb.org/~esr/open-source.html">open source projects</a> are treated as valid, valuable uses of our time.</p>
<p>Today, I posted my first <a href="http://core.trac.wordpress.org/attachment/ticket/10237/csp-wip-v1.patch" style="font-weight:600">patch to WordPress</a>, still a work in progress, which adds an administration panel (see below) for configuring CSP.  One of the features I&#8217;m rather happy with is &#8220;Suggest Policy&#8221;, which analyzes the content in the user&#8217;s blog and recommends a policy based on the content types and sources it finds.</p>
<p class="center"><a href="http://brandon.sternefamily.net/posts/wp-content/uploads/2010/04/Picture-3.png"><img src="http://brandon.sternefamily.net/posts/wp-content/uploads/2010/04/Picture-3-300x206.png" alt="" title="CSP in WordPress" style="width:50%" class="aligncenter size-medium wp-image-217" /></a></p>
<p>Next I&#8217;ll be working on moving the remaining <a href="https://wiki.mozilla.org/Security/CSP/Spec#No_inline_scripts_will_execute">inline script</a> into external script files.  Stay tuned for further updates!</p>
]]></content:encoded>
			<wfw:commentRss>http://brandon.sternefamily.net/posts/2010/04/wordpress-and-content-security-policy/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Python AES Implementation &#8211; Update</title>
		<link>http://brandon.sternefamily.net/posts/2009/04/python-aes-update/</link>
		<comments>http://brandon.sternefamily.net/posts/2009/04/python-aes-update/#comments</comments>
		<pubDate>Sat, 04 Apr 2009 15:55:16 +0000</pubDate>
		<dc:creator>bsterne</dc:creator>
				<category><![CDATA[Programming]]></category>
		<category><![CDATA[Python]]></category>
		<category><![CDATA[Security]]></category>

		<guid isPermaLink="false">http://brandon.sternefamily.net/posts/?p=115</guid>
		<description><![CDATA[I fixed two bugs in my AES implementation. The first was a padding bug which resulted in the loss of up to a block of data when decrypting certain ciphertexts. The second bug was a more serious security problem caused by the use of a static initialization vector.]]></description>
			<content:encoded><![CDATA[<p>I fixed two bugs  in my <a href="/posts/2007/06/aes-tutorial-python-implementation/">AES implementation</a>.  The first was a padding bug which resulted in the loss of up to a block of data when decrypting certain ciphertexts.  The second bug was a more serious security problem caused by the use of a static initialization vector.</p>
]]></content:encoded>
			<wfw:commentRss>http://brandon.sternefamily.net/posts/2009/04/python-aes-update/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>AES Tutorial / Python Implementation</title>
		<link>http://brandon.sternefamily.net/posts/2007/06/aes-tutorial-python-implementation/</link>
		<comments>http://brandon.sternefamily.net/posts/2007/06/aes-tutorial-python-implementation/#comments</comments>
		<pubDate>Mon, 11 Jun 2007 04:51:50 +0000</pubDate>
		<dc:creator>bsterne</dc:creator>
				<category><![CDATA[Programming]]></category>
		<category><![CDATA[Python]]></category>
		<category><![CDATA[Security]]></category>

		<guid isPermaLink="false">http://brandon.sternefamily.net/posts/?p=91</guid>
		<description><![CDATA[I put together a series of slides as well as a <a href="/posts/2007/06/aes-tutorial-python-implementation/" title="AES Tutorial">Python implementation of AES</a>, the symmetric-key cryptosystem.]]></description>
			<content:encoded><![CDATA[<style type="text/css">
p.title {
	margin-top:0;
	text-align:center;
	font-weight:600;
	width: 100%;
	color:white;
	background-color:rgb(0,0,128);
}
.middleblock li {
	margin-bottom:.5em
}
ul li.indent0 {
	margin-left:0;
	margin-bottom:.5em
}
ul li.indent1 {
	margin-left:1em;
	list-style:circle;
	margin-bottom:.5em
}
ul li.indent2 {
	margin-left:1.5em;
	list-style:disc;
	margin-bottom:.5em
}
ul li.indent3 {
	margin-left:2em;
	list-style:none;
	margin-bottom:.5em
}
ol li.indent0 {
	margin:0;
	margin-bottom:.5em
}
.code {
	font-family:monospace;
	white-space:pre;
}
</style>
<div class="middleBlock">
<p><b>Update: 04-Apr-2009</b></p>
<p>I fixed two bugs in my AES implementation pointed out to me by <a href="http://www.ics.uci.edu/~jcarlson/">Josiah Carlson</a>.  First, I was failing to pad properly files whose length was an even multiple of the block size.  In those cases, bytes would be lost upon decrypting the file.  Josiah also pointed out that I was using a static <a href="http://en.wikipedia.org/wiki/Initialization_vector">IV</a>, which leaks information about messages which share common prefixes.  This is a serious security bug and I was glad to have it pointed out.</p>
<p>Feel free to check out the <a href="/files/pyAES_patch">changes</a> I made or simply download the <a href="/files/pyAES.txt">updated script</a>.</p>
</div>
<p>I&#8217;ve put together a series of slides as well as a Python implementation of AES, the symmetric-key cryptosystem.</p>
<div style="border: 1px dashed #000; background-color:rgb(240,240,240); padding:10px; margin:auto;">
<p style="text-align:center"><b>Source:</b> <a href="/files/pyAES.txt">pyAES.py</a></p>
<p><b>Sample Usage:</b> (color added for clarity)</p>
<p class="code" style="text-align:left">[brandon@zodiac pyAES]$ cat > testfile.txt<br />
<span style="color:#00b000">The sky was the color of television tuned to a dead channel.</span><br />
[brandon@zodiac pyAES]$ ./pyAES.py -e testfile.txt -o testfile_encrypted.txt<br />
Password:<br />
Encrypting file: testfile.txt<br />
Encryption complete.<br />
[brandon@zodiac pyAES]$ ./pyAES.py -d testfile_encrypted.txt -o testfile_decrypted.txt<br />
Password:<br />
Decrypting file: testfile_encrypted.txt<br />
Decryption complete.<br />
[brandon@zodiac pyAES]$ cat testfile_decrypted.txt<br />
<span style="color:#00b000">The sky was the color of television tuned to a dead channel.</span><br />
[brandon@zodiac pyAES]$ md5sum *<br />
19725cef7495fd55540728759a6262c8  pyAES.py<br />
<span style="color:#00b000">2fffc9072a7c09f4f97862c0bceb6021  testfile_decrypted.txt</span><br />
<span style="color:#b00000">3e57070eaf1b4adf7f43b38e1c5ee631  testfile_encrypted.txt</span><br />
<span style="color:#00b000">2fffc9072a7c09f4f97862c0bceb6021  testfile.txt</span>
</p>
</div>
<p>					<!-- begin Slide --></p>
<div class="middleBlock">
<p class="title">Symmetric Key Cryptography</p>
<ul>
<li class="indent0">Identical keys used to encrypt/decrypt messages</li>
<li class="indent0">Can be implemented as block ciphers or stream ciphers</li>
</ul>
<p>					<b>Strengths:</b></p>
<ul>
<li class="indent0">Speed</li>
<li class="indent1">Much less computationally intensive than public-key crypto</li>
<li class="indent0">Easy to implement in hardware as well as software</li>
</ul>
<p>					<b>Weaknesses:</b></p>
<ul>
<li class="indent0">Key Management</li>
<li class="indent1"><em>n</em> users require <em>n</em>(<em>n</em>-1)/2 keys for all to communicate</li>
<li class="indent1">secure key distribution is a challenge</li>
<li class="indent0">Cannot be used (directly) for authentication or non-repudiation</li>
</ul></div>
<p>					<!-- end Slide --><br />
					<!-- begin Slide --></p>
<div class="middleBlock">
<p class="title">AES &#8211; The Advanced Encryption Standard</p>
<ul>
<li class="indent0">Rijndael algorithm invented by Joan Daemen and Vincent Rijmen and selected as AES winner by NIST in 2001</li>
<li class="indent0">AES uses fixed block size of 128-bits and key sizes of 128, 192 or 256 bits (though Rijndael specification allows for variable block and key sizes)</li>
<li class="indent0">Most of the calculations in AES are performed within a finite field</li>
<li class="indent1">There are a finite number of elements within the field and all operations on those elements result in an element also contained in the field</li>
</ul></div>
<p>					<!-- end Slide --><br />
					<!-- begin Slide --></p>
<div class="middleBlock">
<p class="title">AES Operations</p>
<ul>
<li class="indent0">AES operates on a 4&#215;4 matrix referred to as the <em>state</em></li>
<li class="indent1">16 bytes == 128 bits == block size</li>
<li class="indent0">All operations in a round of AES are invertible</li>
<li class="indent1">AddRoundKey &#8211; each byte of the round key is combined with the corresponding byte in the state using XOR</li>
<li class="indent1">SubBytes &#8211; each byte in the state is replaced with a different byte according to the S-Box lookup table</li>
<li class="indent1">ShiftRows &#8211; each row in the state table is shifted by a varying number of bytes</li>
<li class="indent1">MixColumns &#8211; each column in the state table is multiplied with a fixed polynomial</li>
</ul></div>
<p>					<!-- end Slide --><br />
					<!-- begin Slide --></p>
<div class="middleBlock">
<p class="title">AES Operation &#8211; AddRoundKey</p>
<ul>
<li class="indent0">Each byte of the round key is XORed with the corresponding byte in the state table</li>
<li class="indent0">Inverse operation is identical since XOR a second time returns the original values</li>
</ul>
<pre class="brush: python; gutter: false"># XOR each byte of the roundKey with the state table
def addRoundKey(state, roundKey):
    for i in range(len(state)):
        state[i] = state[i] ^ roundKey[i]</pre>
</p></div>
<p>					<!-- end Slide --><br />
					<!-- begin Slide --></p>
<div class="middleBlock">
<p class="title">AES Operation &#8211; SubBytes</p>
<ul>
<li class="indent0">Each byte of the state table is substituted with the value in the S-Box whose index is the value of the state table byte</li>
<li class="indent0">Provides non-linearity (algorithm not equal to the sum of its parts)</li>
<li class="indent0">Inverse operation is performed using the inverted S-Box</li>
</ul>
<pre class="brush: python; gutter: false"># do sbox transform on each of the values in the state table
def subBytes(state):
    for i in range(len(state)):
        state[i] = sbox[state[i]]

# sbox transformations are invertible
>>> sbox[237]
85
>>> sboxInv[85]
237
>>> sbox[55]
154
>>> sbox[154]
184
>>> sboxInv[184]
154
>>> sboxInv[154]
55</pre>
</p></div>
<p>					<!-- end Slide --><br />
					<!-- begin Slide --></p>
<div class="middleBlock">
<p class="title">AES Operation &#8211; ShiftRows</p>
<ul>
<li class="indent0">Each row in the state table is shifted left by the number of bytes represented by the row number</li>
<li class="indent0">Inverse operation simply shifts each row to the right by the number of bytes as the row number</li>
</ul>
<pre class="brush: python; gutter: false"># returns a copy of the word shifted n bytes (chars) positive
# values for n shift bytes left, negative values shift right
def rotate(word, n):
    return word[n:]+word[0:n]

# iterate over each "virtual" row in the state table
# and shift the bytes to the LEFT by the appropriate
# offset
def shiftRows(state):
    for i in range(4):
        state[i*4:i*4+4] = rotate(state[i*4:i*4+4],i)</pre>
</p></div>
<p>					<!-- end Slide --><br />
					<!-- begin Slide --></p>
<div class="middleBlock">
<p class="title">AES Operation &#8211; MixColumns</p>
<ul>
<li class="indent0">MixColumns is performed by multiplying each column (within the <a href="http://en.wikipedia.org/wiki/Rijndael_Galois_field">Galois finite field</a>) by the following matrix:</li>
</ul>
<p>					<img src="images/aes_mix_columns_matrix.png" alt="" /></p>
<ul>
<li class="indent0">The inverse operation is performed by multiplying each column by the following inverse matrix:</li>
</ul>
<p>					<img src="images/aes_mix_columns_inv_matrix.png" alt="" /></p>
<pre class="brush: python; gutter: false"># Galois Multiplication
def galoisMult(a, b):
    p = 0
    hiBitSet = 0
    for i in range(8):
        if b &amp; 1 == 1:
            p ^= a
        hiBitSet = a &amp; 0x80
        a &lt;&lt;= 1
        if hiBitSet == 0x80:
            a ^= 0x1b
        b &gt;&gt;= 1
    return p % 256

# mixColumn does Galois multiplication on a state column
def mixColumn(column):
    temp = copy(column)
    column[0] = galoisMult(temp[0],2) ^ galoisMult(temp[3],1) ^ \
                galoisMult(temp[2],1) ^ galoisMult(temp[1],3)
    column[1] = galoisMult(temp[1],2) ^ galoisMult(temp[0],1) ^ \
                galoisMult(temp[3],1) ^ galoisMult(temp[2],3)
    column[2] = galoisMult(temp[2],2) ^ galoisMult(temp[1],1) ^ \
                galoisMult(temp[0],1) ^ galoisMult(temp[3],3)
    column[3] = galoisMult(temp[3],2) ^ galoisMult(temp[2],1) ^ \
                galoisMult(temp[1],1) ^ galoisMult(temp[0],3)</pre>
</p></div>
<p>					<!-- end Slide --><br />
					<!-- begin Slide --></p>
<div class="middleBlock">
<p class="title">AES &#8211; Pulling It All Together</p>
<p>					The AES Cipher operates using a varying <b>number of rounds</b>, based on the size of the <b>cipher key</b>.</p>
<ul>
<li class="indent0">A <b>round</b> of AES consists of the four operations performed in succession: AddRoundKey, SubBytes, ShiftRows, and MixColumns (MixColumns is omitted in the final round)</li>
<li class="indent0">128-bit key &rarr; rounds, 192-bit key &rarr; 12 rounds, 256-bit key &rarr; 14 rounds</li>
<li class="indent0">The AES cipher key is expanded according to the Rijndael key schedule and a different part of the expanded key is used for each round of AES</li>
<li class="indent1">The expanded key will be of length <b>(block size * num rounds+1)</b></li>
<li class="indent1">128-bit cipher key expands to 176-byte key</li>
<li class="indent1">192-bit cipher key expands to 208-byte key</li>
<li class="indent1">256-bit cipher key expands to 240-byte key</li>
</ul></div>
<p>					<!-- end Slide --><br />
					<!-- begin Slide --></p>
<div class="middleBlock">
<p class="title">AES &#8211; Key Expansion Operations</p>
<p>					AES key expansion consists of several primitive operations:</p>
<ol>
<li class="indent0">Rotate &#8211; takes a 4-byte word and rotates everything one byte to the left, e.g. <span style="code">rotate([1,2,3,4]) &rarr; [2, 3, 4, 1]</span></li>
<li class="indent0">SubBytes &#8211; each byte of a word is substituted with the value in the S-Box whose index is the value of the original byte</li>
<li class="indent0">Rcon &#8211; the first byte of a word is XORed with the <b>round constant</b>.  Each value of the Rcon table is a member of the Rinjdael finite field.</li>
</ol>
<pre class="brush: python; gutter: false"># takes 4-byte word and iteration number
def keyScheduleCore(word, i):
    # rotate word 1 byte to the left
    word = rotate(word, 1)
    newWord = []
    # apply sbox substitution on all bytes of word
    for byte in word:
        newWord.append(sbox[byte])
    # XOR the output of the rcon[i] transformation with the first part
    # of the word
    newWord[0] = newWord[0]^rcon[i]
    return newWord</pre>
</p></div>
<p>					<!-- end Slide --></p>
<p>					<!-- begin Slide --></p>
<div class="middleBlock">
<p class="title">AES &#8211; Key Expansion Algorithm (256-bit)</p>
<p>					Pseudo-code for AES Key Expansion:</p>
<ol>
<li class="indent0 code"><b>expandedKey</b>[0:32] &rarr; <b>cipherKey</b>[0:32]  # copy first 32 bytes of cipher key to expanded key</li>
<li class="indent0 code"><b>i</b> &rarr; 1  # Rcon iterator</li>
<li class="indent0 code"><b>temp</b> = byte[4]  # 4-byte container for temp storage</li>
<li class="indent0 code">while size(<b>expandedKey</b>) &lt; 240<br />
    <b>temp</b> &rarr; last 4 bytes of <b>expandedKey</b></p>
<p>    # every 32 bytes apply core schedule to temp<br />
    if size(<b>expandedKey</b>)%32 == 0<br />
        <b>temp</b> = keyScheduleCore(<b>temp</b>, <b>i</b>)<br />
        <b>i</b> &rarr; <b>i</b> + 1<br />
    # since 256-bit key -> add an extra sbox transformation to each new byte<br />
    for <b>j</b> in range(4):<br />
        <b>temp</b>[<b>j</b>] = <b>sbox</b>[<b>temp</b>[<b>j</b>]]<br />
    # XOR temp with the 4-byte block 32 bytes before the end of the current expanded key.<br />
    # These 4 bytes become the next bytes in the expanded key<br />
    <b>expandedKey</b>.append( <b>temp</b> XOR <b>expandedKey</b>[size(<b>expandedKey</b>)-32:size(<b>expandedKey</b>)-28]</li>
</ol>
<p>					Another function to note&#8230;</p>
<pre class="brush: python; gutter: false"># returns a 16-byte round key based on an expanded key and round number
def createRoundKey(expandedKey, n):
    return expandedKey[(n*16):(n*16+16)]</pre>
</p></div>
<p>					<!-- end Slide --><br />
					<!-- begin Slide --></p>
<div class="middleBlock">
<p class="title">AES &#8211; Encrypting a Single Block</p>
<ol>
<li class="indent0"><b>state</b> &rarr; block of plaintext    # 16 bytes of plaintext are copied into the state</li>
<li class="indent0"><b>expandedKey</b> = expandKey(<b>cipherKey</b>)    # create 240-bytes of key material to be used as round keys</li>
<li class="indent0"><b>roundNum</b> &rarr; 0    # counter for which round number we are in</li>
<li class="indent0"><b>roundKey</b> &rarr; createRoundKey(<b>expandedKey</b>, <b>roundNum</b>)</li>
<li class="indent0">addRoundKey(<b>state</b>, <b>roundKey</b>)    # each byte of state is XORed with the present roundKey</li>
<li class="indent0">while <b>roundNum</b> &lt; 14   # 14 rounds in AES-256<br />
    <b>roundKey</b> &rarr; createRoundKey(<b>expandedKey</b>, <b>roundNum</b>)<br />
    # round of AES consists of 1. subBytes, 2. shiftRows, 3. mixColumns, and 4. addRoundKey<br />
    aesRound(<b>state</b>, <b>roundKey</b>)<br />
    <b>roundNum</b> &rarr; <b>roundNum</b> + 1</li>
<li class="indent0"># for the last round leave out the mixColumns operation<br />
    <b>roundKey</b> = createRoundKey(<b>expandedKey</b>, <b>roundNum</b>)<br />
    subBytes(<b>state</b>)<br />
    shiftRows(<b>state</b>)<br />
    addRoundKey(<b>state</b>)</li>
<li class="indent0">return <b>state</b> as block of ciphertext</li>
</ol></div>
<p>					<!-- end Slide --><br />
					<!-- begin Slide --></p>
<div class="middleBlock">
<p class="title">AES &#8211; Encrypting a Single Block (Demo)</p>
<pre class="brush: python; gutter: false">
>>> key = passwordToKey("s0m3_p@ssw0rD")
>>> key
[62, 142, 78, 2, 164, 231, 18, 196, 148, 177, 82, 186, 240, 44, 136, 242,
23, 13, 20, 169, 248, 69, 163, 79, 13, 155, 97, 200, 241, 15, 76, 15]
>>> plaintext = textToBlock("Hiro Protagonist")
>>> plaintext
[72, 105, 114, 111, 32, 80, 114, 111, 116, 97, 103, 111, 110, 105, 115, 116]
>>> blockToText(plaintext)
'Hiro Protagonist'
>>> ciphertext = aesEncrypt(plaintext, key)

*** aesMain ***
initial state:
[72, 105, 114, 111, 32, 80, 114, 111, 116, 97, 103, 111, 110, 105, 115, 116]
state after adding roundKey0:
[118, 231, 60, 109, 132, 183, 96, 171, 224, 208, 53, 213, 158, 69, 251, 134]

*** AES Round1 ***
state after subBytes:
[56, 148, 235, 60, 95, 169, 208, 98, 225, 112, 150, 3, 11, 110, 15, 68]
state after shiftRows:
[56, 148, 235, 60, 169, 208, 98, 95, 150, 3, 225, 112, 68, 11, 110, 15]
state after mixColumns:
[66, 80, 228, 230, 148, 33, 121, 29, 106, 95, 226, 146, 255, 98, 121, 117]
state after addRoundKey:
[85, 93, 240, 79, 108, 100, 218, 82, 103, 196, 131, 90, 14, 109, 53, 122]

&lt;-- SNIP --&gt;

*** AES Round 14 (final) ***
state after subBytes:
[0, 229, 171, 70, 93, 137, 135, 251, 99, 182, 88, 166, 228, 229, 251, 97]
state after shiftRows:
[0, 229, 171, 70, 137, 135, 251, 93, 88, 166, 99, 182, 97, 228, 229, 251]
state after addRoundKey:
[195, 123, 205, 183, 213, 202, 50, 223, 223, 164, 99, 86, 126, 34, 107, 142]

>>> ciphertext
[195, 123, 205, 183, 213, 202, 50, 223, 223, 164, 99, 86, 126, 34, 107, 142]

>>> blockToText(ciphertext)
'\xc3{\xcd\xb7\xd5\xca2\xdf\xdf\xa4cV~"k\x8e'
>>> cleartext = aesDecrypt(ciphertext, key)

*** aesMainInv ***
initial state:
[195, 123, 205, 183, 213, 202, 50, 223, 223, 164, 99, 86, 126, 34, 107, 142]

*** AES Round 14 ***
state after addRoundKey:
[0, 229, 171, 70, 137, 135, 251, 93, 88, 166, 99, 182, 97, 228, 229, 251]
state after shiftRowsInv:
[0, 229, 171, 70, 93, 137, 135, 251, 99, 182, 88, 166, 228, 229, 251, 97]
state after subBytesInv:
[82, 42, 14, 152, 141, 242, 234, 99, 0, 121, 94, 197, 174, 42, 99, 216]

&lt;-- SNIP --&gt;

*** AES Round 0 (final) ***
state after adding roundKey0:
[72, 105, 114, 111, 32, 80, 114, 111, 116, 97, 103, 111, 110, 105, 115, 116]
>>> cleartext
[72, 105, 114, 111, 32, 80, 114, 111, 116, 97, 103, 111, 110, 105, 115, 116]
>>> blockToText(cleartext)
'Hiro Protagonist'</pre>
</p></div>
<p>					<!-- end Slide --></p>
<p><script type="text/javascript" src="/posts/syntax/src/shCore.js"></script><br />
<script type="text/javascript" src="/posts/syntax/scripts/shBrushPython.js"></script></p>
<link rel="stylesheet" type="text/css" href="/posts/syntax/styles/shCore.css" />
<link type="text/css" rel="Stylesheet" href="/posts/syntax/styles/shThemeDefault.css"/>
<script type="text/javascript">SyntaxHighlighter.all()</script></p>
]]></content:encoded>
			<wfw:commentRss>http://brandon.sternefamily.net/posts/2007/06/aes-tutorial-python-implementation/feed/</wfw:commentRss>
		<slash:comments>7</slash:comments>
		</item>
		<item>
		<title>PyRSA &#8211; RSA in Python</title>
		<link>http://brandon.sternefamily.net/posts/2005/06/pyrsa-rsa-in-python/</link>
		<comments>http://brandon.sternefamily.net/posts/2005/06/pyrsa-rsa-in-python/#comments</comments>
		<pubDate>Sat, 18 Jun 2005 18:27:09 +0000</pubDate>
		<dc:creator>bsterne</dc:creator>
				<category><![CDATA[Programming]]></category>
		<category><![CDATA[Python]]></category>
		<category><![CDATA[Security]]></category>

		<guid isPermaLink="false">http://brandon.sternefamily.net/posts/?p=31</guid>
		<description><![CDATA[I implemented the public key cryptosystem <a href="/posts/2005/06/pyrsa-rsa-in-python/">RSA in Python</a>.  Check out the article I wrote about <a href="/posts/2005/05/rsa-algorithm/">RSA</a> or download the <a href="/files/pyrsa.txt">source code</a>.]]></description>
			<content:encoded><![CDATA[<p>PyRSA is a command line utility that allows users to digitally encrypt and sign messages using the public key encryption scheme, <a href="/posts/2005/05/rsa-algorithm/">RSA</a>. There are three basic functions that PyRSA performs: encryption, decryption, and key generation.</p>
<p><strong>Downloads:</strong></p>
<p>Source: <a href="/files/pyrsa.txt">pyrsa.py</a></p>
<p><strong>Sample Use:</strong></p>
<p>1. Generate a public and private key. In this example, we will specify a key of length 1024 bits. Allow several seconds of CPU time for the generation of the keys.</p>
<pre class="brush: plain; gutter: false; light: true">pyrsa.py -g 1024 Enter fil&#101; identifier (i.e. first name): brandon</pre>
<p>2. Now the files
<pre class="brush: bash; gutter: false">brandon_privateKey.txt</pre>
<p> and
<pre class="brush: bash; gutter: false">brandon_publicKey.txt</pre>
<p> are in the current directory. Next place the text we want to encrypt in a text file.</p>
<pre class="brush: bash; gutter: false">echo "The sky above the port was the color of television, tuned
to a dead channel." > message.txt</pre>
<p>3. Encrypt the message using the public key and redirect the output to a text file.</p>
<pre class="brush: bash; gutter: false">pyrsa.py -e message.txt -k brandon_publicKey.txt > ciphertext.txt</pre>
<p>4. At this point the file ciphertext.txt contains the encrypted message. The file can safely be sent to a recipient, i.e. as an email attachment, the contents utterly unreadable to anyone without the private key.</p>
<pre class="brush: bash; gutter: false">cat ciphertext.txt 32464047998704731086703458860763720628883125201
840735448292781611869424600546740055592235111171870058664751326891
416030992911165222195048303846516331939189036032662981573683210672
785053735077400433222553780571914729993485153779710689497701348386
214277988780913721453283666357504772556433129612632786845350983</pre>
<p>5. Next we will assume the message has been sent to the individual who possesses the corresponding private key and he wants to decrypt the message.</p>
<pre class="brush: bash; gutter: false">pyrsa.py -d ciphertext.txt -k brandon_privateKey.txt
Decrypted text:
The sky above the port was the color of television, tuned to a dead channel.</pre>
<p><script type="text/javascript" src="/posts/syntax/src/shCore.js"></script><br />
<script type="text/javascript" src="/posts/syntax/scripts/shBrushBash.js"></script><br />
<script type="text/javascript" src="/posts/syntax/scripts/shBrushPlain.js"></script></p>
<link rel="stylesheet" type="text/css" href="/posts/syntax/styles/shCore.css" />
<link type="text/css" rel="Stylesheet" href="/posts/syntax/styles/shThemeDefault.css"/>
<script type="text/javascript">SyntaxHighlighter.all()</script></p>
]]></content:encoded>
			<wfw:commentRss>http://brandon.sternefamily.net/posts/2005/06/pyrsa-rsa-in-python/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>RSA Algorithm</title>
		<link>http://brandon.sternefamily.net/posts/2005/05/rsa-algorithm/</link>
		<comments>http://brandon.sternefamily.net/posts/2005/05/rsa-algorithm/#comments</comments>
		<pubDate>Thu, 05 May 2005 13:50:42 +0000</pubDate>
		<dc:creator>bsterne</dc:creator>
				<category><![CDATA[Programming]]></category>
		<category><![CDATA[Python]]></category>
		<category><![CDATA[Security]]></category>

		<guid isPermaLink="false">http://brandon.sternefamily.net/posts/?p=28</guid>
		<description><![CDATA[I wrote an article on <a href="/posts/2005/05/rsa-algorithm/">RSA</a>, a popular public key encryption scheme.  Eventually, I am going to implement <a href="/posts/2005/06/pyrsa-rsa-in-python/">RSA in Python</a>.]]></description>
			<content:encoded><![CDATA[<h3 class="center">Overview</h3>
<p>We have spent the last several weeks learning about encryption in my <a href="http://www.cs.ucr.edu/cs165">computer security class</a> so I thought I&#8217;d share what I&#8217;ve learned on public key cryptography.</p>
<p>There is a very good description of RSA on <a href="http://en.wikipedia.org/wiki/RSA">Wikipedia</a>, so I don&#8217;t want to simply restate what they have. The focus here will be the generation of public and private keys as I feel many of the RSA tutorials on the web are lacking a bit in that department. Computing the multiplicative inverse to get <em>d</em> from <em>e</em> is a little tricky, but we will walk through it step-by-step.</p>
<p>First, a brief overview of RSA, for those not familiar with it already. A message <em>M</em> is encrypted by raising it to the power of <em>e</em> and then taking the result modulo some number <em>N</em>. To decrypt the message, you simply raise the value of the encrypted message <em>C</em> to the power of <em>d</em> and again mod by <em>N</em>. The beauty of RSA is that <em>e</em> and <em>N</em> can be published publicly. Together they, in fact, comprise the <strong>public key</strong>. The <strong>private key</strong>, which is not be published, is comprised of <em>d</em> and <em>N</em>.</p>
<p><span style="font-family:monospace">C = M<sup>e</sup> mod N <br/>M = C<sup>d</sup> mod N</span></p>
<p>If you&#8217;re like me, then you are astonished at 1) how simple this system is, and 2) that you can exponentiate messages twice (modulo some number) and leave the original message unaltered. The main question that my skeptical mind came up with when presented with this powerful encryption tool was, &#8220;wouldn&#8217;t it be easy to compute <em>d</em> if you have the values of <em>e</em> and <em>N</em>?&#8221; The answer is, of course, no. It turns out that it is very hard to do so. We shall see later that it is easy to compute <em>d</em> only when we have the factors of <em>N</em>. If we choose <em>N</em> to be arbitrarily large, factoring <em>N</em> can take an arbitrarily long period of time. Currently, there are no known polynomial-time algorithms which can perform this task. Factorization has, in fact, been shown to be in the set of problems known as <a href="http://en.wikipedia.org/wiki/NP_%28complexity%29">NP</a>. So the security of RSA is essentially provided by the hardness of the factorization problem. If someone figures out a way to factor large numbers fast, then RSA is out of business.</p>
<h3 class="center">Key Generation</h3>
<p>As was mentioned above, RSA&#8217;s security is rooted in the fact that <em>N</em> is hard to factor. Therefore, we should choose <em>N</em> to be the product of two large primes, <em>p</em> and <em>q</em>. For clarity in this example, we will choose relatively small values for <em>p</em> and <em>q</em>, but later we will discuss the proper choices for these coefficients given a desired level of security.</p>
<ol>
<li>For this example, let <em>P</em> = 647 and <em>Q</em> = 1871. This means that the modulus, <em>N</em> = 1210537. (Incidentally, factoring this value of <em>N</em> took 0.056 seconds on UCR&#8217;s mainframe).</li>
<li>Compute the <a href="http://en.wikipedia.org/wiki/Euler%27s_totient_function">totient</a> of <em>N</em>, &#966;(<em>N</em>) = (<em>P</em> &#8211; 1)(<em>Q</em> &#8211; 1) = 1208020.</li>
<li>Now we choose a number <em>e</em> which should be <a href="http://en.wikipedia.org/wiki/Coprime">coprime</a> to &#966;(<em>N</em>). The easiest way to do this is to simply choose a prime number. For this example, let <em>e</em> = 1127.</li>
<li>The next step is to compute <em>d</em> such that (<em>d * e</em>) mod &#966;(<em>N</em>) = 1. If this is confusing, that is okay. This property is important because it ensures that (<em>M</em><sup>e</sup>)<sup>d</sup> (mod <em>n</em>) = <em>M</em>. It may help to have a look at <a href="http://en.wikipedia.org/wiki/Euler%27s_theorem">Euler&#8217;s Theorem</a> if you are still confused.</li>
</ol>
<p>The best way to compute the multiplicative inverse, <em>d</em> from <em>e</em> and &#966;(<em>N</em>) is to use the <a href="http://en.wikipedia.org/wiki/Extended_Euclidean_algorithm">Extended Euclidean Algorithm</a>. Here is Euclid&#8217;s algorithm for our example:</p>
<table cellspacing="20">
<tr>
<td>1127</td>
<td>1208020</td>
<td>(1, 0)</td>
<td>(0, 1)</td>
<td rowspan="8" valign="top">We start with unit vectors (1, 0) and (0, 1) which correspond to the values of <em>e</em> and &#966;(<em>N</em>), respectively.<br/><br/>For each operation we perform on the left two columns, we perform the same operation on the right two columns.<br/><br/><br />
For example, in the first step, 1127 divides 1208020 1071 times and leaves a remainder of 1003. The corresponding operation in columns 3 and 4 is to subtract (1, 0) from (0, 1) 1071 times yielding (-1071, 1).<br/><br/><br />
The algorithm terminates when we have 1 and 0, not necessarilly in that order, in the first two columns. The value for <em>d</em> is in the column that corresponds to the 1 in the first two columns.<br/><br/><br />
<strong>*Note</strong>: it is worth mentioning that it is possible for the extended Euclidean algorithm to yield a negative result for <em>d</em>. Obviously, this is not a suitable decryption exponent because raising an integer to a negative number results in a fraction. The simple fix here is to mod the negative value of <em>d</em> by &#966;(<em>N</em>), giving us a positive value of <em>d</em> between 0 and &#966;(<em>N</em>).</td>
</tr>
<tr>
<td>1127</td>
<td>1003</td>
<td>(1, 0)</td>
<td>(-1071, 1)</td>
</tr>
<tr>
<td>124</td>
<td>1003</td>
<td>(1072, -1)</td>
<td>(-1071, 1)</td>
</tr>
<tr>
<td>124</td>
<td>11</td>
<td>(1072, -1)</td>
<td>(-9647, 9)</td>
</tr>
<tr>
<td>3</td>
<td>11</td>
<td>(107189, -100)</td>
<td>(-9647, 9)</td>
</tr>
<tr>
<td>3</td>
<td>2</td>
<td>(107189, -100)</td>
<td>(-331214, 309)</td>
</tr>
<tr>
<td>1</td>
<td>2</td>
<td>(438403, -409)</td>
<td>(-331214, 309)</td>
</tr>
<tr>
<td>1</td>
<td>0</td>
<td>(438403, -409)</td>
<td>(-1208020, 1127)</td>
</tr>
</table>
<p>From the above calculations we know that <em>d</em> = 438403. So we have both the public and private keys for this user:</p>
<pre>public key = (1127, 1210537)
private key = (438403, 1210537)</pre>
<p>To prove that this system works, observe the following computations. Let our message <em>M</em> = 247. The first step is to compute C = 247<sup>1127</sup> mod 1210537.</p>
<p><em>A brief aside:<br/></em>This exponentiation can be computed easily because we are using relatively small values for <em>e</em> and <em>d</em>. However, real world implementations of RSA often use 1024 bit encryption, meaning the exponent is 1024 bits long. That is roughly equivalent to a 300 decimal digit number. To compute an exponent of that order of magnitude in the conventional way, multiplying the base by itself <em>e</em> times would be prohibitively expensive. Even if we could compute 1 billion multiplications per second, the computation would take longer than the current <a href="http://en.wikipedia.org/wiki/Age_of_the_Universe">age of the universe</a>. So it is useful to use an alternative method like <a href="http://en.wikipedia.org/wiki/Exponentiation_by_squaring">exponentiation by squaring</a>. Here is a <a title="Python Exponentiation by Squaring" href="/files/power.txt">script</a> that computes large exponents fast. Another consideration is the storage of a very large number such as <em>C<sup>d</sup></em>. Rather than keeping the value in main memory as we exponentiate, we can simply keep the value modulo <em>N</em>. And now back to our example&#8230;</p>
<p>247<sup>1127</sup> mod 1210537 = 611545. This number was easily obtained with the Python interpreter in a fraction of a second. Raising this number, however to the value of <em>d</em>, 438403, should not be done the conventional way. On the school&#8217;s mainframe this calculation took 11 minutes, 23.65 seconds. This is a situation where we can see the power of divide-and-conquer algorithms. Using our recursive exponentiation function we show that 611545<sup>438403</sup> mod 1210537 = 247. Voil&aacute;, out pops our original message. Additionally, the exponentiation took only 31.16 seconds on the same machine with the repeated squaring method. This can be vastly improved, too, once we develop a non-recursive function. That will be critical when we want to provide real security via RSA and we don&#8217;t want to wait 10 minutes to decrypt the message.</p>
<p><em><a href="/posts/2005/06/pyrsa-rsa-in-python/">PyRSA</a> now available.</em></p>
]]></content:encoded>
			<wfw:commentRss>http://brandon.sternefamily.net/posts/2005/05/rsa-algorithm/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

