用RSA做的一个简单的license过期

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

import javax.crypto.BadPaddingException;
import javax.crypto.Cipher;
import javax.crypto.IllegalBlockSizeException;
import javax.crypto.NoSuchPaddingException;
import java.io.UnsupportedEncodingException;
import java.security.*;
import java.security.interfaces.RSAPrivateKey;
import java.security.interfaces.RSAPublicKey;
import java.security.spec.InvalidKeySpecException;
import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.X509EncodedKeySpec;
import java.util.HashMap;
import java.util.Map;


/**
 * @author zhengliangjun
 * @date 2024/1/5
 * RSA工具类  默认长度为2048位
 */
public class RSAUtil {

    private static final int DEFAULT_RSA_KEY_SIZE = 2048;

    private static final String KEY_ALGORITHM = "RSA";

    private static final String SIGNATURE_ALGORITHM = "MD5withRSA";

    /*public static void main(String [] args) throws Exception {
        Map<String,String> result = generateRsaKey(DEFAULT_RSA_KEY_SIZE);
        System.out.println("公钥为:" + result.get("publicKey") );
        System.out.println("私钥为:" + result.get("privateKey"));

        String expireDate = "2024-01-05";
      String encryptContent =  encrypt(expireDate,result.get("publicKey"));
      String path = System.getProperty("user.dir");

        FileWriter fileWriter;
        try {
            fileWriter = new FileWriter(path+"/license.txt", true);
            fileWriter.write(encryptContent + "\n");// \n: 换行; 每写入一行追加一个换行
            fileWriter.write(result.get("privateKey") + "\n");// \n: 换行; 每写入一行追加一个换行
            fileWriter.close();
        } catch (IOException e) {
            e.printStackTrace();
        }

    }*/

    /**
     * 生成RSA 公私钥,可选长度为1025,2048位.
     */
    public static Map<String,String> generateRsaKey(int keySize) {
        Map<String,String> result = new HashMap<>(2);
        try {
            KeyPairGenerator keyPairGen = KeyPairGenerator.getInstance(KEY_ALGORITHM);

            // 初始化密钥对生成器,密钥大小为1024 2048位
            keyPairGen.initialize(keySize, new SecureRandom());

            // 生成一个密钥对,保存在keyPair中
            KeyPair keyPair = keyPairGen.generateKeyPair();

            // 得到公钥字符串
            result.put("publicKey", new String(Base64.encodeBase64(keyPair.getPublic().getEncoded())));

            // 得到私钥字符串
            result.put("privateKey", new String(Base64.encodeBase64(keyPair.getPrivate().getEncoded())));

        } catch (GeneralSecurityException e) {
            e.printStackTrace();
        }
        return result;
    }

    /**
     * RSA私钥解密
     * @param str  解密字符串
     * @param privateKey  私钥
     * @return 明文
     */
    public static String decrypt(String str, String privateKey) {
        //64位解码加密后的字符串
        byte[] inputByte;
        String outStr = "";
        try {
            inputByte = Base64.decodeBase64(str.getBytes("UTF-8"));
            //base64编码的私钥
            byte[] decoded = Base64.decodeBase64(privateKey);
            RSAPrivateKey priKey = (RSAPrivateKey) KeyFactory.getInstance("RSA").generatePrivate(new PKCS8EncodedKeySpec(decoded));
            //RSA解密
            Cipher cipher = Cipher.getInstance("RSA");
            cipher.init(Cipher.DECRYPT_MODE, priKey);
            outStr = new String(cipher.doFinal(inputByte));
        } catch (UnsupportedEncodingException | NoSuchPaddingException | InvalidKeyException | IllegalBlockSizeException | BadPaddingException | InvalidKeySpecException | NoSuchAlgorithmException e) {
            e.printStackTrace();
        }
        //System.out.println("解密后的数据"+outStr);
        return outStr;
    }

    /**
     *  RSA公钥加密
     * @param str 需要加密的字符串
     * @param publicKey 公钥
     * @return 密文
     * @throws Exception 加密过程中的异常信息
     */
    public static String encrypt(String str, String publicKey) throws Exception {
        //base64编码的公钥
        byte[] decoded = Base64.decodeBase64(publicKey);
        RSAPublicKey pubKey = (RSAPublicKey) KeyFactory.getInstance("RSA").generatePublic(new X509EncodedKeySpec(decoded));
        //RSA加密
        Cipher cipher = Cipher.getInstance("RSA");
        cipher.init(Cipher.ENCRYPT_MODE, pubKey);
        String outStr = Base64.encodeBase64String(cipher.doFinal(str.getBytes("UTF-8")));
        //System.out.println("加密后的数据为:"+outStr);
        return outStr;
    }

}

/**
 * @author zhengliangjun
 * @date 2024/1/5
 */
@Slf4j
public class ValidateLicense {
    static  String privateKey;
    static String encryptText;

    /*public static void main(String[] args) throws Exception {
        ValidateLicense vt = new ValidateLicense();
        //vt.Validate();
        vt.getPath();
        vt.readTextFile();
        System.out.println("privateKey:"+privateKey);
        System.out.println("encryptText:"+encryptText);
        RSAUtil.decrypt(encryptText,privateKey);

    }*/

    /**
     * 验证license是否过期
     * 校验规则:获取系统当前时间与license文件中解析的时间进行对比
     * @return
     */
    public static boolean isExpired() {
        ValidateLicense validateLicense = new ValidateLicense();
        Map<String,String> map = validateLicense.readTextFile();

        String licenseDateStr = RSAUtil.decrypt(map.get("encryptText"),map.get("privateKey")); // 设置license日期字符串

        SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");
        Date licenseDate = null;
        try {
            licenseDate = dateFormat.parse(licenseDateStr);
        } catch (ParseException e) {
            throw new RuntimeException(e);
        }
        Calendar calendar = Calendar.getInstance();
        calendar.setTimeInMillis(System.currentTimeMillis());
        Date currentDate = calendar.getTime();

        if (licenseDate.before(currentDate)) {//license失效返回true
            log.info("License已过期!");
            return  true;
        } else {//license有效返回false
            return  false;
        }
    }

    public String getPath() {
        String relativePath = Thread.currentThread().getContextClassLoader().getResource("").getPath()+"license.txt";

        //URL resources = this.getClass().getResource("license.txt");
       // System.out.println("stockFilePath" + relativePath);
        return relativePath;
    }

    /**
     * 读取license文本文件
     * @return
     */
    public  Map<String,String> readTextFile() {
          Map<String,String> licenseMap = new HashMap<>();

            try {
                // 指定要读取的文本文件路径
                String filePath = getPath();

                FileInputStream fis = new FileInputStream(new File(filePath));
                InputStreamReader isr = new InputStreamReader(fis);
                BufferedReader br = new BufferedReader(isr);
                licenseMap.put("encryptText",br.readLine());
                licenseMap.put("privateKey",br.readLine());

                //encryptText = br.readLine();
               // privateKey = br.readLine();
                // 读取并打印第一行内容
               // System.out.println("第一行私钥内容:" + encryptText);
                // 读取并打印第二行内容
               // System.out.println("第二行是加密后的内容:" + privateKey);

                // 关闭流
                br.close();
                isr.close();
                fis.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
            return licenseMap;
        }


}

license.txt示例。一共3行

E5wEu8Bsj+lfyl5dhpdQ0EuKAtJR+hu7rPCIqq7Pzqb6XTx3A1mRcwDheERua5GQeoFxaRKUIOBwYyH6lvbWzfnOW44RzZBsCtsF0mdY6IRvHJB0HkL+zJOJBxO/1lgBlRr/sZqe5TMN/+FwRBT6f1/MVBWOsdUQnp9CbOLYnbrM5cJiREQJ6f8zsCEW0ebqPrZ4V36Qb/sqTzL77rvhfykSgWWAXz4abDDpAiw4Yadrc8xP6hWW0xk+cA7xwtpLLToO00R0lhO8BU50F35kZVKyOoAmiApziLnkIXR3yTpwooeySl6iys+7bpxN5+HNFaFl+QZkUKpihYdTGrosuw==
MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQCpAJCXrgYniHqerr5GkoXwWhi27TW7wA4jh4IGG238VF+c994ryKF8eTiU8ooRT0aXatXCeQ+PJWkek1/67DC7yH5T032/gCfBJMK3KwOMclfFO1SQs4lHmys+VWLgpSaQ2AFuTMaWvZ8UOA4/obTYzNO1xMm3wDkZCw6rLcIvDQqFH6UakSP2jzfDnL5xXUtt3uOfIwuRd8D1wM+6zl1YQKo6qPYZzezR4PWLC9bFtI6Juvfm728LDXYwZEq8sYLJMRzZFbijAVOhhDSeSfdpzTykQLI6F3np7uLTQRJciNyqzyoEbNiB5yH3M0TdRWEYkP0QV7Ibsxg3zW1jszp1AgMBAAECggEADLXnKhFDkzuXhVG9K8+fVTlhfHiQvwMtzQxHAjCT8BNkcYjO49oeEx+G2uT272BX/dFiLFMwkWKN6mfJIzUaYTUuEx3n6jw4QTWDk4UfqjN7WHEi5hMqswD/mpuPaTfik6g7S1Fo6jNuwHWK1MxTrq6RCa24QiKp6LFFNCin3yPreN9jVlgrsGbgoOA1nOuEKb3ElQdPJJx8eZNbTAZvJE8hJiO854ghmJbUYIWsy1outhnXt2XJls/4ugOTgkS/CW0UG88eNhpOuAIqWdZlE5ykG/G/igIkHCwJFz8R6CMIDh2zRKaTbbiU3STUcLPsmUPWvhRxJhEhjHsdHWoZzQKBgQDoVoXZEH8/VTQy2syNZwE2cAju838Atan3PeOLuXqYazVhByimwMxxwPxWi3i/S3ttRVn2mzkXZSYCqPOhk2iULjGcwaUbmR0abO7UQvABadtxNntTElMTa7aETQaBI6dhAqC+ehQsrOfP/ppxlJcOo3MZ/nQhphHGi4IZRHSq4wKBgQC6NsMg3gAg87Lyo+aNHnPqwMLGJSDW35AHn+DAiBEtOtUXYQ5ooJLmLPgZct+G/GE475aP51fDzYDYwYrcsPv/KiHAWBcfwP8IUNfxDfpL53HVyTA75wSJe5BWdZm1dr3YC89oCtkOf3SrKXxv5lgkYQvP9gp0IIq/BYpZjE1MxwKBgQDg/+GRa5t/TtlFIoUTrxwKhwbvuVlV65fU+tdg2deywago9dDVZELZKsZ0XY8q2kOGd7H+0yW/1VGxI8MEx4dwcSfUoeduSaJYlAPaBZT+GXDNO7DEqytO1HIlv54787ZFiVD4BauB9FRuJieVNQvwvjNaigQXDgeK2lG8fIHrdwKBgQCUtUD1EXUG27dPoGZw0h3+Hjwtot7r2hOakyoYd1FITpB4IDEyivFlUgo7wIoTsZ8uqd8SQszK+GVqNH3hqpFD//B+O5sT57uDd5RL1D7LuSQmd4nGfMIZzQzCjx3WVeJcE2pqCye2NUEFo5bVgh1nx/x38mP8wzQqQpFu2+WrZwKBgBi9UaqrWxCFMGWHa2SNveYxPPYTsB9Uco9vrOQo7v57/EOxqy2OkHUqNkPBN6w6GnR/zqs1s+puBHA1UCq4EtNAMuTg9smw4QI2mGkNmTPPB4mHnhuo8Z9CUAOYaDBDtmwg3bTA500niXQceL9hdWMcoTGrTCljpTh6Dx19CYZO

  • 20
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值