package com.friday.custody.service.trustService.csc.utils;

import org.apache.commons.codec.binary.Base64;

import java.nio.charset.StandardCharsets;

public class SM4Util {

	private String secretKey = "";
	private String iv = "";
	private boolean hexString = false;

	public SM4Util() {
	}

	public String encryptData_ECB(String plainText) throws Exception {

		SM4.SM4_Context ctx = new SM4.SM4_Context();
		ctx.isPadding = true;
		ctx.mode = SM4.SM4_ENCRYPT;

		byte[] keyBytes;
		if (hexString) {
			keyBytes = ByteConvertUtil.hexStringToBytes(secretKey);
		} else {
			keyBytes = secretKey.getBytes();
		}

		SM4 sm4 = new SM4();
		sm4.sm4_setkey_enc(ctx, keyBytes);
		byte[] encrypted = sm4.sm4_crypt_ecb(ctx, plainText.getBytes(StandardCharsets.UTF_8));

		return Base64.encodeBase64String(encrypted);

	}

	public String decryptData_ECB(String cipherText) throws Exception {

		SM4.SM4_Context ctx = new SM4.SM4_Context();
		ctx.isPadding = true;
		ctx.mode = SM4.SM4_DECRYPT;

		byte[] keyBytes;
		if (hexString) {
			keyBytes = ByteConvertUtil.hexStringToBytes(secretKey);
		} else {
			keyBytes = secretKey.getBytes();
		}

		SM4 sm4 = new SM4();
		sm4.sm4_setkey_dec(ctx, keyBytes);
		byte[] decrypted = sm4.sm4_crypt_ecb(ctx, Base64.decodeBase64(cipherText));
		return new String(decrypted, StandardCharsets.UTF_8);

	}

	public String encryptData_CBC(String plainText) throws Exception {

		SM4.SM4_Context ctx = new SM4.SM4_Context();
		ctx.isPadding = true;
		ctx.mode = SM4.SM4_ENCRYPT;

		byte[] keyBytes;
		byte[] ivBytes;
		if (hexString) {
			keyBytes = ByteConvertUtil.hexStringToBytes(secretKey);
			ivBytes = ByteConvertUtil.hexStringToBytes(iv);
		} else {
			keyBytes = secretKey.getBytes();
			ivBytes = iv.getBytes();
		}

		SM4 sm4 = new SM4();
		sm4.sm4_setkey_enc(ctx, keyBytes);
		byte[] encrypted = sm4.sm4_crypt_cbc(ctx, ivBytes, plainText.getBytes(StandardCharsets.UTF_8));

		return Base64.encodeBase64String(encrypted);

	}

	public String decryptData_CBC(String cipherText) throws Exception {

		SM4.SM4_Context ctx = new SM4.SM4_Context();
		ctx.isPadding = true;
		ctx.mode = SM4.SM4_DECRYPT;

		byte[] keyBytes;
		byte[] ivBytes;
		if (hexString) {
			keyBytes = ByteConvertUtil.hexStringToBytes(secretKey);
			ivBytes = ByteConvertUtil.hexStringToBytes(iv);
		} else {
			keyBytes = secretKey.getBytes();
			ivBytes = iv.getBytes();
		}

		SM4 sm4 = new SM4();
		sm4.sm4_setkey_dec(ctx, keyBytes);
		byte[] decrypted = sm4.sm4_crypt_cbc(ctx, ivBytes, Base64.decodeBase64(cipherText));
		return new String(decrypted, StandardCharsets.UTF_8);

	}

	public static String encryptECB(String src, String key) throws Exception {
		SM4Util sm4 = new SM4Util();
		sm4.secretKey = key;
		sm4.hexString = false;
		return sm4.encryptData_ECB(src);
	}

	public static String decryptECB(String src, String key) throws Exception {
		SM4Util sm4 = new SM4Util();
		sm4.secretKey = key;
		sm4.hexString = false;
		return sm4.decryptData_ECB(src);
	}

	public static String encryptCBC(String src, String key, String iv) throws Exception {
		SM4Util sm4 = new SM4Util();
		sm4.secretKey = key;
		sm4.iv = iv;
		sm4.hexString = false;
		return sm4.encryptData_CBC(src);
	}

	public static String decryptCBC(String src, String key, String iv) throws Exception {
		SM4Util sm4 = new SM4Util();
		sm4.secretKey = key;
		sm4.iv = iv;
		sm4.hexString = false;
		return sm4.decryptData_CBC(src);
	}

	public static void main(String[] args) throws Exception {
		String plainText = "中文asdfa阿斯顿发生的12341235中文asdfa阿斯顿发生的12341235中文asdfa阿斯顿发生的12341235中文asdfa阿斯顿发生的12341235中文asdfa阿斯顿发生的12341235";
		System.out.println(plainText);
		String key = "AeF8r9wYFOOfs2Y7";
		String iv = "UISwD9fW6cFh9SNS";

		System.out.println("ECB模式");
		String cipherText = SM4Util.encryptECB(plainText, key);
		System.out.println("密文: " + cipherText);
		System.out.println("");

		plainText = SM4Util.decryptECB(cipherText, key);
		System.out.println("明文: " + plainText);
		System.out.println("");

		System.out.println("CBC模式");

		cipherText = SM4Util.encryptCBC(plainText, key, iv);
		System.out.println("密文: " + cipherText);
		System.out.println("");

		plainText = SM4Util.decryptCBC(cipherText, key, iv);
		System.out.println("明文: " + plainText);
	}
}