protected static SecretKey generateSecretKey(String password, EncryptionVerifier ver, int keySize) { HashAlgorithm hashAlgo = ver.getHashAlgorithm(); byte pwHash[] = hashPassword(password, hashAlgo, ver.getSalt(), ver.getSpinCount()); byte[] blockKey = new byte[4]; LittleEndian.putInt(blockKey, 0, 0); byte[] finalHash = CryptoFunctions.generateKey(pwHash, hashAlgo, blockKey, hashAlgo.hashSize); byte x1[] = fillAndXor(finalHash, (byte) 0x36); byte x2[] = fillAndXor(finalHash, (byte) 0x5c); byte[] x3 = new byte[x1.length + x2.length]; System.arraycopy(x1, 0, x3, 0, x1.length); System.arraycopy(x2, 0, x3, x1.length, x2.length); byte[] key = Arrays.copyOf(x3, keySize); return new SecretKeySpec(key, ver.getCipherAlgorithm().jceId); }
@Override public StandardEncryptionVerifier clone() throws CloneNotSupportedException { return (StandardEncryptionVerifier)super.clone(); } }
@Override protected final void setEncryptedKey(byte[] encryptedKey) { super.setEncryptedKey(encryptedKey); } }
protected static SecretKey generateSecretKey(String password, EncryptionVerifier ver) { if (password.length() > 255) { password = password.substring(0, 255); } HashAlgorithm hashAlgo = ver.getHashAlgorithm(); MessageDigest hashAlg = CryptoFunctions.getMessageDigest(hashAlgo); hashAlg.update(ver.getSalt()); byte hash[] = hashAlg.digest(StringUtil.getToUnicodeLE(password)); return new SecretKeySpec(hash, ver.getCipherAlgorithm().jceId); }
private Cipher getCipher(SecretKey key, String padding) { EncryptionVerifier ver = getEncryptionInfo().getVerifier(); return CryptoFunctions.getCipher(key, ver.getCipherAlgorithm(), ver.getChainingMode(), null, Cipher.ENCRYPT_MODE, padding); }
public boolean verifyPassword(String password) throws GeneralSecurityException { EncryptionVerifier verifier = _info.getVerifier(); int algorithm = verifier.getAlgorithm(); int mode = verifier.getCipherMode(); byte[] iv = generateIv(algorithm, verifier.getSalt(), null); byte[] verifierHashInput = cipher.doFinal(verifier.getVerifier()); byte[] trimmed = new byte[verifier.getSalt().length]; System.arraycopy(verifierHashInput, 0, trimmed, 0, trimmed.length); byte[] hashedVerifier = sha1.digest(trimmed); iv = generateIv(algorithm, verifier.getSalt(), null); cipher = getCipher(algorithm, mode, skey, iv); byte[] verifierHash = cipher.doFinal(verifier.getVerifierHash()); trimmed = new byte[hashedVerifier.length]; System.arraycopy(verifierHash, 0, trimmed, 0, trimmed.length); iv = generateIv(algorithm, verifier.getSalt(), null); cipher = getCipher(algorithm, mode, skey, iv); byte[] inter = cipher.doFinal(verifier.getEncryptedKey()); byte[] keyspec = new byte[_info.getHeader().getKeySize() / 8]; System.arraycopy(inter, 0, keyspec, 0, keyspec.length);
@Override public String toString() { StringBuilder buffer = new StringBuilder(); buffer.append("[FILEPASS]\n"); buffer.append(" .type = ").append(HexDump.shortToHex(encryptionType)).append('\n'); String prefix = " ."+encryptionInfo.getEncryptionMode(); buffer.append(prefix+".info = ").append(HexDump.shortToHex(encryptionInfo.getVersionMajor())).append('\n'); buffer.append(prefix+".ver = ").append(HexDump.shortToHex(encryptionInfo.getVersionMinor())).append('\n'); buffer.append(prefix+".salt = ").append(HexDump.toHex(encryptionInfo.getVerifier().getSalt())).append('\n'); buffer.append(prefix+".verifier = ").append(HexDump.toHex(encryptionInfo.getVerifier().getEncryptedVerifier())).append('\n'); buffer.append(prefix+".verifierHash = ").append(HexDump.toHex(encryptionInfo.getVerifier().getEncryptedVerifierHash())).append('\n'); buffer.append("[/FILEPASS]\n"); return buffer.toString(); } }
protected byte[] hashPassword(EncryptionInfo info, String password) throws NoSuchAlgorithmException { MessageDigest sha1 = MessageDigest.getInstance("SHA-1"); byte[] bytes; try { bytes = password.getBytes("UTF-16LE"); } catch (UnsupportedEncodingException e) { throw new EncryptedDocumentException("UTF16 not supported"); } sha1.update(info.getVerifier().getSalt()); byte[] hash = sha1.digest(bytes); byte[] iterator = new byte[4]; for (int i = 0; i < info.getVerifier().getSpinCount(); i++) { sha1.reset(); LittleEndian.putInt(iterator, 0, i); sha1.update(iterator); hash = sha1.digest(hash); } return hash; } }
@Override protected void setEncryptedVerifier(byte encryptedVerifier[]) { super.setEncryptedVerifier(encryptedVerifier); }
byte encVer[] = ver.getEncryptedVerifier(); Decryptor dec = ei.getDecryptor(); Encryptor enc = ei.getEncryptor(); } else { byte verifier[] = dec.getVerifier(); byte salt[] = ver.getSalt(); enc.confirmPassword(password, null, null, verifier, salt, null);
@Override protected void setEncryptedVerifierHash(byte encryptedVerifierHash[]) { super.setEncryptedVerifierHash(encryptedVerifierHash); }
@Override protected void setSalt(byte salt[]) { if (salt == null || salt.length != 16) { throw new EncryptedDocumentException("invalid verifier salt"); } super.setSalt(salt); }
protected Record[] updateEncryptionRecord(Record records[]) { String password = Biff8EncryptionKey.getCurrentUserPassword(); if (password == null) { if (dea == null) { // no password given, no encryption record exits -> done return records; } else { // need to remove password data dea = null; return removeEncryptionRecord(records); } } else { // create password record if (dea == null) { dea = new DocumentEncryptionAtom(); } EncryptionInfo ei = dea.getEncryptionInfo(); byte salt[] = ei.getVerifier().getSalt(); Encryptor enc = getEncryptionInfo().getEncryptor(); if (salt == null) { enc.confirmPassword(password); } else { byte verifier[] = ei.getDecryptor().getVerifier(); enc.confirmPassword(password, null, null, verifier, salt, null); } // move EncryptionRecord to last slide position records = normalizeRecords(records); return addEncryptionRecord(records, dea); } }
private byte[] generateKey(byte[] hash, byte[] blockKey) throws NoSuchAlgorithmException { MessageDigest sha1 = MessageDigest.getInstance("SHA-1"); sha1.update(hash); return getBlock(_info.getVerifier().getAlgorithm(), sha1.digest(blockKey)); }
public EncryptionInfo(DirectoryNode dir) throws IOException { DocumentInputStream dis = dir.createDocumentInputStream("EncryptionInfo"); versionMajor = dis.readShort(); versionMinor = dis.readShort(); encryptionFlags = dis.readInt(); if (versionMajor == 4 && versionMinor == 4 && encryptionFlags == 0x40) { StringBuilder builder = new StringBuilder(); byte[] xmlDescriptor = new byte[dis.available()]; dis.read(xmlDescriptor); for (byte b : xmlDescriptor) builder.append((char)b); String descriptor = builder.toString(); header = new EncryptionHeader(descriptor); verifier = new EncryptionVerifier(descriptor); } else { int hSize = dis.readInt(); header = new EncryptionHeader(dis); if (header.getAlgorithm()==EncryptionHeader.ALGORITHM_RC4) { verifier = new EncryptionVerifier(dis, 20); } else { verifier = new EncryptionVerifier(dis, 32); } } }
public boolean verifyPassword(String password) throws GeneralSecurityException { EncryptionVerifier verifier = _info.getVerifier(); int algorithm = verifier.getAlgorithm(); int mode = verifier.getCipherMode(); byte[] iv = generateIv(algorithm, verifier.getSalt(), null); byte[] verifierHashInput = cipher.doFinal(verifier.getVerifier()); byte[] trimmed = new byte[verifier.getSalt().length]; System.arraycopy(verifierHashInput, 0, trimmed, 0, trimmed.length); byte[] hashedVerifier = sha1.digest(trimmed); iv = generateIv(algorithm, verifier.getSalt(), null); cipher = getCipher(algorithm, mode, skey, iv); byte[] verifierHash = cipher.doFinal(verifier.getVerifierHash()); trimmed = new byte[hashedVerifier.length]; System.arraycopy(verifierHash, 0, trimmed, 0, trimmed.length); iv = generateIv(algorithm, verifier.getSalt(), null); cipher = getCipher(algorithm, mode, skey, iv); byte[] inter = cipher.doFinal(verifier.getEncryptedKey()); byte[] keyspec = new byte[_info.getHeader().getKeySize() / 8]; System.arraycopy(inter, 0, keyspec, 0, keyspec.length);
protected static SecretKey generateSecretKey(String password, EncryptionVerifier ver) { if (password.length() > 255) { password = password.substring(0, 255); } HashAlgorithm hashAlgo = ver.getHashAlgorithm(); MessageDigest hashAlg = CryptoFunctions.getMessageDigest(hashAlgo); byte hash[] = hashAlg.digest(StringUtil.getToUnicodeLE(password)); byte salt[] = ver.getSalt(); hashAlg.reset(); for (int i = 0; i < 16; i++) { hashAlg.update(hash, 0, 5); hashAlg.update(salt); } hash = new byte[5]; System.arraycopy(hashAlg.digest(), 0, hash, 0, 5); return new SecretKeySpec(hash, ver.getCipherAlgorithm().jceId); }
@Override public String toString() { StringBuilder buffer = new StringBuilder(); buffer.append("[FILEPASS]\n"); buffer.append(" .type = ").append(HexDump.shortToHex(encryptionType)).append('\n'); String prefix = " ."+encryptionInfo.getEncryptionMode(); buffer.append(prefix+".info = ").append(HexDump.shortToHex(encryptionInfo.getVersionMajor())).append('\n'); buffer.append(prefix+".ver = ").append(HexDump.shortToHex(encryptionInfo.getVersionMinor())).append('\n'); buffer.append(prefix+".salt = ").append(HexDump.toHex(encryptionInfo.getVerifier().getSalt())).append('\n'); buffer.append(prefix+".verifier = ").append(HexDump.toHex(encryptionInfo.getVerifier().getEncryptedVerifier())).append('\n'); buffer.append(prefix+".verifierHash = ").append(HexDump.toHex(encryptionInfo.getVerifier().getEncryptedVerifierHash())).append('\n'); buffer.append("[/FILEPASS]\n"); return buffer.toString(); } }
protected byte[] hashPassword(EncryptionInfo info, String password) throws NoSuchAlgorithmException { MessageDigest sha1 = MessageDigest.getInstance("SHA-1"); byte[] bytes; try { bytes = password.getBytes("UTF-16LE"); } catch (UnsupportedEncodingException e) { throw new EncryptedDocumentException("UTF16 not supported"); } sha1.update(info.getVerifier().getSalt()); byte[] hash = sha1.digest(bytes); byte[] iterator = new byte[4]; for (int i = 0; i < info.getVerifier().getSpinCount(); i++) { sha1.reset(); LittleEndian.putInt(iterator, 0, i); sha1.update(iterator); hash = sha1.digest(hash); } return hash; } }
@Override protected void setEncryptedVerifier(byte encryptedVerifier[]) { super.setEncryptedVerifier(encryptedVerifier); }