StandardEncrypter.java
/*
* Copyright 2010 Srikanth Reddy Lingala
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package net.lingala.zip4j.crypto;
import net.lingala.zip4j.crypto.engine.ZipCryptoEngine;
import net.lingala.zip4j.exception.ZipException;
import java.security.SecureRandom;
import static net.lingala.zip4j.util.InternalZipConstants.STD_DEC_HDR_SIZE;
public class StandardEncrypter implements Encrypter {
private final ZipCryptoEngine zipCryptoEngine = new ZipCryptoEngine();
private byte[] headerBytes;
public StandardEncrypter(char[] password, long key, boolean useUtf8ForPassword) throws ZipException {
init(password, key, useUtf8ForPassword);
}
private void init(char[] password, long key, boolean useUtf8ForPassword) throws ZipException {
if (password == null || password.length <= 0) {
throw new ZipException("input password is null or empty, cannot initialize standard encrypter");
}
zipCryptoEngine.initKeys(password, useUtf8ForPassword);
headerBytes = generateRandomBytes();
// Initialize again since the generated bytes were encrypted.
zipCryptoEngine.initKeys(password, useUtf8ForPassword);
headerBytes[STD_DEC_HDR_SIZE - 1] = (byte) ((key >>> 24));
headerBytes[STD_DEC_HDR_SIZE - 2] = (byte) ((key >>> 16));
encryptData(headerBytes);
}
public int encryptData(byte[] buff) throws ZipException {
if (buff == null) {
throw new NullPointerException();
}
return encryptData(buff, 0, buff.length);
}
public int encryptData(byte[] buff, int start, int len) throws ZipException {
if (len < 0) {
throw new ZipException("invalid length specified to decrpyt data");
}
for (int i = start; i < start + len; i++) {
buff[i] = encryptByte(buff[i]);
}
return len;
}
protected byte encryptByte(byte val) {
byte temp_val = (byte) (val ^ zipCryptoEngine.decryptByte() & 0xff);
zipCryptoEngine.updateKeys(val);
return temp_val;
}
protected byte[] generateRandomBytes() {
byte[] buff = new byte[STD_DEC_HDR_SIZE];
SecureRandom random = new SecureRandom();
for (int i = 0; i < buff.length; i++) {
buff[i] = encryptByte((byte) random.nextInt(256));
}
return buff;
}
public byte[] getHeaderBytes() {
return headerBytes;
}
}