您的位置:首页 > 其它

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

2017-10-28 08:15 387 查看
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网络安全工具类》,不喜勿喷。

每天努力一点,每天都在进步。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: