/*
* Copyright (c) Huawei Technologies Co., Ltd. 2022-2024. All rights reserved.
*/
package zip4cj.crypto
public class StandardEncrypter <: Encrypter {
private let zipCryptoEngine = ZipCryptoEngine()
private var headerBytes: Array<Byte>
@OverflowWrapping
public StandardEncrypter(password: ?Array<Rune>, key: Int64, useUtf8ForPassword: Bool) {
if (password.isNone()) {
throw ZipException("input password is null or empty, cannot initialize standard encrypter")
}
zipCryptoEngine.initKeys(password.getOrThrow(), useUtf8ForPassword)
headerBytes = Array<Byte>(InternalZipConstants.STD_DEC_HDR_SIZE, repeat: 0)
var random = SecureRandom()
for (i in 0..InternalZipConstants.STD_DEC_HDR_SIZE) {
headerBytes[i] = encryptByte(random.nextUInt8())
}
// Initialize again since the generated bytes were encrypted.
zipCryptoEngine.initKeys(password.getOrThrow(), useUtf8ForPassword)
headerBytes[InternalZipConstants.STD_DEC_HDR_SIZE - 1] = UInt8(key[24])
headerBytes[InternalZipConstants.STD_DEC_HDR_SIZE - 2] = UInt8(key[16])
encryptData(headerBytes)
}
public func encryptData(buff: Array<Byte>): Int64 {
return encryptData(buff, 0, buff.size)
}
func encryptData(buff: Array<Byte>, start: Int64, len: Int64): Int64 {
if (len < 0) {
throw ZipException("invalid length specified to decrpyt data")
}
for (i in start..start + len) {
buff[i] = encryptByte(buff[i])
}
return len
}
protected func encryptByte(val: Byte): Byte {
let temp_val = UInt8(val ^ zipCryptoEngine.decryptByte() & 0xff)
zipCryptoEngine.updateKeys(val)
return temp_val
}
public func getHeaderBytes(): Array<Byte> {
return this.headerBytes
}
}