Crud, you know what the problem is? Bytes in java are signed, so if
the SHA1 MessageDigest gives a character from 0x80 to 0xFF, then java
will pass that along OK but here:
encodedData[encodedIndex] = lookUpBase64Alphabet[b1 >> 2];
and all similar places it will be treated as a negative number, i.e. a
negative index into the array, and it will blow up.
I think these things need to be cast to integers to work correctly ...
or don't use [] but instead make a small private static function to do
the lookup and do the conversion there.
Just a theory.
On Thu, Jun 10, 2010 at 5:16 PM, Christopher Piggott <cpiggott_at_gmail.com> wrote:
> I have some passwords stored in what's essentially the apache
> .htpasswd file format, if you use SHA hashes.. the format is something
> like:
>
> user:{SHA}W6ph5Mm5Pz8GgiULbPgzG37mj9g=
>
> I thought that, as long as the class com.sun.jersey.core.util.Base64
> was there, I would use it. But, it bombs.
>
> public boolean check(String actual, String given) {
> /* MessageDigest md = MessageDigest.getInstance("SHA1");
> // was created earlier */
>
> md.reset();
> byte[] digest = md.digest(given.getBytes());
> String encoded = "{SHA}" + new String(Base64.encode(digest));
> return encoded.equals(actual);
> }
>
>
> digest is an array of 20 bytes (tested this, it works).
> Base64.encode() crashes with:
>
> java.lang.ArrayIndexOutOfBoundsException: -6
> at com.sun.jersey.core.util.Base64.encode(Base64.java:181)
>
> which corresponds Base64.java:
>
> encodedData[encodedIndex + 1] = lookUpBase64Alphabet[(b2 >> 4) |
> (k << 4)];
>
> Wondering ... should I not depend on this? (Previously was using
> org.apache.commons.ssl.Base64 but I don't need apache commons ssl any
> more).
>
> --C
>