users@jersey.java.net

Re: Base64.encode() ok to use?

From: Christopher Piggott <cpiggott_at_gmail.com>
Date: Thu, 10 Jun 2010 17:22:24 -0400

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
>