Docx密码验证程序

时间:2016-03-08 19:56:00

标签: java

我在java中有一个小程序,应该验证密码,但似乎很短。如果有人在这里有任何关于offcrypto的经验,我们将非常感谢帮助。

我的主要课程如下。

import java.util.Arrays;
import java.util.logging.Level;
import java.util.logging.Logger;
import java.util.Base64;
import java.lang.reflect.Field;

import java.io.BufferedWriter;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;  
import java.io.*;

import java.security.MessageDigest;
import java.security.DigestException;
import java.security.GeneralSecurityException;
import java.security.Key;

import javax.crypto.Cipher;
import javax.crypto.spec.SecretKeySpec;

import org.apache.poi.poifs.crypt.*;
import org.apache.poi.util.StringUtil;
import org.apache.poi.util.LittleEndianConsts;
import org.apache.poi.EncryptedDocumentException;
import org.apache.poi.poifs.crypt.CipherAlgorithm;

import java.util.Base64;

public class KeyGen
{
    public static void main(String args[])
    {
        /**********************************************************************
        *
        *       variables are extracted from docx in base64 format
        *
        *       then manually transformed to hex then byte array as per JtR
        *
        ***********************************************************************/
        String salt = "gqJkQH6pdKPLzLSvXzNk/Q==";//initial values retrieved from word doc
        String HashInput ="jjyuf6DaqqL81TLEovnr0w==";
        String HashValue="VZUku9tIkOMd2HyoF+Qq1E9wjmgaPvujUaauptYHxbtVpvvG4tfhbYg2vDJJFxo8V73DlAcWESDQyLlrD8/y3A==";//this was truncated in JtR but will only work at full length here

        String hexSalt="82a264407ea974a3cbccb4af5f3364fd";
        String hexHashInput="8e3cae7fa0daaaa2fcd532c4a2f9ebd3";
        String hexHashValue = "559524bbdb4890e31dd87ca817e42ad44f708e681a3efba351a6aea6d607c5bb";

        Hex h = new Hex();

        //hexSalt = h.hexToAscii(hexSalt);
        //hexHashInput = h.hexToAscii(hexHashInput);
        //hexHashValue = h.hexToAscii(hexHashValue);

        int spinCount = 100000;//loop count
        int blockSize = 16;
        int keySize = 32;//size in bytes = 256 bits
        String password = "abc";
        byte[] blockKeyInput = {(byte)0xfe,(byte)0xa7,(byte)0xd2,(byte)0x76,(byte)0x3b,(byte)0x4b,(byte)0x9e,(byte)0x79};//block key for input given by microsoft
        byte[] blockKeyValue = {(byte)0xd7,(byte)0xaa,(byte)0x0f,(byte)0x6d,(byte)0x30,(byte)0x61,(byte)0x34,(byte)0x4e};//block key for value given by microsoft

        byte[] decodedValueIn = Base64.getDecoder().decode(HashInput);//decode base64 values to byte array
        byte[] decodedValueVal = Base64.getDecoder().decode(HashValue);
        byte[] decodedSalt = Base64.getDecoder().decode(salt);

        //decodedValueVal = hexHashValue.getBytes();
        //decodedValueIn = hexHashInput.getBytes();
        //decodedSalt = hexSalt.getBytes();

        SHA512 sha = new SHA512();//create sha object

        /**********************************************************************
        *
        *       variables used in cryptofunctions class parameters
        *
        ***********************************************************************/

        HashAlgorithm ha = HashAlgorithm.sha512;//define hash algorithm
        CipherAlgorithm ca = CipherAlgorithm.aes256;//define encryption algorithm
        ChainingMode cm = ChainingMode.cbc;//define chaining mode
        int cipherMode = 0;//unused as cryptofunctions class code changed
        boolean iteratorFirst = true;//order of i (i+hash)

        CryptoFunctions cf = new CryptoFunctions();//call class instead of using library (for troubleshooting)

        byte[] hash = cf.hashPassword(password,ha,decodedSalt,spinCount,iteratorFirst);//get hash from loop

        /**********************************************************************
        *
        *   generate an IV (initialization vector) for each key generated
        *
        ***********************************************************************/


        byte[] IVIn = cf.generateIv(ha,decodedSalt,blockKeyInput,blockSize);//get IV from salt+blockKey
        byte[] IVVal = cf.generateIv(ha,decodedSalt,blockKeyValue,blockSize);

        /**********************************************************************
        *
        *       generate final byte arrays which are part of the key
        *
        ***********************************************************************/    

        byte[] valueKey = cf.generateKey(hash,ha,blockKeyValue,keySize);
        byte[] inputKey = cf.generateKey(hash,ha,blockKeyInput,keySize);//as above
        SecretKeySpec inKey = new SecretKeySpec(inputKey,"AES");//generate key for cipher parameter
        SecretKeySpec valKey = new SecretKeySpec(valueKey,"AES");//generate second key

        Cipher cipherV = cf.getCipher(valKey,ca,cm,IVVal,cipherMode);//get cipher from combined values
        Cipher cipherI = cf.getCipher(inKey,ca,cm,IVIn,cipherMode);

        /**********************************************************************
        *
        *       final step decrypt two values then hash input
        *
        ***********************************************************************/

        byte[] decryptedIn = {};//initialize byte arrays outside try/catch
        byte[] decryptedVal = {};
        byte[] hashedBytesIn = {};

        try
        {
            decryptedIn = cipherI.doFinal(decodedValueIn);//do final decrypts using aes256+key
            decryptedVal = cipherV.doFinal(decodedValueVal);
            hashedBytesIn = sha.hashBytes(decryptedIn);//input must be hashed again
        }
        catch(Exception ex){}

        /**********************************************************************
        *
        *       compare arrays to retrieve candidate key result
        *
        ***********************************************************************/

        boolean Result = Arrays.equals(hashedBytesIn,decryptedVal);

        if(Result)//check for matching values
        {
            System.out.println("Success!");
        }
        else
        {
            System.out.println("");
            System.out.println("Fail!");
            System.out.println("");
        }
        System.out.println("decryptedVal"+Arrays.toString(decryptedVal));
        System.out.println("");
        System.out.println("hashedBytesIn"+Arrays.toString(hashedBytesIn));     
    }

}

    /****************************************POSSIBLE ERRORS********************************************
    *
    *           No padding found in docx so field is empty in CryptoFunctinos.getCipher()
    *
    *           Secret Key is used in cf but in this class its SecretKeySpec, can't instantiate SecretKey
    *
    ****************************************************************************************************/

encryptedVerifierHashInput和encryptedVerifierHashValue都存储在加密文档中,我刚刚对它们进行了硬编码。这些都被解码,然后使用派生密钥解密,并再次对输入值进行散列。他们应该匹配以确认密码。不幸的是他们没有。

我以为我已经破解了但是在那里有一个问题,我希望有人可以发现它。

cryptofunctions类来自这里的库。

http://source.dussan.org/raw/mirrors/poi.git/trunk/src/java/org/apache/poi/poifs/crypt/

0 个答案:

没有答案