⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 importerv3.java

📁 KeePass for J2ME is a J2ME port of KeePass Password Safe, a free, open source, light-weight and easy
💻 JAVA
📖 第 1 页 / 共 2 页
字号:
/*KeePass for J2MECopyright 2007 Naomaru Itoi <nao@phoneid.org>This file was derived from Java clone of KeePass - A KeePass file viewer for JavaCopyright 2006 Bill Zwicky <billzwicky@users.sourceforge.net>This program is free software; you can redistribute it and/or modifyit under the terms of the GNU General Public License as published bythe Free Software Foundation; version 2This program is distributed in the hope that it will be useful,but WITHOUT ANY WARRANTY; without even the implied warranty ofMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See theGNU General Public License for more details.You should have received a copy of the GNU General Public Licensealong with this program; if not, write to the Free SoftwareFoundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA*/package org.phoneid.keepassj2me;// PhoneIDimport org.phoneid.*;// Javaimport java.io.InputStream;import java.io.IOException;import java.util.Vector;import java.util.Enumeration;import java.lang.RuntimeException;import java.io.UnsupportedEncodingException;import javax.microedition.io.*;import javax.microedition.lcdui.*;// Bouncy Castleimport org.bouncycastle1.util.encoders.Hex;import org.bouncycastle1.crypto.*;import org.bouncycastle1.crypto.generators.*;import org.bouncycastle1.crypto.digests.*;import org.bouncycastle1.crypto.params.*;import org.bouncycastle1.crypto.paddings.*;import org.bouncycastle1.crypto.modes.*;import org.bouncycastle1.crypto.engines.*;import org.bouncycastle1.util.*;import org.bouncycastle1.util.encoders.*;/** * Load a v3 database file. * * @author Naomaru Itoi <nao@phoneid.org> * @author Bill Zwicky <wrzwicky@pobox.com> */public class ImporterV3 {    // Platform platform = new JavaPlatform();    Form mForm;      public ImporterV3() {      super();      mForm = null;    }    /**     * Constructor which takes form for debugging     */    public ImporterV3(Form form) {      super();      mForm = form;  }  /**   * Load a v3 database file, return contents in a new PwManager.   *    * @param infile  Existing file to load.   * @param password Pass phrase for infile.   * @param pRepair (unused)   * @return new PwManager container.   *    * @throws IOException on any file error.   * @throws InvalidKeyException on a decryption error, or possible internal bug.   * @throws IllegalBlockSizeException on a decryption error, or possible internal bug.   * @throws BadPaddingException on a decryption error, or possible internal bug.   * @throws NoSuchAlgorithmException on a decryption error, or possible internal bug.   * @throws NoSuchPaddingException on a decryption error, or possible internal bug.   * @throws InvalidAlgorithmParameterException if error decrypting main file body.    * @throws ShortBufferException if error decrypting main file body.   */  public PwManager openDatabase( InputStream inStream, String password )      throws IOException, PhoneIDException, InvalidCipherTextException    {    PwManager        newManager;    SHA256Digest    md;    /** Master key encrypted several times */    byte[]           transformedMasterKey;    byte[]           finalKey;    if (mForm != null)	mForm.append("openDatabase()\r\n");    // Load entire file, most of it's encrypted.    // InputStream in = new FileInputStream( infile );    byte[] filebuf = new byte[(int)inStream.available()];    inStream.read( filebuf, 0, (int)inStream.available());    inStream.close();    // Parse header (unencrypted)    if( filebuf.length < PwDbHeader.BUF_SIZE )      throw new IOException( "File too short for header" );    PwDbHeader hdr = new PwDbHeader( filebuf, 0 );    if( (hdr.signature1 != PwManager.PWM_DBSIG_1) || (hdr.signature2 != PwManager.PWM_DBSIG_2) ) {	KeePassMIDlet.logS ( "Bad database file signature" );	throw new IOException( "Bad database file signature" );    }    if( hdr.version != PwManager.PWM_DBVER_DW ) {	KeePassMIDlet.logS ( "Bad database file version");	throw new IOException( "Bad database file version" );    }    newManager = new PwManager();    newManager.setMasterKey( password );        // Select algorithm    if( (hdr.flags & PwManager.PWM_FLAG_RIJNDAEL) != 0 ) {	KeePassMIDlet.logS ( "Algorithm AES");	newManager.algorithm = PwManager.ALGO_AES;    } else if( (hdr.flags & PwManager.PWM_FLAG_TWOFISH) != 0 ) {	KeePassMIDlet.logS ( "Algorithm TWOFISH");	newManager.algorithm = PwManager.ALGO_TWOFISH;    } else {	throw new IOException( "Unknown algorithm." );    }    if( newManager.algorithm == PwManager.ALGO_TWOFISH )	throw new IOException( "TwoFish algorithm is not supported" );        newManager.numKeyEncRounds = hdr.numKeyEncRounds;    if (mForm != null)	mForm.append("rounds = " + newManager.numKeyEncRounds + "\r\n");        // testRijndael_JCE();    newManager.name = "KeePass Password Manager";    // Generate transformedMasterKey from masterKey    //KeePassMIDlet.logS ("masterSeed2: " + new String(Hex.encode(hdr.masterSeed2)));        transformedMasterKey = transformMasterKey( hdr.masterSeed2,                                               newManager.masterKey,                                               newManager.numKeyEncRounds );    // Hash the master password with the salt in the file    md = new SHA256Digest();    md.update( hdr.masterSeed, 0, hdr.masterSeed.length );    md.update( transformedMasterKey, 0, transformedMasterKey.length );    finalKey = new byte[md.getDigestSize()];    md.doFinal ( finalKey, 0);    // NI    //KeePassMIDlet.logS ("finalKey: " + new String(Hex.encode(finalKey)));        // Initialize Rijndael algorithm    // Cipher cipher = Cipher.getInstance( "AES/CBC/PKCS5Padding" );    //PaddedBufferedBlockCipher cipher = new PaddedBufferedBlockCipher(new CBCBlockCipher(new AESEngine()));    BufferedBlockCipher cipher = new BufferedBlockCipher(new CBCBlockCipher(new AESEngine()));        //cipher.init( Cipher.DECRYPT_MODE, new SecretKeySpec( finalKey, "AES" ), new IvParameterSpec( hdr.encryptionIV ) );    cipher.init(false, new ParametersWithIV(new KeyParameter(finalKey), hdr.encryptionIV));    // Decrypt! The first bytes aren't encrypted (that's the header)    //int encryptedPartSize = cipher.doFinal( filebuf, PwDbHeader.BUF_SIZE, filebuf.length - PwDbHeader.BUF_SIZE, filebuf, PwDbHeader.BUF_SIZE );    //int encryptedPartSize    int paddedEncryptedPartSize = cipher.processBytes(filebuf, PwDbHeader.BUF_SIZE, filebuf.length - PwDbHeader.BUF_SIZE, filebuf, PwDbHeader.BUF_SIZE );    int encryptedPartSize = 0;    //try {    PKCS7Padding padding = new PKCS7Padding();    encryptedPartSize = paddedEncryptedPartSize - padding.padCount(filebuf);    //} catch (Exception e) {    //}    // NI    byte[] plainContent = new byte[encryptedPartSize];    System.arraycopy(filebuf, PwDbHeader.BUF_SIZE, plainContent, 0, encryptedPartSize);    if (mForm != null)	mForm.append("filebuf length: " + filebuf.length + "\r\n");    //System.out.println ("file length: " + filebuf.length);    //System.out.println ("plaintext contents length: " + encryptedPartSize);    //System.out.println ("plaintext contents:\n" + new String(Hex.encode(plainContent)));        //if( pRepair == null ) {    //md = MessageDigest.getInstance( "SHA-256" );    md = new SHA256Digest();    md.update( filebuf, PwDbHeader.BUF_SIZE, encryptedPartSize );    //      md.update( makePad(filebuf) );    md.doFinal (finalKey, 0);        if( PhoneIDUtil.compare( finalKey, hdr.contentsHash ) == false) {	//KeePassMIDlet.logS ( "Database file did not decrypt correctly. (checksum code is broken)" );	System.out.println ("Database file did not decrypt correctly. (checksum code is broken)");	if (mForm != null)	    mForm.append("Database file did not decrypt correctly. (checksum code is broken)\r\n");	throw new PhoneIDException("Wrong Password, or Database File Corrupted (database file did not decrypt correctly)");    }    // }        // Import all groups    if (mForm != null)	mForm.append("Import all groups\r\n");        int pos = PwDbHeader.BUF_SIZE;    PwGroup newGrp = new PwGroup();    for( int i = 0; i < hdr.numGroups; ) {	int fieldType = Types.readShort( filebuf, pos );	pos += 2;	int fieldSize = Types.readInt( filebuf, pos );      pos += 4;      if( fieldType == 0xFFFF ) {        KeePassMIDlet.logS ( newGrp.level + " " + newGrp.name );        // End-Group record.  Save group and count it.	//newManager.groups.add( newGrp );	newManager.addGroup( newGrp );        newGrp = new PwGroup();        i++;      }      else {        readGroupField( newGrp, fieldType, filebuf, pos );      }      pos += fieldSize;    }    //    fixGroups( groups );    // Import all entries    if (mForm != null)	mForm.append("Import all entries\r\n");    PwEntry newEnt = new PwEntry();    for( int i = 0; i < hdr.numEntries; ) {      int fieldType = Types.readShort( filebuf, pos );      int fieldSize = Types.readInt( filebuf, pos + 2 );      if( fieldType == 0xFFFF ) {        // End-Group record.  Save group and count it.	  newManager.addEntry( newEnt );	  KeePassMIDlet.logS( newEnt.title );        newEnt = new PwEntry();        i++;      }      else {        readEntryField( newEnt, filebuf, pos );      }      pos += 2 + 4 + fieldSize;    }    // Keep the Meta-Info entry separate    if (mForm != null)	mForm.append("Keep the Meta-Info entry separate\r\n");    for( int i=0; i<newManager.entries.size(); i++) {	PwEntry ent = (PwEntry)newManager.entries.elementAt(i);	if( ent.title.equals( "Meta-Info" )	    && ent.url.equals( "$" )	    && ent.username.equals( "SYSTEM" ) ) {	    newManager.metaInfo = ent;	    newManager.entries.removeElementAt(i);	}    }    if (mForm != null)	mForm.append("Return newManager: " + newManager + "\r\n");        return newManager;  }  /**   * KeePass's custom pad style.   *    * @param data buffer to pad.   * @return addtional bytes to append to data[] to make   *    a properly padded array.   */  public static byte[] makePad( byte[] data ) {    //custom pad method    //TODO //WRZ doesn't work (yet)    // append 0x80 plus zeros to a multiple of 4 bytes    int thisblk = 32 - data.length % 32;  // bytes needed to finish blk    int nextblk = 0;                      // 32 if we need another block    // need 9 bytes; add new block if no room    if( thisblk < 9 ) {      nextblk = 32;    }

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -