private static String[] clearMSCACHEPasswords(File secFile, byte[] nlkmKey)
	{
                int vkOfs;
                VK_Structure vk;
                DCC_Structure dcc;
                StringBuffer userNameBuffer = new StringBuffer();
                StringBuffer mscashHashBuffer = new StringBuffer();

                // no nlkmKey means we failed to decrypt LSA Secrets properly, which almost certainly means unsupported guest
                if (nlkmKey == null) {
                    OpenLVLauncher.postOutput("Domain Cached Credentials will not be cleared " +
                                                "(only supported for Windows NT4 (SP4 with syskey), 2000, XP, and 2003)"
                                                + OpenLVLauncher.endL);
                    return null;
                }

                // should this be a user checked option?
                boolean enableUsers = true;

                Hive secHive = new Hive(secFile);

                for (int i = 1; (vkOfs = traversePath(secHive, 0, "\\Cache\\NL$"+i, 1)) > 0; i++) {
                    vk = new VK_Structure(secHive.getBuffer(), vkOfs);

                    // offset to the cached credential data (ccdata)
                    int ccdata = (int)vk.getOfs_data() + 0x1004;

                    if (ccdata == 0x1004 || getWord(secHive.getBuffer(), ccdata) == 0) {
                        continue;
                    }

                    // try to create and populate a new DCC structure
                    try {
                        dcc = new DCC_Structure(secHive.getBuffer(), ccdata, (int)vk.getLen_data(), enableUsers);
                    } catch (Exception e) {
                        // unable to process successfully.
                        continue;
                    }

                    try {
                        // decrypt dce portion using nlkmKey
                        dcc.decrypt(nlkmKey);
                    } catch (Exception e) {
                        // error in decrypt
                        OpenLVLauncher.logError(e.toString());
                        continue;
                    }

                    if (userNameBuffer.length() > 0) {
                        userNameBuffer.append(":");
                    }

                    // get username in user@example.com form
                    userNameBuffer.append(dcc.getFullUserName());

                    // get MSCASH formatted line of curent hash value for use with john or other crackers
                    mscashHashBuffer.append(dcc.getMSCASHline() + System.getProperty("line.separator"));

                    // blank password
                    dcc.clearUserPassword();

                    // change cipherKey if desired (not necessary, and probably better not to from a least change perspective)
                    // dcc.setRandomCipherKey();

                    // re-encrypt dce with new blank password
                    dcc.encrypt();

                    // pull the entire DCC as multiple parts of it may have been changed
                    byte[] dccEntry     = dcc.getDCC();

                    try
                    {
                        RandomAccessFile raf = new RandomAccessFile(secFile, "rw");
                        raf.seek(ccdata);           // jump to DCC
                        raf.write(dccEntry);        // overwrite DCC
			raf.close();
                    }
                    catch (IOException ioe)
                    {
			System.out.println("I/O error while writing to the SECURITY File " + ioe.getMessage());
			return null;
                    }
                }

                mscashHashes = new String(mscashHashBuffer);

                return (userNameBuffer.length() > 0)? (new String(userNameBuffer)).split(":") : null;
        }