effbe57e创建于 2024年11月25日历史提交
/*
 * 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
    }
}