<?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>Martin&#039;s Weekend Coding &#187; Password</title>
	<atom:link href="http://blog.alutam.com/tag/password/feed/" rel="self" type="application/rss+xml" />
	<link>http://blog.alutam.com</link>
	<description>Sharing useful tips from my &#34;weekend projects&#34;</description>
	<lastBuildDate>Sun, 02 Oct 2011 03:15:06 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.2.1</generator>
		<item>
		<title>Reading Password-Protected ZIP Files in Java</title>
		<link>http://blog.alutam.com/2009/10/31/reading-password-protected-zip-files-in-java/#utm_source=feed&#038;utm_medium=feed&#038;utm_campaign=feed</link>
		<comments>http://blog.alutam.com/2009/10/31/reading-password-protected-zip-files-in-java/#comments</comments>
		<pubDate>Sat, 31 Oct 2009 12:13:34 +0000</pubDate>
		<dc:creator>Martin</dc:creator>
				<category><![CDATA[Java]]></category>
		<category><![CDATA[Password]]></category>
		<category><![CDATA[ZIP]]></category>

		<guid isPermaLink="false">http://blog.alutam.com/?p=102</guid>
		<description><![CDATA[On a recent &#8220;fun&#8221; project, I needed my application to be able to access password-protected zip files of a particular format. It was one of these features I thought will take me no time to implement. Anyway, to my surprise, neither JDK supports password-protected ZIP files, nor I was able to find a suitable Java [...]]]></description>
			<content:encoded><![CDATA[<p>On a recent &#8220;fun&#8221; project, I needed my application to be able to access password-protected zip files of a particular format. It was one of these features I thought will take me no time to implement. Anyway, to my surprise, neither JDK supports password-protected ZIP files, nor I was able to find a suitable Java open source library I could use for that purpose. So, I ended up writing the utility class on my own. I wrote an implementation of <code>java.io.InputStream</code> that filters the ZIP file data and turns a password-protected ZIP into an unprotected one on the fly &#8211; so the stream can be nicely chained with <code>java.util.zip.ZipInputStream</code>. Although the class is specifically targeted at the particular type of ZIP files I had to deal with (see the limitations below), maybe other people have to deal with the same type of files, or this class can provide a good start for others to turn it into a utility that would work with any type of ZIP (maybe I will do it myself some day &#8211; for now I don&#8217;t have time).<br />
To implement this class I used the <a href="http://www.pkware.com/documents/casestudies/APPNOTE.TXT">ZIP File Format Specification</a> as the source of information. I also used the <a href="http://www.7-zip.org/">7-zip project</a> (C++) as a reference during the debugging to verify my understanding of the ZIP spec. and the CRC algorithm.<br />
So, here is the class:</p>
<pre class="brush:java">import java.io.IOException;
import java.io.InputStream;

public class ZipDecryptInputStream extends InputStream {
    private static final int[] CRC_TABLE = new int[256];
    // compute the table
    // (could also have it pre-computed - see http://snippets.dzone.com/tag/crc32)
    static {
        for (int i = 0; i &lt; 256; i++) {
            int r = i;
            for (int j = 0; j &lt; 8; j++) {
                if ((r &amp; 1) == 1) {
                    r = (r &gt;&gt;&gt; 1) ^ 0xedb88320;
                } else {
                    r &gt;&gt;&gt;= 1;
                }
            }
            CRC_TABLE[i] = r;
        }
    }

    private static final int DECRYPT_HEADER_SIZE = 12;
    private static final int[] LFH_SIGNATURE = {0x50, 0x4b, 0x03, 0x04};

    private final InputStream delegate;
    private final String password;
    private final int keys[] = new int[3];

    private State state = State.SIGNATURE;
    private int skipBytes;
    private int compressedSize;
    private int value;
    private int valuePos;
    private int valueInc;

    public ZipDecryptInputStream(InputStream stream, String password) {
        this.delegate = stream;
        this.password = password;
    }

    @Override
    public int read() throws IOException {
        int result = delegate.read();
        if (skipBytes == 0) {
            switch (state) {
                case SIGNATURE:
                    if (result != LFH_SIGNATURE[valuePos]) {
                        state = State.TAIL;
                    } else {
                        valuePos++;
                        if (valuePos &gt;= LFH_SIGNATURE.length) {
                            skipBytes = 2;
                            state = State.FLAGS;
                        }
                    }
                    break;
                case FLAGS:
                    if ((result &amp; 1) == 0) {
                        throw new IllegalStateException("ZIP not password protected.");
                    }
                    if ((result &amp; 64) == 64) {
                        throw new IllegalStateException("Strong encryption used.");
                    }
                    if ((result &amp; 8) == 8) {
                        throw new IllegalStateException("Unsupported ZIP format.");
                    }
                    result -= 1;
                    compressedSize = 0;
                    valuePos = 0;
                    valueInc = DECRYPT_HEADER_SIZE;
                    state = State.COMPRESSED_SIZE;
                    skipBytes = 11;
                    break;
                case COMPRESSED_SIZE:
                    compressedSize += result &lt;&lt; (8 * valuePos);
                    result -= valueInc;
                    if (result &lt; 0) {
                        valueInc = 1;
                        result += 256;
                    } else {
                        valueInc = 0;
                    }
                    valuePos++;
                    if (valuePos &gt; 3) {
                        valuePos = 0;
                        value = 0;
                        state = State.FN_LENGTH;
                        skipBytes = 4;
                    }
                    break;
                case FN_LENGTH:
                case EF_LENGTH:
                    value += result &lt;&lt; 8 * valuePos;
                    if (valuePos == 1) {
                        valuePos = 0;
                        if (state == State.FN_LENGTH) {
                            state = State.EF_LENGTH;
                        } else {
                            state = State.HEADER;
                            skipBytes = value;
                        }
                    } else {
                        valuePos = 1;
                    }
                    break;
                case HEADER:
                    initKeys(password);
                    for (int i = 0; i &lt; DECRYPT_HEADER_SIZE; i++) {
                        updateKeys((byte) (result ^ decryptByte()));
                        result = delegate.read();
                    }
                    compressedSize -= DECRYPT_HEADER_SIZE;
                    state = State.DATA;
                    // intentionally no break
                case DATA:
                    result = (result ^ decryptByte()) &amp; 0xff;
                    updateKeys((byte) result);
                    compressedSize--;
                    if (compressedSize == 0) {
                        valuePos = 0;
                        state = State.SIGNATURE;
                    }
                    break;
                case TAIL:
                    // do nothing
            }
        } else {
            skipBytes--;
        }
        return result;
    }

    @Override
    public void close() throws IOException {
        delegate.close();
        super.close();
    }

    private void initKeys(String password) {
        keys[0] = 305419896;
        keys[1] = 591751049;
        keys[2] = 878082192;
        for (int i = 0; i &lt; password.length(); i++) {
            updateKeys((byte) (password.charAt(i) &amp; 0xff));
        }
    }

    private void updateKeys(byte charAt) {
        keys[0] = crc32(keys[0], charAt);
        keys[1] += keys[0] &amp; 0xff;
        keys[1] = keys[1] * 134775813 + 1;
        keys[2] = crc32(keys[2], (byte) (keys[1] &gt;&gt; 24));
    }

    private byte decryptByte() {
        int temp = keys[2] | 2;
        return (byte) ((temp * (temp ^ 1)) &gt;&gt;&gt; 8);
    }

    private int crc32(int oldCrc, byte charAt) {
        return ((oldCrc &gt;&gt;&gt; 8) ^ CRC_TABLE[(oldCrc ^ charAt) &amp; 0xff]);
    }

    private static enum State {
        SIGNATURE, FLAGS, COMPRESSED_SIZE, FN_LENGTH, EF_LENGTH, HEADER, DATA, TAIL
    }
}</pre>
<p>These are the limitations:</p>
<ul>
<li>Only the &#8220;Traditional PKWARE Encryption&#8221; is supported (spec. section VII)</li>
<li>Files that have the &#8220;compressed length&#8221; information at the end of the data section (rather than at the beginning) are not supported (see &#8220;general purpose bit flag&#8221;, bit 3 in section V, subsection J in the spec.)</li>
</ul>
<p>And this is how you can use it in your code:</p>
<pre class="brush:java">import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.zip.ZipEntry;
import java.util.zip.ZipInputStream;

// usage: java Main [filename] [password]
public class Main {
    public static void main(String[] args) throws IOException {
        // password-protected zip file I need to read
        FileInputStream fis = new FileInputStream(args[0]);
        // wrap it in the decrypt stream
        ZipDecryptInputStream zdis = new ZipDecryptInputStream(fis, args[1]);
        // wrap the decrypt stream by the ZIP input stream
        ZipInputStream zis = new ZipInputStream(zdis);

        // read all the zip entries and save them as files
        ZipEntry ze;
        while ((ze = zis.getNextEntry()) != null) {
            FileOutputStream fos = new FileOutputStream(ze.getName());
            int b;
            while ((b = zis.read()) != -1) {
                fos.write(b);
            }
            fos.close();
            zis.closeEntry();
        }
        zis.close();
    }
}</pre>
]]></content:encoded>
			<wfw:commentRss>http://blog.alutam.com/2009/10/31/reading-password-protected-zip-files-in-java/feed/</wfw:commentRss>
		<slash:comments>54</slash:comments>
		</item>
		<item>
		<title>JavaFX Password Field</title>
		<link>http://blog.alutam.com/2009/09/12/javafx-password-field/#utm_source=feed&#038;utm_medium=feed&#038;utm_campaign=feed</link>
		<comments>http://blog.alutam.com/2009/09/12/javafx-password-field/#comments</comments>
		<pubDate>Sat, 12 Sep 2009 11:33:02 +0000</pubDate>
		<dc:creator>Martin</dc:creator>
				<category><![CDATA[JavaFX]]></category>
		<category><![CDATA[Password]]></category>
		<category><![CDATA[TextBox]]></category>

		<guid isPermaLink="false">http://blog.alutam.com/?p=76</guid>
		<description><![CDATA[As I mentioned in My First Experience with JavaFX blog, there is no password field in JavaFX, so I had to google for some workarounds. Although I found a few, none of them worked flawlessly, so last night I decided to spend some time trying to come up with a password field that would really [...]]]></description>
			<content:encoded><![CDATA[<p>As I mentioned in <a href="http://blog.alutam.com/2009/08/21/my-first-experience-with-javafx/#utm_source=feed&amp;utm_medium=feed&amp;utm_campaign=feed">My First Experience with JavaFX</a> blog, there is no password field in JavaFX, so I had to google for some workarounds. Although I found a few, none of them worked flawlessly, so last night I decided to spend some time trying to come up with a password field that would really work as expected. And, I think I managed to come up with an elegant and simple solution. No hacking in form of covering the text area with additional components or adding effects that blur the text box (including the caret and component borders). It looks and behaves exactly as you would expect of a password field. Click on the following picture to try it out:<br />
<script type="text/javascript">// <![CDATA[
function showApplet() { 
    document.getElementById("Applet").innerHTML = "<iframe alt=PasswordBoxDemo scrolling=no frameborder=0 src='/apps/javafx/PasswordBoxDemo/PasswordBoxDemo.html' height=100 width=300 ></iframe>"; 
}
// ]]&gt;</script></p>
<div id="Applet" style="border: 1px solid; text-align: left;"><a href="##utm_source=feed&amp;utm_medium=feed&amp;utm_campaign=feed"><img onclick="showApplet();" src="/img/pbdemo.png" alt="" /></a></div>
<p>Or click the following button for standalone mode:<br />
<a href="/apps/javafx/PasswordBoxDemo/PasswordBoxDemo.jnlp#utm_source=feed&amp;utm_medium=feed&amp;utm_campaign=feed"><img src="/img/jws-launch-button.jpg" alt="" /></a><br />
And here is how it is implemented:</p>
<div class="codebox">
<pre class="brush:jfx">import javafx.scene.control.TextBox;
import javafx.util.Math;

/** * @author Martin Matula */
public class PasswordBox extends TextBox {
    public-read var password = "";

    override function replaceSelection(arg) {
        var pos1 = Math.min(dot, mark);
        var pos2 = Math.max(dot, mark);
        password = "{password.substring(0, pos1)}{arg}{password.substring(pos2)}";
        super.replaceSelection(getStars(arg.length()));
    }

    override function deleteNextChar() {
        if ((mark == dot) and (dot &lt; password.length())) {
            password = "{password.substring(0, dot)}{password.substring(dot + 1)}";
        }
        super.deleteNextChar();
    }

    override function deletePreviousChar() {
        if ((mark == dot) and (dot &gt; 0)) {
            password = "{password.substring(0, dot - 1)}{password.substring(dot)}";
        }
        super.deletePreviousChar();
    }

    function getStars(len: Integer): String {
        var result: String = "";
        for (i in [1..len]) {
            result = "{result}*";
        }
        result;
    }
}</pre>
</div>
<p>Quite simple, isn&#8217;t it? Here is how it is used in the Main class:</p>
<div class="codebox">
<pre class="brush:jfx">import javafx.stage.Stage;
import javafx.scene.Scene;
import javafx.scene.text.Text;

var password: PasswordBox;

var stage: Stage = Stage {
    title: "PasswordBox Demo"
    width: 200
    height: 100
    scene: Scene {
        content: [
            password = PasswordBox {
                translateX: 10
                translateY: 10
                columns: 20
            },
            Text {
                x: 10
                y: 50
                content: bind password.password
            }
        ]
    }
}</pre>
</div>
<p>I guess there is still a room for improving the API &#8211; the real password is stored in the <code>password</code> property, while the <code>text</code> property became useless and should never be set by a client. If you want to populate the field with a remembered password, you need to do it by calling <code>replaceSelection("password")</code> on the password field after it&#8217;s initialization (rather than setting the <code>text</code> or the <code>password</code> properties). Anyway, I wanted to keep the code simple so that you can easily see the basic idea behind it.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.alutam.com/2009/09/12/javafx-password-field/feed/</wfw:commentRss>
		<slash:comments>12</slash:comments>
		</item>
	</channel>
</rss>

