我在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/