RSA加密解密以及内容超长时采用分段加密

RSA加密解密以及内容超长时采用分段加密


1、在使用 RSA加密解密内容时会出现这样的异常 : Data must not be longer than 117 bytes。 
解决办法是:分段加密和分段解密。


2、分段加密
    /** 
     * @Title: RSAEncode 
     * @Description: 将字符串加密 
     * @param key 
     * @param data 
     * @return String 
     */  
    public static String RSAEncode(String data, RSAPublicKey publicKey) {  
        byte[] b = data.getBytes();  
        try {  
            int inputLen = b.length;  
            ByteArrayOutputStream out = new ByteArrayOutputStream();  
            int offSet = 0;  
            byte[] cache;  
            int i = 0;  
            Cipher cipher = Cipher.getInstance(RSA);  
            cipher.init(Cipher.ENCRYPT_MODE, publicKey);  
            // 对数据分段解密  
            while (inputLen - offSet > 0) {  
                if (inputLen - offSet > MAX_ENCRYPT_BLOCK) {  
                    cache = cipher.doFinal(b, offSet, MAX_ENCRYPT_BLOCK);  
                } else {  
                    cache = cipher.doFinal(b, offSet, inputLen - offSet);  
                }  
                out.write(cache, 0, cache.length);  
                i++;  
                offSet = i * MAX_ENCRYPT_BLOCK;  
            }  
            byte[] decryptedData = out.toByteArray();  
            out.close();  
            return Base64.toBase64String(decryptedData);  
        } catch (Exception e) {
logger.error(e.getMessage());
}
        return null;  
    } 
3、分段解密
    /** 
     * @Title: RSADecode 
     * @Description: 将字符串解密 
     * @param key 
     * @param encodedText 
     * @return String 
     */  
    public static String RSADecode(String data, RSAPrivateKey privateKey) {  
        try {
            byte[] b = Base64.decode(data);  
            int inputLen = b.length;  
            ByteArrayOutputStream out = new ByteArrayOutputStream();  
            int offSet = 0;  
            byte[] cache;  
            int i = 0;  
            Cipher cipher = Cipher.getInstance(RSA);  
            cipher.init(Cipher.DECRYPT_MODE, privateKey);  
            // 对数据分段解密  
            while (inputLen - offSet > 0) {  
                if (inputLen - offSet > MAX_DECRYPT_BLOCK) {  
                    cache = cipher.doFinal(b, offSet, MAX_DECRYPT_BLOCK);  
                } else {  
                    cache = cipher.doFinal(b, offSet, inputLen - offSet);  
                }  
                out.write(cache, 0, cache.length);  
                i++;  
                offSet = i * MAX_DECRYPT_BLOCK;  
            }  
            byte[] decryptedData = out.toByteArray();  
            out.close();  
            return new String(decryptedData);  
        } catch (Exception e) {
logger.error(e.getMessage());
}
return null;
    } 


3、当出现前端加解密没问题,后台加解密没问题,但是前端不能完全解密后台的密文,前端给的密文后台解不出的问题。
原因:前端和后台生产秘药对采用的补位方式不同,所以出现加解密失败。


解决方案:
使用模和指数生成RSA公钥 注意:【此代码用了默认补位方式,为RSA/None/PKCS1Padding,不同JDK默认的补位方式可能不同,如Android默认是RSA/None/NoPadding】
前端修改代码:
Cipher cipher = Cipher.getInstance("RSA/ECB/PKCS1Padding");


4、采用本方法生产的公私钥对,因为位数的问题对ios不适用的问题。


我们代码自己生产的秘钥对对ios不适用,需要让ios在端自己生产一份,我们来加解密,进行操作。


部分代码如下:
public static void main(String[] args) {
try {
Map<String, Object> map = RsaUtils.getKeys();
RSAPublicKey publicKey = (RSAPublicKey) map.get("public");
RSAPrivateKey privateKey = (RSAPrivateKey) map.get("private");
// 模
String modulus = publicKey.getModulus().toString();
logger.info("modulus:"+modulus);
// 公钥指数
String public_exponent = publicKey.getPublicExponent().toString();
logger.info("public_exponent:"+public_exponent);
// 私钥指数
String private_exponent = privateKey.getPrivateExponent().toString();
logger.info("private_exponent:"+private_exponent);
// 明文
String ming = "这是一段加密明文,可以很长的数据进行加密,采用分组加密";
// 使用模和指数生成公钥和私钥
RSAPublicKey pubKey = RsaUtils.getPublicKey(modulus, public_exponent);
RSAPrivateKey priKey = RsaUtils.getPrivateKey(modulus, private_exponent);
//自己生产的公私钥对
String publicKeyStr = Base64.toBase64String(pubKey.getEncoded());
String privateKeyStr = Base64.toBase64String(priKey.getEncoded());

System.out.println("public key  :"+publicKeyStr);
System.out.println("private key :"+privateKeyStr);
// 加密后的密文
String mi = RsaUtils.RSAEncode(ming, RsaUtils.loadPublicKey(publicKeyStr));
logger.info("密文:"+mi);
// 解密后的明文
//String mi = "Johjwa/2jAe/k3pkB9Ax9WE0RMjq4s73csdBg==这是一段加密的密文数据,用来测试解密的";
ming = RsaUtils.RSADecode(mi, RsaUtils.loadPrivateKey(privateKeyStr));
logger.info("明文:"+ming);
} catch (Exception e) {
logger.error(e.getMessage());
}

}

有需要完整代码的请到下载页面进行获取《RSA网络安全工具类》,不喜勿喷。


每天努力一点,每天都在进步。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

powerfuler

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

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

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

打赏作者

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

抵扣说明:

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

余额充值