package com.bcxin.ins.third.gzx.huatai.util;

import com.alibaba.fastjson.JSONObject;
import org.apache.commons.codec.binary.Base64;
import org.apache.commons.lang3.StringUtils;

import javax.crypto.Cipher;
import java.io.ByteArrayOutputStream;
import java.security.KeyFactory;
import java.security.PrivateKey;
import java.security.PublicKey;
import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.X509EncodedKeySpec;

/**
 * @author Administrator
 * @create 2023-11-27 17:10
 */
public class RsaUtil {
    /** 指定key的大小 */
    private static int KEYSIZE = 1024;
    private static final String encoding = "UTF-8";
    private static final String RSA_ALGORITHM = "RSA";
    /*** RSA最大加密明文大小*/
    private static final int MAX_ENCRYPT_BLOCK = 117;
    /*** RSA最大解密密文大小*/
    private static final int MAX_DECRYPT_BLOCK = 128;
    //私钥
    public static final String RSA_privateKey="MIICdgIBADANBgkqhkiG9w0BAQEFAASCAmAwggJcAgEAAoGBAJeyDifymEHf0arnbCaySHTbbcLvmVtOVRkQxCG0ozrgKSPfdgv7N509cagDIaWKTcbTtjte7bycga/+Yi1jA2i2kTwa84bz7rrqJa3LOzVOBeIk9b0SHPcjXPOv7QxxrJGM2x1UACd3l3wLIfAC0bYxQ5xTj7lzdZYboTfj2JCtAgMBAAECgYB6Uyr3K7l75XC90EB2M+4ZzZiFSZDxAAm/XLXMOE4oe/qw4tHed4YxVgsA4QWQ6CYv3ylkVvh+z/YEZa3ly6JC3ZWK/bNeWEEot8qV+szYSS8IvI/iBFeM1r9qOSw2iic3y05d2+33eRJGh0f2IuSoro9gm+jX3EYIf0f7JyROAQJBAOJW3PBR/pe2N5GtPro9ULUUrhz45fSuGVDAE+WA7gSZJFBkPQqSUW1fby2iwlGZuLSDphrDhh/OfiBrb2CA+YUCQQCrkxLitsnLwNcV4JydB7ifasy867fv9/e3vJGzhu/kXg4MJhI6VfKuywCStiRqovgL3PPrZs4oVmM2k6tMPQ8JAkByzhB/LXfvyBNjpvZ8TQGU+Apg07cAZxacKPFupfkVCACtbkqwBAudaJziDv51mX1gwq4MQUTU+U5sb1ItJv5pAkEAnMnE21rwY3rw0nQ0iidRJpUhTY8WwnrWa5gtiWJI/Gaa7a0owRhjsimed3NtKemNRMIAQODsid4PwgMF6aBuiQJAC2TPh6f0bf3mLJbBe8nJvOFH+Iuxk4DD0DYKTJ+xzMN4SuejN9YwTiGfHk8GYqoJZQ5LVXfXj6KztycdhLl57Q==";
    //公钥
    public static final String RSA_publicKey="MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCXsg4n8phB39Gq52wmskh0223C75lbTlUZEMQhtKM64Ckj33YL+zedPXGoAyGlik3G07Y7Xu28nIGv/mItYwNotpE8GvOG8+666iWtyzs1TgXiJPW9Ehz3I1zzr+0McayRjNsdVAAnd5d8CyHwAtG2MUOcU4+5c3WWG6E349iQrQIDAQAB";

    public static String message = "{\"publicOrderVo\":{\"policyDynamicVos\":[{\"dynamicValue\":\"开\",\"dynamicId\":\"1\",\"dynamicMean\":\"旅行1目的地\",\"insuredNo\":\"1\",\"itemNo\":\"1\",\"dynamicKey\":\"travleDes\"}],\"policyProgrammeVos\":[{\"policyRdrCategoryVos\":[{\"itemNo\":\"1\",\"personDecimal\":\"1\",\"plan\":\"01MD0001\"}]}],\"policyMainVo\":{\"amount\":\"145000\",\"effectiveTm\":\"2021-07-3100:00:00\",\"premium\":\"45\",\"productCode\":\"01MD\",\"chlCode\":\"HT100042\",\"proTm\":\"2021-07-30 15:18:28\",\"terminalTm\":\"2021-09-2900:00:00\",\"paymentWayCode\":\"1\",\"copy\":\"1\",\"dataProducer\":\"PB\"},\"policyInsuredVos\":[{\"insuredNum\":\"11010119990101023X\",\"insuredGender\":\"1\",\"insuredTelNum\":\"15001132199\",\"islegal\":\"1\",\"isHolder\":\"0\",\"insuredIdType\":\"01\",\"insuredNo\":\"1\",\"insuredType\":\"1\",\"itemNo\":\"1\",\"insuredBirthday\":\"1999-01-01\",\"insuredName\":\"核酸\",\"relationship\":\"03\"}],\"policyApplicantVo\":{\"appEmail\":\"11111@qq.com\",\"appNum\":\"110101199901010096\",\"apptelNum\":\"15001132199\",\"appGender\":\"1\",\"appName\":\"验证\",\"appType\":\"1\",\"appidType\":\"01\",\"visaType\":\"2\",\"appBirthday\":\"1999-01-01 00:00:00\"}},\"requestHeadVo\":{\"requestType\":\"HTIC002\",\"channelCode\":\"HT100042\"}}";

    public static void main(String[] args) throws Exception {
//        JSONObject inputObj = JSONObject.parseObject(message);
//        message= inputObj.toJSONString();
//        String s1 = rsaEncrypt(message, RSA_publicKey,"UTF-8");
//        System.out.println(s1);
//        String s = rsaDecrypt(s1, RSA_privateKey,"UTF-8");
//        System.out.println(s);
//        String ss = "CXT+My8Pjgr3A/7XP2SpezjplpA+RU6I6BOUlzLlAbp6tODbj2tcl3EdG/otAjAHrjmSb84tNEHm9TdwfPnCvzIHWV2XXKKR4kBLVbS+bdWrcM0SA4Ui0zkoxgDWgcTr+LV2miYH/+8bgU5V9IZBRrkx38Y13xdhlogNmiJQSto=";
//        System.out.println(dSign(ss,RSA_privateKey));
        String pu=" MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCmboDOkoghWVe447pylZHpTy0JvcWL3XcfbIeB+zVBpabpoFgH71MicGIlEDdMbrY8GXcAn5Gy8m/IdbIGe7aHYpSv4Q2r98y+OuFJ0ttqy9PVbrcspScwyAOvSVTdScRaBPB6JPSzSqLqzEnqJfE5K87RDh2qWcLBJm3Urvx8AwIDAQAB";
        String pr=" MIICdwIBADANBgkqhkiG9w0BAQEFAASCAmEwggJdAgEAAoGBAKZugM6SiCFZV7jjunKVkelPLQm9xYvddx9sh4H7NUGlpumgWAfvUyJwYiUQN0xutjwZdwCfkbLyb8h1sgZ7todilK/hDav3zL464UnS22rL09VutyylJzDIA69JVN1JxFoE8Hok9LNKourMSeol8TkrztEOHapZwsEmbdSu/HwDAgMBAAECgYAkO9KXJpe0ivrqKcohwCZwIOixQjuL479XfA1UYxiJHkNkgaAouhXjXYxAfXNMlJ3gH7sky5iw2M81WUpU1wI5xRuv/XnDg2bYT4UxXKaMGHQm6R2ESvFBPJqcr8nrMJCZKyF9B7Z/QfM+o09kOzaDQQC6NCT8vqe7LJrJy5/eQQJBAOKZzvgtGg3uREwAk0VGTvCGN4u+jQUFRqynjloT7xtJ6/hHeFsTRxiybaT0fJrS2LJ7TswU3U+GkSN966xf2xkCQQC8BkUmbG4UdR/kcb4ORBF307FQMigxlJkeO7zYdMQUkszcdJzcHk0cb4JrMNV9bu3eFxfz0hjVnrGMaUzejc97AkBTkDTrAHbjPEKjZHLq0Qq7WEOTnSmT+GYftYqhXUiH37LNVE3mCC3nxaT5d8+bqLWQ3DgqumcCtLVBSWZnotHBAkEAjl7RDX8c+zCUrY3Ss0qnT2xj3q2b8a7rIhFptRz1O/7MUEGcZLAtA1MMFc4sWYYdZwVlhaGYXGiFWCSDqCEI8QJBANDaRpiB7LfE6U9pAtfRWX3Zh021Q3ojQXn6RL8cv80pQYnYDxB1Xna7gdN5ZKbw6Xvm92ZRXjBZWLqvNbCr890=";
        String json = "{\"edrEffectDate\":\"2025-04-18\",\"edrNo\":\"PA1362434842800853777\",\"edrResult\":\"01\",\"orderNo\":\"PA1362439149969379840\",\"plyNo\":\"PB251649722503943872\",\"plyUrl\":\"http://localhost:8080/HT-API/TYX/callback-record\"}";
        String esign = eSign(json, pu);
        System.out.println(esign);
        System.out.println(dSign(esign,pr));
    }

    public static String eSign(String message,String publicKey) throws Exception {
        return rsaEncrypt(message, publicKey,"UTF-8");
    }
    public static String dSign(String message,String privateKey) throws Exception {
        return rsaDecrypt(message, privateKey,"UTF-8");
    }

    public static PrivateKey getPrivateKey(String privateKey) throws Exception {
        KeyFactory keyFactory = KeyFactory.getInstance("RSA");
        byte[] decodedKey = Base64.decodeBase64(privateKey.getBytes());
        PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(decodedKey);
        return keyFactory.generatePrivate(keySpec);
    }
    public static PublicKey getPublicKey(String publicKey) throws Exception {
        KeyFactory keyFactory = KeyFactory.getInstance("RSA");
        byte[] decodedKey = Base64.decodeBase64(publicKey.getBytes());
        X509EncodedKeySpec keySpec = new X509EncodedKeySpec(decodedKey);
        return keyFactory.generatePublic(keySpec);
    }

    /*** 公钥加密<br>
     *对于<b>开发者</b>，publicKey是指公钥，privateKey是指开发者自己的私钥<br>
     *对于，publicKey是指开发者的公钥，privateKey是指私钥<br>*
     * * @param content 待加密内容* @param publicKey 公钥* @param charset 字符集，如UTF-8* @return 密文内容* @throws Exception*/
    public static String rsaEncrypt(String content, String publicKey, String charset) throws Exception {
        PublicKey pubKey = getPublicKey(publicKey);
        Cipher cipher = Cipher.getInstance("RSA");
        cipher.init(Cipher.ENCRYPT_MODE, pubKey);
        byte[] data = StringUtils.isEmpty(charset) ? content.getBytes() :content.getBytes(charset);
        int inputLen = data.length;
        ByteArrayOutputStream out = new ByteArrayOutputStream();
        int offSet = 0;byte[] cache;int i = 0;
        // 对数据分段加密
        while (inputLen - offSet > 0) {
            if (inputLen - offSet > 117) {
                cache = cipher.doFinal(data, offSet, 117);
            } else {
                cache = cipher.doFinal(data, offSet, inputLen - offSet);
            }
            out.write(cache, 0, cache.length);
            i++;
            offSet = i * 117;
        }
        byte[] encryptedData = Base64.encodeBase64(out.toByteArray());
        out.close();
        return StringUtils.isEmpty(charset) ? new String(encryptedData) : new String(encryptedData, charset);
    }
    /*** 私钥解密<br>** @param content 待解密内容* @param privateKey 私钥* @param charset 字符集，如UTF-8* @return 明文内容* @throws Exception*/
    public static String rsaDecrypt(String content, String privateKey, String charset) throws Exception {
        try {
            PrivateKey priKey = getPrivateKey(privateKey);
            Cipher cipher = Cipher.getInstance("RSA");
            cipher.init(Cipher.DECRYPT_MODE, priKey);
            byte[] encryptedData =StringUtils.isEmpty(charset) ? Base64.decodeBase64(content.getBytes()): Base64.decodeBase64(content.getBytes(charset));
            int inputLen = encryptedData.length;
            ByteArrayOutputStream out = new ByteArrayOutputStream();
            int offSet = 0;byte[] cache;int i = 0;
            // 对数据分段解密
            while (inputLen - offSet > 0) {
                if (inputLen - offSet > 128) {
                    cache = cipher.doFinal(encryptedData, offSet, 128);
                } else {
                    cache = cipher.doFinal(encryptedData, offSet, inputLen - offSet);
                }
                out.write(cache, 0, cache.length);
                i++;
                offSet = i * 128;
            }
            byte[] decryptedData = out.toByteArray();out.close();
            return StringUtils.isEmpty(charset) ? new String(decryptedData): new String(decryptedData, charset);
        } catch (Exception e) {
            throw new Exception("EncodeContent = " + content + ",charset = " +charset, e);
        }
    }
}
