<?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>No One Is Perfect &#187; Mac</title>
	<atom:link href="http://watchitlater.com/blog/category/mac/feed/" rel="self" type="application/rss+xml" />
	<link>http://watchitlater.com/blog</link>
	<description>A reluctant foray into the world of blogging.</description>
	<lastBuildDate>Sun, 13 Jun 2010 03:35:03 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.9.2</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>Java and iPhone AES interoperability</title>
		<link>http://watchitlater.com/blog/2010/02/java-and-iphone-aes-interoperability/</link>
		<comments>http://watchitlater.com/blog/2010/02/java-and-iphone-aes-interoperability/#comments</comments>
		<pubDate>Mon, 08 Feb 2010 00:13:50 +0000</pubDate>
		<dc:creator>Tom</dc:creator>
				<category><![CDATA[Mac]]></category>
		<category><![CDATA[My Code]]></category>
		<category><![CDATA[aes]]></category>
		<category><![CDATA[bouncycastle]]></category>
		<category><![CDATA[cryptography]]></category>
		<category><![CDATA[iPhone]]></category>
		<category><![CDATA[Java]]></category>
		<category><![CDATA[jpasskeep]]></category>
		<category><![CDATA[objective-c]]></category>

		<guid isPermaLink="false">http://watchitlater.com/blog/?p=146</guid>
		<description><![CDATA[I&#8217;ve been trying to get my head around cryptography on the iPhone so that I can create a native iPhone app  (iPasskeep) that interoperates with my JPasskeep password keeper application. It has taken a while to get my head around CommonCrypto APIs &#8211; how to use them, how not to use them and their [...]]]></description>
			<content:encoded><![CDATA[<p>I&#8217;ve been trying to get my head around cryptography on the iPhone so that I can create a native iPhone app  (iPasskeep) that interoperates with my <a href="http://github.com/tomcz/jpasskeep">JPasskeep</a> password keeper application. It has taken a while to get my head around CommonCrypto APIs &#8211; how to use them, how not to use them and their limitations. It then took a bit of fiddling to find the right incantations in Java to get an interoperable cryptographic transformation.</p>
<p>Caveat: The following Objective-C code is not yet production ready or quality. It passes unit tests, but I haven&#8217;t checked it for memory leaks, performance, etc.</p>
<p>Hope this helps.</p>
<p><strong>Listing: Cipher.h</strong></p>
<pre name="code" class="java:nogutter">
#import &lt;Cocoa/Cocoa.h&gt;

#import &lt;CommonCrypto/CommonDigest.h&gt;
#import &lt;CommonCrypto/CommonCryptor.h&gt;

@interface Cipher : NSObject {
	NSString* cipherKey;
}

@property (retain) NSString* cipherKey;

- (Cipher *) initWithKey:(NSString *) key;

- (NSData *) encrypt:(NSData *) plainText;
- (NSData *) decrypt:(NSData *) cipherText;

- (NSData *) transform:(CCOperation) encryptOrDecrypt data:(NSData *) inputData;

+ (NSData *) md5:(NSString *) stringToHash;

@end
</pre>
<p><strong>Listing: Cipher.m</strong></p>
<pre name="code" class="cpp:nogutter">
#import &quot;Cipher.h&quot;

@implementation Cipher

@synthesize cipherKey;

- (Cipher *) initWithKey:(NSString *) key {
	self = [super init];
	if (self) {
		[self setCipherKey:key];
	}
	return self;
}

- (NSData *) encrypt:(NSData *) plainText {
	return [self transform:kCCEncrypt data:plainText];
}

- (NSData *) decrypt:(NSData *) cipherText {
	return [self transform:kCCDecrypt data:cipherText];
}

- (NSData *) transform:(CCOperation) encryptOrDecrypt data:(NSData *) inputData {

	// kCCKeySizeAES128 = 16 bytes
	// CC_MD5_DIGEST_LENGTH = 16 bytes
	NSData* secretKey = [Cipher md5:cipherKey];

	CCCryptorRef cryptor = NULL;
	CCCryptorStatus status = kCCSuccess;

	uint8_t iv[kCCBlockSizeAES128];
    memset((void *) iv, 0x0, (size_t) sizeof(iv));

	status = CCCryptorCreate(encryptOrDecrypt, kCCAlgorithmAES128, kCCOptionPKCS7Padding,
							 [secretKey bytes], kCCKeySizeAES128, iv, &amp;cryptor);

	if (status != kCCSuccess) {
		return nil;
	}

	size_t bufsize = CCCryptorGetOutputLength(cryptor, (size_t)[inputData length], true);

	void * buf = malloc(bufsize * sizeof(uint8_t));
	memset(buf, 0x0, bufsize);

	size_t bufused = 0;
    size_t bytesTotal = 0;

	status = CCCryptorUpdate(cryptor, [inputData bytes], (size_t)[inputData length],
							 buf, bufsize, &amp;bufused);

	if (status != kCCSuccess) {
		free(buf);
		CCCryptorRelease(cryptor);
		return nil;
	}

	bytesTotal += bufused;

	status = CCCryptorFinal(cryptor, buf + bufused, bufsize - bufused, &amp;bufused);

	if (status != kCCSuccess) {
		free(buf);
		CCCryptorRelease(cryptor);
		return nil;
	}

	bytesTotal += bufused;

	CCCryptorRelease(cryptor);

	return [NSData dataWithBytesNoCopy:buf length:bytesTotal];
}

+ (NSData *) md5:(NSString *) stringToHash {

	const char *src = [stringToHash UTF8String];

	unsigned char result[CC_MD5_DIGEST_LENGTH];

	CC_MD5(src, strlen(src), result);

	return [NSData dataWithBytes:result length:CC_MD5_DIGEST_LENGTH];
}

@end
</pre>
<p><strong>Listing: Cipher.java</strong></p>
<pre name="code" class="cpp:nogutter">
package com.tomczarniecki.iphone;

import org.apache.commons.codec.digest.DigestUtils;
import org.bouncycastle.crypto.BufferedBlockCipher;
import org.bouncycastle.crypto.engines.AESFastEngine;
import org.bouncycastle.crypto.modes.CBCBlockCipher;
import org.bouncycastle.crypto.paddings.PaddedBufferedBlockCipher;
import org.bouncycastle.crypto.params.KeyParameter;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;

public class Cipher {

    private final String password;

    public Cipher(String password) {
        this.password = password;
    }

    public byte[] encrypt(byte[] plainText) throws Exception {
        return transform(true, plainText);
    }

    public byte[] decrypt(byte[] cipherText) throws Exception {
        return transform(false, cipherText);
    }

    private byte[] transform(boolean encrypt, byte[] inputBytes) throws Exception {
        byte[] key = DigestUtils.md5(password.getBytes(&quot;UTF-8&quot;));

        BufferedBlockCipher cipher = new PaddedBufferedBlockCipher(new CBCBlockCipher(new AESFastEngine()));
        cipher.init(encrypt, new KeyParameter(key));

        ByteArrayInputStream input = new ByteArrayInputStream(inputBytes);
        ByteArrayOutputStream output = new ByteArrayOutputStream();

        int inputLen;
        int outputLen;

        byte[] inputBuffer = new byte[1024];
        byte[] outputBuffer = new byte[cipher.getOutputSize(inputBuffer.length)];

        while ((inputLen = input.read(inputBuffer)) &gt; -1) {
            outputLen = cipher.processBytes(inputBuffer, 0, inputLen, outputBuffer, 0);
            if (outputLen &gt; 0) {
                output.write(outputBuffer, 0, outputLen);
            }
        }

        outputLen = cipher.doFinal(outputBuffer, 0);
        if (outputLen &gt; 0) {
            output.write(outputBuffer, 0, outputLen);
        }

        return output.toByteArray();
    }
}
</pre>
]]></content:encoded>
			<wfw:commentRss>http://watchitlater.com/blog/2010/02/java-and-iphone-aes-interoperability/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>JPasskeep and Command-Q on Mac</title>
		<link>http://watchitlater.com/blog/2010/02/jpasskeep-and-command-q-on-mac/</link>
		<comments>http://watchitlater.com/blog/2010/02/jpasskeep-and-command-q-on-mac/#comments</comments>
		<pubDate>Sun, 07 Feb 2010 01:48:09 +0000</pubDate>
		<dc:creator>Tom</dc:creator>
				<category><![CDATA[Mac]]></category>
		<category><![CDATA[My Code]]></category>
		<category><![CDATA[command-q]]></category>
		<category><![CDATA[html]]></category>
		<category><![CDATA[Java]]></category>
		<category><![CDATA[javascript]]></category>
		<category><![CDATA[jpasskeep]]></category>
		<category><![CDATA[password]]></category>

		<guid isPermaLink="false">http://watchitlater.com/blog/?p=138</guid>
		<description><![CDATA[I&#8217;ve released a new version of my long-running password keeper application: JPasskeep. This new release is now able to handle a Command-Q keystroke on the Mac, giving a user (i.e. me) an chance to save any updated entries. No more mousing around to close a window.
The actual mechanism to do this was to reflectively call [...]]]></description>
			<content:encoded><![CDATA[<p>I&#8217;ve released a new version of my long-running password keeper application: JPasskeep. This new release is now able to handle a Command-Q keystroke on the Mac, giving a user (i.e. me) an chance to save any updated entries. No more mousing around to close a window.</p>
<p>The actual mechanism to do this was to reflectively call Apple&#8217;s EAWT application classes to allow me to register the correct event listener. Hmm, run anywhere with java GUI apps.</p>
<p>You can download the <a href="http://cloud.github.com/downloads/tomcz/jpasskeep/JPasskeep-20100207.zip">cross-platform</a> and <a href="http://cloud.github.com/downloads/tomcz/jpasskeep/JPasskeep-20100207.dmg">mac DMG</a> binaries from the project&#8217;s <a href="http://github.com/tomcz/jpasskeep">GitHub</a> repository.</p>
]]></content:encoded>
			<wfw:commentRss>http://watchitlater.com/blog/2010/02/jpasskeep-and-command-q-on-mac/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>Command-Tab and friends on Mac</title>
		<link>http://watchitlater.com/blog/2010/01/command-tab-and-friends-on-mac/</link>
		<comments>http://watchitlater.com/blog/2010/01/command-tab-and-friends-on-mac/#comments</comments>
		<pubDate>Sat, 02 Jan 2010 05:47:21 +0000</pubDate>
		<dc:creator>Tom</dc:creator>
				<category><![CDATA[Mac]]></category>
		<category><![CDATA[Reminders]]></category>
		<category><![CDATA[command]]></category>
		<category><![CDATA[key]]></category>
		<category><![CDATA[shortcut]]></category>
		<category><![CDATA[tab]]></category>
		<category><![CDATA[tilde]]></category>

		<guid isPermaLink="false">http://watchitlater.com/blog/?p=133</guid>
		<description><![CDATA[Most people who work with a Mac know Command-Tab to cycle through currently running applications, but few know of Command-~ (tilde): it allows you to cycle through all the windows of the current application. No more mucking around with F10.
]]></description>
			<content:encoded><![CDATA[<p>Most people who work with a Mac know Command-Tab to cycle through currently running applications, but few know of Command-~ (tilde): it allows you to cycle through all the windows of the current application. No more mucking around with F10.</p>
]]></content:encoded>
			<wfw:commentRss>http://watchitlater.com/blog/2010/01/command-tab-and-friends-on-mac/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
	</channel>
</rss>
