searchusermenu
  • 发布文章
  • 消息中心
点赞
收藏
评论
分享
原创

Rsa分段加密大数据

2024-07-31 09:49:38
22
0

分段加解密的基本思路
分段加密:将要加密的数据分成多个小段,每段的长度不超过 RSA 加密允许的最大长度,然后对每段数据分别进行加密。
分段解密:将加密后的数据分成多个小段,每段的长度为 RSA 加密后的长度,然后对每段数据分别进行解密。

 

import java.security.KeyFactory;
import java.security.PrivateKey;
import java.security.PublicKey;
import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.X509EncodedKeySpec;
import java.util.ArrayList;
import java.util.Base64;
import java.util.List;
import javax.crypto.Cipher;

public class RSAUtils {

    private static final String RSA_ALGORITHM = "RSA";
    private static final String TRANSFORMATION = "RSA/ECB/PKCS1Padding";

    // 加密块大小 (密钥长度 / 8 - 11) - 这里以2048位密钥为例
    private static final int ENCRYPT_BLOCK_SIZE = 2048 / 8 - 11;
    // 解密块大小 (密钥长度 / 8) - 这里以2048位密钥为例
    private static final int DECRYPT_BLOCK_SIZE = 2048 / 8;

    // RSA 分段加密
    public static List<byte[]> encryptData(byte[] data, PublicKey publicKey) throws Exception {
        Cipher cipher = Cipher.getInstance(TRANSFORMATION);
        cipher.init(Cipher.ENCRYPT_MODE, publicKey);
        return splitData(data, cipher, ENCRYPT_BLOCK_SIZE);
    }

    // RSA 分段解密
    public static byte[] decryptData(List<byte[]> encryptedData, PrivateKey privateKey) throws Exception {
        Cipher cipher = Cipher.getInstance(TRANSFORMATION);
        cipher.init(Cipher.DECRYPT_MODE, privateKey);
        return joinData(encryptedData, cipher);
    }

    // 将数据分段加密
    private static List<byte[]> splitData(byte[] data, Cipher cipher, int blockSize) throws Exception {
        int inputLength = data.length;
        List<byte[]> encryptedData = new ArrayList<>();
        int offset = 0;

        while (offset < inputLength) {
            int length = Math.min(inputLength - offset, blockSize);
            byte[] encryptedBlock = cipher.doFinal(data, offset, length);
            encryptedData.add(encryptedBlock);
            offset += length;
        }
        return encryptedData;
    }

    // 合并解密后的数据
    private static byte[] joinData(List<byte[]> encryptedData, Cipher cipher) throws Exception {
        List<byte[]> decryptedData = new ArrayList<>();
        for (byte[] block : encryptedData) {
            byte[] decryptedBlock = cipher.doFinal(block);
            decryptedData.add(decryptedBlock);
        }

        // 合并所有解密后的数据
        int totalLength = decryptedData.stream().mapToInt(b -> b.length).sum();
        byte[] result = new byte[totalLength];
        int currentPosition = 0;
        for (byte[] block : decryptedData) {
            System.arraycopy(block, 0, result, currentPosition, block.length);
            currentPosition += block.length;
        }
        return result;
    }

    public static void main(String[] args) throws Exception {
        // 示例:假设已经加载了 RSA 公钥和私钥
        PublicKey publicKey = getPublicKeyFromBase64String("你的公钥Base64字符串");
        PrivateKey privateKey = getPrivateKeyFromBase64String("你的私钥Base64字符串");

        String originalText = "这是需要加密的非常长的数据...";
        byte[] originalData = originalText.getBytes();

        // 分段加密
        List<byte[]> encryptedData = encryptData(originalData, publicKey);

        // 分段解密
        byte[] decryptedData = decryptData(encryptedData, privateKey);

        String decryptedText = new String(decryptedData);
        System.out.println("Decrypted Text: " + decryptedText);
    }

    // 加载公钥(Base64 字符串转 PublicKey 对象)
    private static PublicKey getPublicKeyFromBase64String(String key) throws Exception {
        byte[] keyBytes = Base64.getDecoder().decode(key);
        X509EncodedKeySpec keySpec = new X509EncodedKeySpec(keyBytes);
        KeyFactory keyFactory = KeyFactory.getInstance(RSA_ALGORITHM);
        return keyFactory.generatePublic(keySpec);
    }

    // 加载私钥(Base64 字符串转 PrivateKey 对象)
    private static PrivateKey getPrivateKeyFromBase64String(String key) throws Exception {
        byte[] keyBytes = Base64.getDecoder().decode(key);
        PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(keyBytes);
        KeyFactory keyFactory = KeyFactory.getInstance(RSA_ALGORITHM);
        return keyFactory.generatePrivate(keySpec);
    }
}


使用 RSA 加密和解密大数据时,由于 RSA 本身的限制,无法一次性加密或解密大数据。RSA 加密的最大数据长度受到密钥长度和填充方式的限制。通常,为了加密和解密大数据,需要将数据分段处理。以下是实现分段加解密的基本思路和示例代码。

分段加解密的基本思路
分段加密:将要加密的数据分成多个小段,每段的长度不超过 RSA 加密允许的最大长度,然后对每段数据分别进行加密。
分段解密:将加密后的数据分成多个小段,每段的长度为 RSA 加密后的长度,然后对每段数据分别进行解密。
RSA 分段加密示例
java
复制代码
import java.security.KeyFactory;
import java.security.PrivateKey;
import java.security.PublicKey;
import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.X509EncodedKeySpec;
import java.util.ArrayList;
import java.util.Base64;
import java.util.List;
import javax.crypto.Cipher;

public class RSAUtils {

    private static final String RSA_ALGORITHM = "RSA";
    private static final String TRANSFORMATION = "RSA/ECB/PKCS1Padding";

    // 加密块大小 (密钥长度 / 8 - 11) - 这里以2048位密钥为例
    private static final int ENCRYPT_BLOCK_SIZE = 2048 / 8 - 11;
    // 解密块大小 (密钥长度 / 8) - 这里以2048位密钥为例
    private static final int DECRYPT_BLOCK_SIZE = 2048 / 8;

    // RSA 分段加密
    public static List<byte[]> encryptData(byte[] data, PublicKey publicKey) throws Exception {
        Cipher cipher = Cipher.getInstance(TRANSFORMATION);
        cipher.init(Cipher.ENCRYPT_MODE, publicKey);
        return splitData(data, cipher, ENCRYPT_BLOCK_SIZE);
    }

    // RSA 分段解密
    public static byte[] decryptData(List<byte[]> encryptedData, PrivateKey privateKey) throws Exception {
        Cipher cipher = Cipher.getInstance(TRANSFORMATION);
        cipher.init(Cipher.DECRYPT_MODE, privateKey);
        return joinData(encryptedData, cipher);
    }

    // 将数据分段加密
    private static List<byte[]> splitData(byte[] data, Cipher cipher, int blockSize) throws Exception {
        int inputLength = data.length;
        List<byte[]> encryptedData = new ArrayList<>();
        int offset = 0;

        while (offset < inputLength) {
            int length = Math.min(inputLength - offset, blockSize);
            byte[] encryptedBlock = cipher.doFinal(data, offset, length);
            encryptedData.add(encryptedBlock);
            offset += length;
        }
        return encryptedData;
    }

    // 合并解密后的数据
    private static byte[] joinData(List<byte[]> encryptedData, Cipher cipher) throws Exception {
        List<byte[]> decryptedData = new ArrayList<>();
        for (byte[] block : encryptedData) {
            byte[] decryptedBlock = cipher.doFinal(block);
            decryptedData.add(decryptedBlock);
        }

        // 合并所有解密后的数据
        int totalLength = decryptedData.stream().mapToInt(b -> b.length).sum();
        byte[] result = new byte[totalLength];
        int currentPosition = 0;
        for (byte[] block : decryptedData) {
            System.arraycopy(block, 0, result, currentPosition, block.length);
            currentPosition += block.length;
        }
        return result;
    }

    public static void main(String[] args) throws Exception {
        // 示例:假设已经加载了 RSA 公钥和私钥
        PublicKey publicKey = getPublicKeyFromBase64String("你的公钥Base64字符串");
        PrivateKey privateKey = getPrivateKeyFromBase64String("你的私钥Base64字符串");

        String originalText = "这是需要加密的非常长的数据...";
        byte[] originalData = originalText.getBytes();

        // 分段加密
        List<byte[]> encryptedData = encryptData(originalData, publicKey);

        // 分段解密
        byte[] decryptedData = decryptData(encryptedData, privateKey);

        String decryptedText = new String(decryptedData);
        System.out.println("Decrypted Text: " + decryptedText);
    }

    // 加载公钥(Base64 字符串转 PublicKey 对象)
    private static PublicKey getPublicKeyFromBase64String(String key) throws Exception {
        byte[] keyBytes = Base64.getDecoder().decode(key);
        X509EncodedKeySpec keySpec = new X509EncodedKeySpec(keyBytes);
        KeyFactory keyFactory = KeyFactory.getInstance(RSA_ALGORITHM);
        return keyFactory.generatePublic(keySpec);
    }

    // 加载私钥(Base64 字符串转 PrivateKey 对象)
    private static PrivateKey getPrivateKeyFromBase64String(String key) throws Exception {
        byte[] keyBytes = Base64.getDecoder().decode(key);
        PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(keyBytes);
        KeyFactory keyFactory = KeyFactory.getInstance(RSA_ALGORITHM);
        return keyFactory.generatePrivate(keySpec);
    }
}

 


说明:


块大小计算:

加密块大小:ENCRYPT_BLOCK_SIZE = (密钥长度 / 8) - 11。11 是 PKCS1 填充方式的开销。
解密块大小:DECRYPT_BLOCK_SIZE = 密钥长度 / 8。


加密过程:

数据被分成小块,每块的大小不超过 ENCRYPT_BLOCK_SIZE。
每个小块单独加密,并将结果保存到 List<byte[]> 中。

 

解密过程:

对加密后的数据分块解密,每个小块的大小为 DECRYPT_BLOCK_SIZE。
将解密后的数据块合并成完整的数据。
公钥和私钥加载:

通过 Base64 字符串加载公钥和私钥。
注意事项
分段处理:由于 RSA 的最大加密块长度受限于密钥长度和填充方式,务必确保每个数据块不超过允许的大小。
加密块顺序:加密和解密时必须保持相同的顺序,以确保数据正确性。
填充方式一致:确保加密和解密使用相同的填充方式。

 

 

 

 

0条评论
0 / 1000
l****n
5文章数
0粉丝数
l****n
5 文章 | 0 粉丝
原创

Rsa分段加密大数据

2024-07-31 09:49:38
22
0

分段加解密的基本思路
分段加密:将要加密的数据分成多个小段,每段的长度不超过 RSA 加密允许的最大长度,然后对每段数据分别进行加密。
分段解密:将加密后的数据分成多个小段,每段的长度为 RSA 加密后的长度,然后对每段数据分别进行解密。

 

import java.security.KeyFactory;
import java.security.PrivateKey;
import java.security.PublicKey;
import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.X509EncodedKeySpec;
import java.util.ArrayList;
import java.util.Base64;
import java.util.List;
import javax.crypto.Cipher;

public class RSAUtils {

    private static final String RSA_ALGORITHM = "RSA";
    private static final String TRANSFORMATION = "RSA/ECB/PKCS1Padding";

    // 加密块大小 (密钥长度 / 8 - 11) - 这里以2048位密钥为例
    private static final int ENCRYPT_BLOCK_SIZE = 2048 / 8 - 11;
    // 解密块大小 (密钥长度 / 8) - 这里以2048位密钥为例
    private static final int DECRYPT_BLOCK_SIZE = 2048 / 8;

    // RSA 分段加密
    public static List<byte[]> encryptData(byte[] data, PublicKey publicKey) throws Exception {
        Cipher cipher = Cipher.getInstance(TRANSFORMATION);
        cipher.init(Cipher.ENCRYPT_MODE, publicKey);
        return splitData(data, cipher, ENCRYPT_BLOCK_SIZE);
    }

    // RSA 分段解密
    public static byte[] decryptData(List<byte[]> encryptedData, PrivateKey privateKey) throws Exception {
        Cipher cipher = Cipher.getInstance(TRANSFORMATION);
        cipher.init(Cipher.DECRYPT_MODE, privateKey);
        return joinData(encryptedData, cipher);
    }

    // 将数据分段加密
    private static List<byte[]> splitData(byte[] data, Cipher cipher, int blockSize) throws Exception {
        int inputLength = data.length;
        List<byte[]> encryptedData = new ArrayList<>();
        int offset = 0;

        while (offset < inputLength) {
            int length = Math.min(inputLength - offset, blockSize);
            byte[] encryptedBlock = cipher.doFinal(data, offset, length);
            encryptedData.add(encryptedBlock);
            offset += length;
        }
        return encryptedData;
    }

    // 合并解密后的数据
    private static byte[] joinData(List<byte[]> encryptedData, Cipher cipher) throws Exception {
        List<byte[]> decryptedData = new ArrayList<>();
        for (byte[] block : encryptedData) {
            byte[] decryptedBlock = cipher.doFinal(block);
            decryptedData.add(decryptedBlock);
        }

        // 合并所有解密后的数据
        int totalLength = decryptedData.stream().mapToInt(b -> b.length).sum();
        byte[] result = new byte[totalLength];
        int currentPosition = 0;
        for (byte[] block : decryptedData) {
            System.arraycopy(block, 0, result, currentPosition, block.length);
            currentPosition += block.length;
        }
        return result;
    }

    public static void main(String[] args) throws Exception {
        // 示例:假设已经加载了 RSA 公钥和私钥
        PublicKey publicKey = getPublicKeyFromBase64String("你的公钥Base64字符串");
        PrivateKey privateKey = getPrivateKeyFromBase64String("你的私钥Base64字符串");

        String originalText = "这是需要加密的非常长的数据...";
        byte[] originalData = originalText.getBytes();

        // 分段加密
        List<byte[]> encryptedData = encryptData(originalData, publicKey);

        // 分段解密
        byte[] decryptedData = decryptData(encryptedData, privateKey);

        String decryptedText = new String(decryptedData);
        System.out.println("Decrypted Text: " + decryptedText);
    }

    // 加载公钥(Base64 字符串转 PublicKey 对象)
    private static PublicKey getPublicKeyFromBase64String(String key) throws Exception {
        byte[] keyBytes = Base64.getDecoder().decode(key);
        X509EncodedKeySpec keySpec = new X509EncodedKeySpec(keyBytes);
        KeyFactory keyFactory = KeyFactory.getInstance(RSA_ALGORITHM);
        return keyFactory.generatePublic(keySpec);
    }

    // 加载私钥(Base64 字符串转 PrivateKey 对象)
    private static PrivateKey getPrivateKeyFromBase64String(String key) throws Exception {
        byte[] keyBytes = Base64.getDecoder().decode(key);
        PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(keyBytes);
        KeyFactory keyFactory = KeyFactory.getInstance(RSA_ALGORITHM);
        return keyFactory.generatePrivate(keySpec);
    }
}


使用 RSA 加密和解密大数据时,由于 RSA 本身的限制,无法一次性加密或解密大数据。RSA 加密的最大数据长度受到密钥长度和填充方式的限制。通常,为了加密和解密大数据,需要将数据分段处理。以下是实现分段加解密的基本思路和示例代码。

分段加解密的基本思路
分段加密:将要加密的数据分成多个小段,每段的长度不超过 RSA 加密允许的最大长度,然后对每段数据分别进行加密。
分段解密:将加密后的数据分成多个小段,每段的长度为 RSA 加密后的长度,然后对每段数据分别进行解密。
RSA 分段加密示例
java
复制代码
import java.security.KeyFactory;
import java.security.PrivateKey;
import java.security.PublicKey;
import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.X509EncodedKeySpec;
import java.util.ArrayList;
import java.util.Base64;
import java.util.List;
import javax.crypto.Cipher;

public class RSAUtils {

    private static final String RSA_ALGORITHM = "RSA";
    private static final String TRANSFORMATION = "RSA/ECB/PKCS1Padding";

    // 加密块大小 (密钥长度 / 8 - 11) - 这里以2048位密钥为例
    private static final int ENCRYPT_BLOCK_SIZE = 2048 / 8 - 11;
    // 解密块大小 (密钥长度 / 8) - 这里以2048位密钥为例
    private static final int DECRYPT_BLOCK_SIZE = 2048 / 8;

    // RSA 分段加密
    public static List<byte[]> encryptData(byte[] data, PublicKey publicKey) throws Exception {
        Cipher cipher = Cipher.getInstance(TRANSFORMATION);
        cipher.init(Cipher.ENCRYPT_MODE, publicKey);
        return splitData(data, cipher, ENCRYPT_BLOCK_SIZE);
    }

    // RSA 分段解密
    public static byte[] decryptData(List<byte[]> encryptedData, PrivateKey privateKey) throws Exception {
        Cipher cipher = Cipher.getInstance(TRANSFORMATION);
        cipher.init(Cipher.DECRYPT_MODE, privateKey);
        return joinData(encryptedData, cipher);
    }

    // 将数据分段加密
    private static List<byte[]> splitData(byte[] data, Cipher cipher, int blockSize) throws Exception {
        int inputLength = data.length;
        List<byte[]> encryptedData = new ArrayList<>();
        int offset = 0;

        while (offset < inputLength) {
            int length = Math.min(inputLength - offset, blockSize);
            byte[] encryptedBlock = cipher.doFinal(data, offset, length);
            encryptedData.add(encryptedBlock);
            offset += length;
        }
        return encryptedData;
    }

    // 合并解密后的数据
    private static byte[] joinData(List<byte[]> encryptedData, Cipher cipher) throws Exception {
        List<byte[]> decryptedData = new ArrayList<>();
        for (byte[] block : encryptedData) {
            byte[] decryptedBlock = cipher.doFinal(block);
            decryptedData.add(decryptedBlock);
        }

        // 合并所有解密后的数据
        int totalLength = decryptedData.stream().mapToInt(b -> b.length).sum();
        byte[] result = new byte[totalLength];
        int currentPosition = 0;
        for (byte[] block : decryptedData) {
            System.arraycopy(block, 0, result, currentPosition, block.length);
            currentPosition += block.length;
        }
        return result;
    }

    public static void main(String[] args) throws Exception {
        // 示例:假设已经加载了 RSA 公钥和私钥
        PublicKey publicKey = getPublicKeyFromBase64String("你的公钥Base64字符串");
        PrivateKey privateKey = getPrivateKeyFromBase64String("你的私钥Base64字符串");

        String originalText = "这是需要加密的非常长的数据...";
        byte[] originalData = originalText.getBytes();

        // 分段加密
        List<byte[]> encryptedData = encryptData(originalData, publicKey);

        // 分段解密
        byte[] decryptedData = decryptData(encryptedData, privateKey);

        String decryptedText = new String(decryptedData);
        System.out.println("Decrypted Text: " + decryptedText);
    }

    // 加载公钥(Base64 字符串转 PublicKey 对象)
    private static PublicKey getPublicKeyFromBase64String(String key) throws Exception {
        byte[] keyBytes = Base64.getDecoder().decode(key);
        X509EncodedKeySpec keySpec = new X509EncodedKeySpec(keyBytes);
        KeyFactory keyFactory = KeyFactory.getInstance(RSA_ALGORITHM);
        return keyFactory.generatePublic(keySpec);
    }

    // 加载私钥(Base64 字符串转 PrivateKey 对象)
    private static PrivateKey getPrivateKeyFromBase64String(String key) throws Exception {
        byte[] keyBytes = Base64.getDecoder().decode(key);
        PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(keyBytes);
        KeyFactory keyFactory = KeyFactory.getInstance(RSA_ALGORITHM);
        return keyFactory.generatePrivate(keySpec);
    }
}

 


说明:


块大小计算:

加密块大小:ENCRYPT_BLOCK_SIZE = (密钥长度 / 8) - 11。11 是 PKCS1 填充方式的开销。
解密块大小:DECRYPT_BLOCK_SIZE = 密钥长度 / 8。


加密过程:

数据被分成小块,每块的大小不超过 ENCRYPT_BLOCK_SIZE。
每个小块单独加密,并将结果保存到 List<byte[]> 中。

 

解密过程:

对加密后的数据分块解密,每个小块的大小为 DECRYPT_BLOCK_SIZE。
将解密后的数据块合并成完整的数据。
公钥和私钥加载:

通过 Base64 字符串加载公钥和私钥。
注意事项
分段处理:由于 RSA 的最大加密块长度受限于密钥长度和填充方式,务必确保每个数据块不超过允许的大小。
加密块顺序:加密和解密时必须保持相同的顺序,以确保数据正确性。
填充方式一致:确保加密和解密使用相同的填充方式。

 

 

 

 

文章来自个人专栏
杂项
5 文章 | 1 订阅
0条评论
0 / 1000
请输入你的评论
0
0