package com.qmth.boot.tools.crypto;

import com.qmth.boot.tools.models.ByteArray;

import javax.crypto.Cipher;
import java.io.ByteArrayOutputStream;
import java.security.Key;

/**
 * RSA公私钥共用的抽象接口，提供加解密方法
 */
public interface RsaHelper {

    String ALGORITHM = "RSA";

    int MAX_ENCRYPT_BLOCK = 117;

    int MAX_DECRYPT_BLOCK = 128;

    Key getKey() throws Exception;

    /**
     * 加密
     *
     * @param data
     * @return
     * @throws Exception
     */
    default ByteArray encrypt(byte[] data) throws Exception {
        Cipher cipher = Cipher.getInstance(ALGORITHM);
        cipher.init(Cipher.ENCRYPT_MODE, getKey());
        return process(cipher, data, MAX_ENCRYPT_BLOCK);
    }

    /**
     * 解密
     *
     * @param data
     * @return
     * @throws Exception
     */
    default ByteArray decrypt(byte[] data) throws Exception {
        Cipher cipher = Cipher.getInstance(ALGORITHM);
        cipher.init(Cipher.DECRYPT_MODE, getKey());
        return process(cipher, data, MAX_DECRYPT_BLOCK);
    }

    default ByteArray process(Cipher cipher, byte[] data, int blockSize) throws Exception {
        ByteArrayOutputStream out = new ByteArrayOutputStream();
        int offset = 0;
        int left = data.length - offset;
        while (left > 0) {
            int block = Math.min(left, blockSize);
            byte[] cache = cipher.doFinal(data, offset, block);
            out.write(cache, 0, cache.length);
            offset += block;
            left -= block;
        }
        return ByteArray.fromArray(out.toByteArray());
    }

}
