RSA2分段加密解密

public class RSAEncrypt {

    // 取值 SHA256WithRSA 或者 SHA1WithRSA
    // RSA 对应 SHA1WithRSA
    // RSA2 对应 SHA256WithRSA 至少2048 位以上
    public static final String SHA_WITH_RSA_ALGORITHM = "SHA256WithRSA";

    public static final String MD5_WITH_RSA = "MD5WithRSA";

    public static final int KEY_SIZE = 2048;

    public static final String ALGORITHM = "RSA";

    public static final String CHARSET = "UTF-8";

    /**
     * RSA最大加密明文大小
     */
    private static final int MAX_ENCRYPT_BLOCK = 245;
    /**
     * RSA最大解密密文大小
     */
    private static final int MAX_DECRYPT_BLOCK = 256;

    /**
     * SHAWithRSA签名
     */
    public static String sign(String in, String pivateKey, String algorithm) throws Exception {
        PKCS8EncodedKeySpec priPKCS8 = new PKCS8EncodedKeySpec(Base64.getDecoder().decode(pivateKey));
        KeyFactory keyf = KeyFactory.getInstance(ALGORITHM);
        PrivateKey priKey = keyf.generatePrivate(priPKCS8);
        Signature signa = Signature.getInstance(algorithm != null ? algorithm : SHA_WITH_RSA_ALGORITHM);
        signa.initSign(priKey);
        signa.update(in.getBytes());
        byte[] signdata = signa.sign();
        return Base64.getEncoder().encodeToString(signdata);
    }

    /**
     * SHAWithRSA签名 默认 SHAWithRSA签名
     */
    public static String sign(String in, String pivateKey) throws Exception {
        return sign(in, pivateKey, null);
    }

    /**
     * SHAWithRSA验签 默认SHAWithRSA验签
     */
    public static boolean isValid(String in, String signData, String publicKey, String algorithm) throws Exception {
        KeyFactory keyFactory = KeyFactory.getInstance(ALGORITHM);
        byte[] encodedKey = Base64.getDecoder().decode(publicKey);
        PublicKey pubKey = keyFactory.generatePublic(new X509EncodedKeySpec(encodedKey));
        Signature signa = Signature.getInstance(algorithm != null ? algorithm : SHA_WITH_RSA_ALGORITHM);
        signa.initVerify(pubKey);
        signa.update(in.getBytes());
        byte[] sign_byte = Base64.getDecoder().decode(signData);
        boolean flag = signa.verify(sign_byte);
        return flag;
    }

    /**
     * SHAWithRSA验签
     */
    public static boolean isValid(String in, String signData, String publicKey) throws Exception {
        return isValid(in, signData, publicKey, null);
    }

    /**
     * RSA公钥加密
     */
    public static String encrypt(String str, String publicKey) throws Exception {
        // base64编码的公钥
        byte[] decoded = Base64.getDecoder().decode(publicKey);
        RSAPublicKey pubKey =
            (RSAPublicKey)KeyFactory.getInstance(ALGORITHM).generatePublic(new X509EncodedKeySpec(decoded));
        // RSA加密
        Cipher cipher = Cipher.getInstance(ALGORITHM);
        cipher.init(Cipher.ENCRYPT_MODE, pubKey);

        // 对数据分段加密
        byte[] data = str.getBytes();
        int inputLen = data.length;
        ByteArrayOutputStream out = new ByteArrayOutputStream();
        int offSet = 0;
        byte[] cache;
        int i = 0;
        while (inputLen - offSet > 0) {
            if (inputLen - offSet > MAX_ENCRYPT_BLOCK) {
                cache = cipher.doFinal(data, offSet, MAX_ENCRYPT_BLOCK);
            } else {
                cache = cipher.doFinal(data, offSet, inputLen - offSet);
            }
            out.write(cache, 0, cache.length);
            i++;
            offSet = i * MAX_ENCRYPT_BLOCK;
        }
        byte[] encryptedData = out.toByteArray();
        out.close();
        String outStr = Base64.getEncoder().encodeToString(encryptedData);

        return outStr;
    }

    /**
     * RSA私钥解密
     */
    public static String decrypt(String str, String privateKey) throws Exception {
        // 64位解码加密后的字符串
        byte[] inputByte = java.util.Base64.getDecoder().decode(str.getBytes(CHARSET));
        // base64编码的私钥
        byte[] decoded = Base64.getDecoder().decode(privateKey);
        RSAPrivateKey priKey =
            (RSAPrivateKey)KeyFactory.getInstance(ALGORITHM).generatePrivate(new PKCS8EncodedKeySpec(decoded));
        // RSA解密
        Cipher cipher = Cipher.getInstance(ALGORITHM);
        cipher.init(Cipher.DECRYPT_MODE, priKey);

        // 对数据分段解密
         byte[] encryptedData = Base64.getDecoder().decode(str);
         int inputLen = encryptedData.length;
         ByteArrayOutputStream out = new ByteArrayOutputStream();
         int offSet = 0;
         byte[] cache;
         int i = 0;
         while (inputLen - offSet > 0) {
         if (inputLen - offSet > MAX_DECRYPT_BLOCK) {
         cache = cipher.doFinal(encryptedData, offSet, MAX_DECRYPT_BLOCK);
         } else {
         cache = cipher.doFinal(encryptedData, offSet, inputLen - offSet);
         }
         out.write(cache, 0, cache.length);
         i++;
         offSet = i * MAX_DECRYPT_BLOCK;
         }
         byte[] decryptedData = out.toByteArray();
         out.close();
         String outStr =  new String(decryptedData);


        return outStr;
    }

    /**
     * 随机生成密钥对 也可以用阿里的生成工具
     */
    public static  Map<Integer, String> genKeyPair() throws NoSuchAlgorithmException {
        Map<Integer, String> keyMap = new HashMap<Integer, String>(2);
        // KeyPairGenerator类用于生成公钥和私钥对,基于RSA算法生成对象
        KeyPairGenerator keyPairGen = KeyPairGenerator.getInstance(ALGORITHM);
        // 初始化密钥对生成器,密钥大小为96-1024位
        keyPairGen.initialize(KEY_SIZE, new SecureRandom());
        // 生成一个密钥对,保存在keyPair中
        KeyPair keyPair = keyPairGen.generateKeyPair();
        RSAPrivateKey privateKey = (RSAPrivateKey)keyPair.getPrivate(); // 得到私钥
        RSAPublicKey publicKey = (RSAPublicKey)keyPair.getPublic(); // 得到公钥
        String publicKeyString = new String(Base64.getEncoder().encode(publicKey.getEncoded()));
        // 得到私钥字符串
        String privateKeyString = new String(Base64.getEncoder().encode(privateKey.getEncoded()));
        // 将公钥和私钥保存到Map
        System.out.println("公钥:" + publicKeyString);
        System.out.println("私钥:" + privateKeyString);
        keyMap.put(0, publicKeyString); // 0表示公钥
        keyMap.put(1, privateKeyString); // 1表示私钥
        return keyMap;
    }

    // 测试
    public static void main(String[] args) throws Exception {
        String content = "dahfaa老子最帅%^$##&";
        // for (int i = 0; i < 10; i++) {
        // content += content;
        // }
        System.out.println(content.getBytes().length);
        Map<Integer, String> keyMap = genKeyPair();
        String publicKey = keyMap.get(0);
        String privateKey = keyMap.get(1);
        // 支付宝RSA生成的公私钥 也同样适用,可以自行尝试
        // String publicKey =
        // "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAkGv/70Te42PS5fyuLCNr/UiMtDqhasMZpmA92aDTWjh9RT5r4Kl3sKRO63RitWuEgFAZHljJUB9afEzWnP+EGpkeiq3SMpIfpUWy89nqZxUUyOg6aIvfEZBjKFFc3umM9uasFTLC8l4NCfDnlkpHxwQjc5emUGJ5ZnqqGOmrdP5se7dyO7QEtdI7/jfbzPDmMeWyegWE5iN8CHJh2V0foBur7gS/syTnbLFcRr3wzsbXh9RyLP9OMmHx9MO1fhTOnTZnN+xWXNggTgymoUM27+bZd/nrKaZNeUF50DIyTFEe6yqwkbtVf2jeR+CNjcWO+uP7CvTpDKk+9h3DZyZ5RwIDAQAB";
        // String privateKey =
        // "MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQCQa//vRN7jY9Ll/K4sI2v9SIy0OqFqwxmmYD3ZoNNaOH1FPmvgqXewpE7rdGK1a4SAUBkeWMlQH1p8TNac/4QamR6KrdIykh+lRbLz2epnFRTI6Dpoi98RkGMoUVze6Yz25qwVMsLyXg0J8OeWSkfHBCNzl6ZQYnlmeqoY6at0/mx7t3I7tAS10jv+N9vM8OYx5bJ6BYTmI3wIcmHZXR+gG6vuBL+zJOdssVxGvfDOxteH1HIs/04yYfH0w7V+FM6dNmc37FZc2CBODKahQzbv5tl3+esppk15QXnQMjJMUR7rKrCRu1V/aN5H4I2NxY764/sK9OkMqT72HcNnJnlHAgMBAAECggEAYq4o1miMk3rl49fferFJXGtyGMPm/3gH0rL4D/ff8kme7u1T8NJawgvDEQcZWzT3+GTChQXNqD2EKmKmUegVb8coI0HZ2kwV62vQduZzT7QL26syHbVU2j96QVY2yulyNFIxStrAcbLp3d0JoJtoqAef4Z/BODPRF8DA8PzY9rrKM38EIki/lywgnhmmavfB4Z0jOi+yjL7uwj497YAC6XK5A4ZKFXYp1D5b0af7N7VyZNte/r/3nrH+/T2FpLGB3I8y/VB7cAS5GXB0GrUMOvVfnm576tukh4nOi+F0J3YxHW2AJU92RYE4qLT9nq5FsHFtu83+0Lo6C51wl4WcAQKBgQDNiM0J2gc10gNd0lv47CIUxgprKDJgxOs7xm7H+MVGzy2xpfsm3kjB/M4fHVDFLhSbqgo3TYBd9SgMxJRcmuE1HBs2Vd0NXMM+Q/XdIYA57YV3rclx7xUf95XZ2G2PFFFh45VW68KamZKufs4kbXwb3nrFgT48qkFWiKxTrXi7gQKBgQCz4d9da6+WVuDR5tURnZDATwbEefxpmSaIGbF16JAR1sY4Wnj5hB0phD0Pv0b/8+35ZpKGpK/ca7qm1VR9fEfMvP1f311ICXqovoydHktgEhTC+ictDMoHjSjJ8VHMKz+ahmQKB/AFHqReg+lfkcc3zOf/A99cvqWWkyGmq4i4xwKBgGZHjmk5o17oDJ7SwMwFjgwyZRrgHPnE5J6RZ62BoYJUNRPzWiEEesZ2LIiVSQ1mmgDAxGay3Y9kITMBXCcdN7b7LpuCbQdqQwqoPSB2vF2XUlS1Gcrlw+hth5epuRN7c+g3nahsmCHhDHpjReggx6MCuquwXi1IOE18o+zcJXmBAoGAVmTBVqkFp/sJ90YaR1+ZygMqiOrdpAn+S5erd6m+qBKzGRW6zHv7VZlBinKfswaA4Su2bBxkqkTDXKVQ8wPhqB+MwaMRtit3UdxSxJNsODP27L4gWq6tyXqugG76jkinP5wUKA0v5gWVhB9u0ou9Vrt/ISfG+1BFT1BS9S2leLkCgYAbFtXUQTNKd9IuI1pZguuwVI8US/xAOM4uTQoQx/tUO3OwgLt9iziKqg1n8GtRESAGwfbtJli85fhYSB36CdPs3ad22Y1SM6xnpLt5TnA8Vc3IuME4Y1ogH6Z3EBVvTPBb5BX2XoBvbpx8nMxtPIrh5ZkS8Cb9aoOoEhTrvEXrNw==";
        /*加解密测试*/
        String encryptContent = RSAEncrypt.encrypt(content, publicKey);
        System.out.println("加密后数据:" + encryptContent);
        String decryptContent = RSAEncrypt.decrypt(encryptContent, privateKey);
        System.out.println("解密后数据:\n" + decryptContent);

        /*加签验签测试*/
        String signOriginalContent = "验签功能测试";
        String geneSignContent = RSAEncrypt.sign(signOriginalContent, privateKey);
        System.out.println("生成的签名:\n"+geneSignContent);
        boolean valid = RSAEncrypt.isValid(signOriginalContent,geneSignContent, publicKey);
        System.out.println("结果验签:\n"+valid);

    }

}

  • 2
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
RSA算法是一种非对称加密算法,它的加密过程可以分为两个步骤:密钥生成和加密/解密。 在密钥生成过程中,需要生成一对公私钥对。公钥用于加密数据,私钥用于解密数据。RSA算法的安全性依赖于大素数的存在,因此在密钥生成过程中需要随机生成两个大素数p和q,并计算出n=p*q和φ(n)=(p-1)*(q-1)。然后选择一个整数e,使得1<e<φ(n)且e与φ(n)互质,最后计算出d,使得d*e ≡ 1 mod φ(n)。 在加密过程中,需要将明文分段加密。假设明文为m,密钥为公钥(n,e),将明文m分为若干个长度不超过n-11的块,然后对每个块进行加密。具体的加密过程为:将每个块转化为一个整数x,然后计算出密文c=x^e mod n。 在解密过程中,需要将密文分段解密。假设密文为c,密钥为私钥(n,d),将密文c分为若干个长度为n的块,然后对每个块进行解密。具体的解密过程为:将每个块转化为一个整数y,然后计算出明文m=y^d mod n。 下面是使用Qt语言实现RSA算法分段加密的示例代码: ```cpp #include <QByteArray> #include <QtMath> // 随机生成一个大素数 unsigned int generatePrime() { unsigned int prime; do { prime = qrand() % 10000 + 10000; } while (!QIntValidator(10000, 99999).isPrime(prime)); return prime; } // 计算最大公约数 unsigned int gcd(unsigned int a, unsigned int b) { if (b == 0) { return a; } else { return gcd(b, a % b); } } // 计算模反元素 unsigned int modInverse(unsigned int a, unsigned int n) { int t = 0, newt = 1; unsigned int r = n, newr = a; while (newr != 0) { int quotient = r / newr; int tmp = t; t = newt; newt = tmp - quotient * newt; tmp = r; r = newr; newr = tmp - quotient * newr; } if (r > 1) { return 0; } if (t < 0) { t += n; } return t; } // 生成公私钥对 void generateKeys(unsigned int& n, unsigned int& e, unsigned int& d) { unsigned int p = generatePrime(); unsigned int q = generatePrime(); n = p * q; unsigned int phi = (p - 1) * (q - 1); do { e = qrand() % phi + 1; } while (gcd(e, phi) != 1); d = modInverse(e, phi); } // 分段加密 QByteArray encrypt(const QByteArray& data, unsigned int n, unsigned int e) { QByteArray encryptedData; int blockSize = qFloor(qLn(n) / qLn(256)) - 1; int pos = 0; while (pos < data.size()) { QByteArray block = data.mid(pos, blockSize); unsigned int x = block.toUInt(); unsigned int c = qPow(x, e) % n; QByteArray encryptedBlock = QByteArray::number(c); encryptedData.append(encryptedBlock); pos += blockSize; } return encryptedData; } // 分段解密 QByteArray decrypt(const QByteArray& encryptedData, unsigned int n, unsigned int d) { QByteArray decryptedData; int blockSize = qFloor(qLn(n) / qLn(256)); int pos = 0; while (pos < encryptedData.size()) { QByteArray encryptedBlock = encryptedData.mid(pos, blockSize); unsigned int c = encryptedBlock.toUInt(); unsigned int y = qPow(c, d) % n; QByteArray block = QByteArray::number(y); while (block.size() < blockSize) { block.prepend('\0'); } decryptedData.append(block); pos += blockSize; } return decryptedData; } ```
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值