dbuser/src/test/java/no/kantega/security/api/impl/dbuser/password/CopyOfMD5Crypt.java
/**
     * Linux/BSD MD5Crypt function
     * @return The encrypted password as an MD5 hash
     * @param magic $1$ for Linux/BSB, $apr1$ for Apache crypt
     * @param salt 8 byte permutation string
     * @param password user password
     */
Linux/BSD MD5Crypt function
@return The encrypted password as an MD5 hash
@param magic $1$ for Linux/BSB, $apr1$ for Apache crypt
@param salt 8 byte permutation string
@param password user password
Linux / BSD MD5Crypt function @return The encrypted password as an MD5 hash @param magic $1$ for Linux / BSB $apr1$ for Apache crypt @param salt 8 byte permutation string @param password user password
static public final String crypt( String password, String salt, String magic ) throws NoSuchAlgorithmException {
        byte finalState[];
        long l;
        /**
         * Two MD5 hashes are used
         */
        MessageDigest ctx, ctx1;
        ctx = MessageDigest.getInstance( "md5" );
        ctx1 = MessageDigest.getInstance( "md5" );
        /* Refine the Salt first */
        /* If it starts with the magic string, then skip that */
        if ( salt.startsWith( magic ) )
        {
            salt = salt.substring( magic.length() );
        }
        /* It stops at the first '$', max 8 chars */
        if ( salt.indexOf( '$' ) != -1 )
        {
            salt = salt.substring( 0, salt.indexOf( '$' ) );
        }
        if ( salt.length() > 8 )
        {
            salt = salt.substring( 0, 8 );
        }
        /**
         * Transformation set #1:
         * The password first, since that is what is most unknown
         * Magic string
         * Raw salt
         */
        ctx.update( password.getBytes() );
        ctx.update( magic.getBytes() );
        ctx.update( salt.getBytes() );
        /* Then just as many characters of the MD5(pw,salt,pw) */
        ctx1.update( password.getBytes() );
        ctx1.update( salt.getBytes() );
        ctx1.update( password.getBytes() );
        finalState = ctx1.digest(); 
        for ( int pl = password.length(); pl > 0; pl -= 16 )
        {
            ctx.update( finalState, 0, pl > 16 ? 16 : pl );
        }
        /** the original code claimed that finalState was being cleared
         to keep dangerous bits out of memory,
         but doing this is also required in order to get the right output. */
        clearbits( finalState );
        /* Then something really weird... */
        for ( int i = password.length(); i != 0; i >>>= 1 )
        {
            if ( ( i & 1 ) != 0 )
            {
                ctx.update( finalState, 0, 1 );
            }
            else
            {
                ctx.update( password.getBytes(), 0, 1 );
            }
        }
        finalState = ctx.digest();
        /** and now, just to make sure things don't run too fast
         * On a 60 Mhz Pentium this takes 34 msec, so you would
         * need 30 seconds to build a 1000 entry dictionary...
         * (The above timings from the C version)
         */
        for ( int i = 0; i < 1000; i++ )
        {
            try {
                ctx1 = MessageDigest.getInstance( "md5" );
            }
            catch (NoSuchAlgorithmException e0 ) { return null;}
            if ( ( i & 1 ) != 0 )
            {
                ctx1.update( password.getBytes() );
            }
            else
            {
                ctx1.update( finalState, 0, 16 );
            }
            if ( ( i % 3 ) != 0 )
            {
                ctx1.update( salt.getBytes() );
            }
            if ( ( i % 7 ) != 0 )
            {
                ctx1.update( password.getBytes() );
            }
            if ( ( i & 1 ) != 0 )
            {
                ctx1.update( finalState, 0, 16 );
            }
            else
            {
                ctx1.update( password.getBytes() );
            }
            finalState = ctx1.digest(); 
        }
        /* Now make the output string */
        StringBuffer result = new StringBuffer();
        result.append( magic );
        result.append( salt );
        result.append( "$" );
        /**
         * Build a 22 byte output string from the set: A-Za-z0-9./
         */
        l = ( bytes2u( finalState[0] ) << 16 )
                | ( bytes2u( finalState[6] ) << 8 ) | bytes2u( finalState[12] );
        result.append( to64( l, 4 ) );
        l = ( bytes2u( finalState[1] ) << 16 )
                | ( bytes2u( finalState[7] ) << 8 ) | bytes2u( finalState[13] );
        result.append( to64( l, 4 ) );
        l = ( bytes2u( finalState[2] ) << 16 )
                | ( bytes2u( finalState[8] ) << 8 ) | bytes2u( finalState[14] );
        result.append( to64( l, 4 ) );
        l = ( bytes2u( finalState[3] ) << 16 )
                | ( bytes2u( finalState[9] ) << 8 ) | bytes2u( finalState[15] );
        result.append( to64( l, 4 ) );
        l = ( bytes2u( finalState[4] ) << 16 )
                | ( bytes2u( finalState[10] ) << 8 ) | bytes2u( finalState[5] );
        result.append( to64( l, 4 ) );
        l = bytes2u( finalState[11] );
        result.append( to64( l, 2 ) );
        /* Don't leave anything around in vm they could use. */
        clearbits( finalState );
        return result.toString();
    }
static public final String crypt ( String password , String salt , String magic ) throws NoSuchAlgorithmException { byte finalState [ ] ; long l ; /**
         * Two MD5 hashes are used
         */ MessageDigest ctx , ctx1 ; ctx = MessageDigest . getInstance ( "md5" ) ; ctx1 = MessageDigest . getInstance ( "md5" ) ; /* Refine the Salt first */ /* If it starts with the magic string, then skip that */ if ( salt . startsWith ( magic ) ) { salt = salt . substring ( magic . length ( ) ) ; } /* It stops at the first '$', max 8 chars */ if ( salt . indexOf ( '$' ) != - 1 ) { salt = salt . substring ( 0 , salt . indexOf ( '$' ) ) ; } if ( salt . length ( ) > 8 ) { salt = salt . substring ( 0 , 8 ) ; } /**
         * Transformation set #1:
         * The password first, since that is what is most unknown
         * Magic string
         * Raw salt
         */ ctx . update ( password . getBytes ( ) ) ; ctx . update ( magic . getBytes ( ) ) ; ctx . update ( salt . getBytes ( ) ) ; /* Then just as many characters of the MD5(pw,salt,pw) */ ctx1 . update ( password . getBytes ( ) ) ; ctx1 . update ( salt . getBytes ( ) ) ; ctx1 . update ( password . getBytes ( ) ) ; finalState = ctx1 . digest ( ) ; for ( int pl = password . length ( ) ; pl > 0 ; pl -= 16 ) { ctx . update ( finalState , 0 , pl > 16 ? 16 : pl ) ; } /** the original code claimed that finalState was being cleared
         to keep dangerous bits out of memory,
         but doing this is also required in order to get the right output. */ clearbits ( finalState ) ; /* Then something really weird... */ for ( int i = password . length ( ) ; i != 0 ; i >>>= 1 ) { if ( ( i & 1 ) != 0 ) { ctx . update ( finalState , 0 , 1 ) ; } else { ctx . update ( password . getBytes ( ) , 0 , 1 ) ; } } finalState = ctx . digest ( ) ; /** and now, just to make sure things don't run too fast
         * On a 60 Mhz Pentium this takes 34 msec, so you would
         * need 30 seconds to build a 1000 entry dictionary...
         * (The above timings from the C version)
         */ for ( int i = 0 ; i < 1000 ; i ++ ) { try { ctx1 = MessageDigest . getInstance ( "md5" ) ; } catch ( NoSuchAlgorithmException e0 ) { return null ; } if ( ( i & 1 ) != 0 ) { ctx1 . update ( password . getBytes ( ) ) ; } else { ctx1 . update ( finalState , 0 , 16 ) ; } if ( ( i % 3 ) != 0 ) { ctx1 . update ( salt . getBytes ( ) ) ; } if ( ( i % 7 ) != 0 ) { ctx1 . update ( password . getBytes ( ) ) ; } if ( ( i & 1 ) != 0 ) { ctx1 . update ( finalState , 0 , 16 ) ; } else { ctx1 . update ( password . getBytes ( ) ) ; } finalState = ctx1 . digest ( ) ; } /* Now make the output string */ StringBuffer result = new StringBuffer ( ) ; result . append ( magic ) ; result . append ( salt ) ; result . append ( "$" ) ; /**
         * Build a 22 byte output string from the set: A-Za-z0-9./
         */ l = ( bytes2u ( finalState [ 0 ] ) << 16 ) | ( bytes2u ( finalState [ 6 ] ) << 8 ) | bytes2u ( finalState [ 12 ] ) ; result . append ( to64 ( l , 4 ) ) ; l = ( bytes2u ( finalState [ 1 ] ) << 16 ) | ( bytes2u ( finalState [ 7 ] ) << 8 ) | bytes2u ( finalState [ 13 ] ) ; result . append ( to64 ( l , 4 ) ) ; l = ( bytes2u ( finalState [ 2 ] ) << 16 ) | ( bytes2u ( finalState [ 8 ] ) << 8 ) | bytes2u ( finalState [ 14 ] ) ; result . append ( to64 ( l , 4 ) ) ; l = ( bytes2u ( finalState [ 3 ] ) << 16 ) | ( bytes2u ( finalState [ 9 ] ) << 8 ) | bytes2u ( finalState [ 15 ] ) ; result . append ( to64 ( l , 4 ) ) ; l = ( bytes2u ( finalState [ 4 ] ) << 16 ) | ( bytes2u ( finalState [ 10 ] ) << 8 ) | bytes2u ( finalState [ 5 ] ) ; result . append ( to64 ( l , 4 ) ) ; l = bytes2u ( finalState [ 11 ] ) ; result . append ( to64 ( l , 2 ) ) ; /* Don't leave anything around in vm they could use. */ clearbits ( finalState ) ; return result . toString ( ) ; }
Linux/BSD MD5Crypt function
 @return The encrypted password as an MD5 hash
 @param magic $1$ for Linux/BSB, $apr1$ for Apache crypt
 @param salt 8 byte permutation string
 @param password user password
Linux / BSD MD5Crypt function @return The encrypted password as an MD5 hash @param magic $1$ for Linux / BSB $apr1$ for Apache crypt @param salt 8 byte permutation string @param password user password
// ctx1.Final(); // Final();