vue2+java+RSA分段加解密

vue2+java+RSA分段加解密

前端

  1. 安装encryptlong
npm install encryptlong -S
  1. 创建工具类
import { JSEncrypt } from 'encryptlong'

const b64map = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
const b64pad = "=";

function hex2b64(h) {
  let i;
  let c;
  let ret = "";
  for (i = 0; i + 3 <= h.length; i += 3) {
    c = parseInt(h.substring(i, i + 3), 16);
    ret += b64map.charAt(c >> 6) + b64map.charAt(c & 63);
  }
  if (i + 1 == h.length) {
    c = parseInt(h.substring(i, i + 1), 16);
    ret += b64map.charAt(c << 2);
  }
  else if (i + 2 == h.length) {
    c = parseInt(h.substring(i, i + 2), 16);
    ret += b64map.charAt(c >> 2) + b64map.charAt((c & 3) << 4);
  }
  while ((ret.length & 3) > 0) ret += b64pad;
  return ret;
}

function addPreZero(num, length) {
  var t = (num + '').length,
    s = '';
  for (var i = 0; i < length - t; i++) {
    s += '0';
  }

  return s + num;
}

JSEncrypt.prototype.encryptLong2 = function (string) {
  const k = this.getKey();
  try {
    const lt = "";
    let ct = "";
    //RSA每次加密117bytes,需要辅助方法判断字符串截取位置
    //1.获取字符串截取点
    const bytes = new Array();
    bytes.push(0);
    let byteNo = 0;
    let len, c;
    // eslint-disable-next-line prefer-const
    len = string.length;
    let temp = 0;
    // eslint-disable-next-line no-var
    for (var i = 0; i < len; i++) {
      c = string.charCodeAt(i);
      if (c >= 0x010000 && c <= 0x10FFFF) {
        byteNo += 4;
      } else if (c >= 0x000800 && c <= 0x00FFFF) {
        byteNo += 3;
      } else if (c >= 0x000080 && c <= 0x0007FF) {
        byteNo += 2;
      } else {
        byteNo += 1;
      }
      if ((byteNo % 117) >= 114 || (byteNo % 117) == 0 ) {
          bytes.push(i);
          byteNo = 0;
      }
    }
    //2.截取字符串并分段加密
    if (bytes.length > 1) {
      // eslint-disable-next-line no-var
      for (var i = 0; i < bytes.length - 1; i++) {
        // eslint-disable-next-line no-var
        var str;
        if (i == 0) {
          str = string.substring(0, bytes[i + 1] + 1);
        } else {
          str = string.substring(bytes[i] + 1, bytes[i + 1] + 1);
        }
        const t1 = k.encrypt(str);
        let a=addPreZero(t1, 256);
        ct += a;
      }
      if (bytes[bytes.length - 1] != string.length - 1) {
        const lastStr = string.substring(bytes[bytes.length - 1] + 1);
        const rsaStr = k.encrypt(lastStr)
        let a=addPreZero(rsaStr, 256);
        ct += a;
      }
      return hex2b64(ct);
    }
    const t = k.encrypt(string);
    const y = hex2b64(t);
    return y;
  } catch (ex) {
    return false;
  }
}

export default class crypto {
// rsa公钥:加密
  static rsaPublicKey = '';
}

/**
   * rsa公钥加密
   * @param {*} word
   * @returns
   */
  // jsencrypt.min.js使用,注意事项:
  // 1.该加密库默认是ECB模式,对应java rsa加密库的ECB或NONE模式
  // 2.填充方式:PKCS1
  // 3.setPublicKey(key):key需为base64格式数据
  // 4.每次加密后的结果不一样,但是不影响解密后的结果(解密结果均一样)
  static encryptRsa(word) {
    const jsencrypt = new JSEncrypt();
    jsencrypt.setPublicKey(this.rsaPublicKey);
    jsencrypt.set
    return jsencrypt.encryptLong2(word);
  }
  1. 使用
<script>
  import crypto from '@/util/crypto'

  //加密
  encrypt(data){
  	return crypto.encryptRsa(data);
  }
</script>

后端

  1. 创建工具类
public class CryptoUtil {
	public CryptoUtil() {
	}

	/**
	 * 分段解密
	 * @param base64Key
	 * @param base64Str
	 * @return
	 */
	public static String rsaDecrypt(String base64Key,String base64Str) {
		try {
			byte[] data = Base64.decodeBase64(base64Str);
			int inputLen = data.length;
			ByteArrayOutputStream out = new ByteArrayOutputStream();
			int offSet = 0;
			// 对数据分段解密
			while (inputLen - offSet > 0) {
				byte[] bytesDe;
				if (inputLen - offSet > 128) {
					byte[] bytes = Arrays.copyOfRange(data, offSet, offSet + 128);
					bytesDe = RsaUtil.decrypt(base64Key, bytes);
					offSet += 128;
				} else {
					byte[] bytes = Arrays.copyOfRange(data, offSet, inputLen);
					bytesDe = RsaUtil.decrypt(base64Key, bytes);
					offSet = inputLen;
				}
				out.write(bytesDe, 0, bytesDe.length);
			}
			String resutl = out.toString("UTF-8");
			out.close();
			return resutl;
		}catch (Exception e){
			e.printStackTrace();
		 	throw new ServiceException("解密失败");
		}
	}
	
	private byte[] decrypt(String base64PrivateKey, byte[] data){
		 try {
		 	Key key = getPrivateKey(base64PrivateKey);
		 	
            Cipher cipher = Cipher.getInstance("RSA/ECB/PKCS1Padding");
            cipher.init(1, key);
            return cipher.doFinal(data);
        } catch (Exception var4) {
            throw Exceptions.unchecked(var4);
        }
	}
	
	private PrivateKey getPrivateKey(String base64PriKey) {
        Objects.requireNonNull(base64PriKey, "base64 private key is null.");
        byte[] keyBytes = Base64Utils.decodeFromString(base64PriKey);
        PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(keyBytes);

        try {
            KeyFactory keyFactory = KeyFactory.getInstance("RSA");
            return keyFactory.generatePrivate(keySpec);
        } catch (InvalidKeySpecException | NoSuchAlgorithmException var4) {
            throw Exceptions.unchecked(var4);
        }
    }
}
  1. 使用
CryptoUtil.rsaDecrypt(privateKey,data);
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

墨寂

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值