public boolean authenticateOwnerPassword(String ownerPassword) {
        // Step 1: Computer an encryption key from the supplied password string,
        // as described in steps 1 to 4 of algorithm 3.3.
        byte[] encryptionKey = calculateOwnerPassword(ownerPassword,
                "", true);

        // Step 2: start decryption of O
        byte[] decryptedO = null;
        try {
            // get bigO value
            byte[] bigO = Utils.convertByteCharSequenceToByteArray(
                    encryptionDictionary.getBigO());
            if (encryptionDictionary.getRevisionNumber() == 2) {
                // Step 2 (R == 2):  decrypt the value of the encryption dictionary
                // O entry, using an RC4 encryption function with the encryption
                // key computed in step 1.

                // Use above as key for the RC4 encryption function.
                SecretKeySpec key = new SecretKeySpec(encryptionKey, "RC4");
                Cipher rc4 = Cipher.getInstance("RC4");
                rc4.init(Cipher.DECRYPT_MODE, key);
                decryptedO = rc4.doFinal(bigO);
            }
            // Step 2 (R >= 3): Do the following 19 times: Take the output from the previous
            // invocation of the RC4 function and pass it as input to a new
            // invocation of the function; use an encryption key generated by taking
            // each byte of the encryption key in step 4 and performing an XOR
            // operation between that byte and the single-byte value of the
            // iteration counter
            else {//if (encryptionDictionary.getRevisionNumber() >= 3){
                // key to be made on each interaction
                byte[] indexedKey = new byte[encryptionKey.length];

                decryptedO = bigO;
                // start the 19->0? interactions
                for (int i = 19; i >= 0; i--) {

                    // build new key for each i xor on each byte
                    for (int j = 0; j < indexedKey.length; j++) {
                        indexedKey[j] = (byte) (encryptionKey[j] ^ (byte) i);
                    }
                    // create new key and init rc4
                    SecretKeySpec key = new SecretKeySpec(indexedKey, "RC4");
                    Cipher rc4 = Cipher.getInstance("RC4");
                    rc4.init(Cipher.ENCRYPT_MODE, key);
                    // encrypt the old data with the new key
                    decryptedO = rc4.update(decryptedO);
                }
            }

        } catch (NoSuchAlgorithmException ex) {
            logger.log(Level.FINE, "NoSuchAlgorithmException.", ex);
        } catch (IllegalBlockSizeException ex) {
            logger.log(Level.FINE, "IllegalBlockSizeException.", ex);
        } catch (BadPaddingException ex) {
            logger.log(Level.FINE, "BadPaddingException.", ex);
        } catch (NoSuchPaddingException ex) {
            logger.log(Level.FINE, "NoSuchPaddingException.", ex);
        } catch (InvalidKeyException ex) {
            logger.log(Level.FINE, "InvalidKeyException.", ex);
        }
        // Step 3: The result of step 2 purports to be the user password.
        // Authenticate this user password using Algorithm 3.6.  If it is found
        // to be correct, the password supplied is the correct owner password.

        String tmpUserPassword = Utils.convertByteArrayToByteString(decryptedO);
        //System.out.println("tmp user password " + tmpUserPassword);
        boolean isValid = authenticateUserPassword(tmpUserPassword);

        if (isValid) {
            userPassword = tmpUserPassword;
            this.ownerPassword = ownerPassword;
            // setup permissions if valid
        }

        return isValid;
    }