RSA2解密报错:Data must not be longer than 256 bytes

一、原因:

     实际使用RSA加解密算法通常有两种不同的方式,一种是使用对称密钥(比如 AES/ DES等加解密方法)加密数据,然后使用非对称密钥(RSA加解密密钥)加密对称密钥;另一种是直接使用非对称密钥加密数据。第一种方式安全性高,复杂度也高,不存在加密数据长度限制问题,第二种方式安全性差一些,复杂度低,但是存在加密数据限制问题(即使用非对称密钥加密数据时,一次加密的数据长度是(密钥长度/8-11))。
     目前双方约定的方式为第二种方式,而对应于本次抛错的密钥,key长度为1024位,1024/8 - 11 = 117,所以一次加密内容不能超过117bytes。另一个密钥没有问题,因为key的长度为2048位, 2048 /8 - 11 = 245, 一次加密内容不能超过 245 bytes。而分段加密代码中用128为单位分段,从而使得一个密钥报错,另一个不报错。

二、解决

    /**
     * RSA私钥解密
     * str加密字符串
     * privateKey私钥
     * return明文
     */
    public static String decryptByPrivateKey(String str, String privateKey) {
        try {
            //base64解码加密后的字符串
            byte[] inputByte = org.apache.commons.codec.binary.Base64.decodeBase64(str.getBytes(CHATSET));

            //base64编码的私钥
            byte[] decoded = org.apache.commons.codec.binary.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);
            //String outStr = new String(cipher.doFinal(inputByte));
            //当长度过长的时候,需要分割后解密 256个字节
            String outStr = new String(getMaxResultDecrypt(str, cipher));
            return outStr;
        } catch (Exception e) {
            logger.info(e.getMessage(), e);
        }
        return null;
    }




    //长度过长分割解密
    private static byte[] getMaxResultDecrypt(String str, Cipher cipher) throws IllegalBlockSizeException, BadPaddingException, UnsupportedEncodingException {
        byte[] inputArray = Base64.decodeBase64(str.getBytes("UTF-8"));
        int inputLength = inputArray.length;
        logger.info("inputLength: "+inputLength);
        // 最大解密字节数,超出最大字节数需要分组加密
        int MAX_ENCRYPT_BLOCK = 256;
        // 标识
        int offSet = 0;
        byte[] resultBytes = {};
        byte[] cache = {};
        while (inputLength - offSet > 0) {
            if (inputLength - offSet > MAX_ENCRYPT_BLOCK) {
                cache = cipher.doFinal(inputArray, offSet, MAX_ENCRYPT_BLOCK);
                offSet += MAX_ENCRYPT_BLOCK;
            } else {
                cache = cipher.doFinal(inputArray, offSet, inputLength - offSet);
                offSet = inputLength;
            }
            resultBytes = Arrays.copyOf(resultBytes, resultBytes.length + cache.length);
            System.arraycopy(cache, 0, resultBytes, resultBytes.length - cache.length, cache.length);
        }
        return resultBytes;
    }

参考:Java使用RSA进行加密解密【完美版本】;Data must not be longer than 117 bytes【不报此错误】_superswang的博客-CSDN博客

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值