RSA加密 分割加密解密

参加比赛做了面对医患的作品,中间用到RSA了,因为不止要加密字符串,还要加密图片,病例等。但java自带的类限制了加密长度。。。所以要采用分割加密,分割解密,不然会出现Data must not be longer than 117 bytes之类的问题

然后我就各种谷歌。。stackoverflow。。。就成功了

项目目录结构。。jdk是1.8,java8中带有Rsa的类


1.GetKey(读取公钥和私钥)  

2.RsaTool(文件的加密和解密)

3.TesRsa(测试)


上代码

GetKey.java

package com.test;
import java.security.KeyFactory;
import java.security.KeyPair;
import java.security.KeyPairGenerator;
import java.security.PrivateKey;
import java.security.PublicKey;
import java.security.SecureRandom;
import java.security.interfaces.RSAPrivateKey;
import java.security.interfaces.RSAPublicKey;
import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.X509EncodedKeySpec;
import java.util.Base64;
import java.util.Date;
import java.io.*;
import java.nio.ByteBuffer;


import javax.crypto.Cipher;

public class GetKey {

//生成公私钥

    public static void geration(){
        KeyPairGenerator keyPairGenerator;
        try {
            keyPairGenerator = KeyPairGenerator.getInstance("RSA");
            SecureRandom secureRandom = new SecureRandom(new Date().toString().getBytes());
            keyPairGenerator.initialize(1024, secureRandom);
            KeyPair keyPair = keyPairGenerator.genKeyPair();
            byte[] publicKeyBytes = keyPair.getPublic().getEncoded();
            FileOutputStream fos = new FileOutputStream("c:/key/PUBLIC_KEY.key");
            fos.write(publicKeyBytes);
            fos.close();
            byte[] privateKeyBytes = keyPair.getPrivate().getEncoded();
            fos = new FileOutputStream("c:/key/PRIVATE_KEY.key");
            fos.write(privateKeyBytes);
            fos.close();
        } catch (Exception e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }


    public static PublicKey getPublicKey(String filename) throws Exception {
        File f = new File(filename);
        FileInputStream fis = new FileInputStream(f);
        DataInputStream dis = new DataInputStream(fis);
        byte[] keyBytes = new byte[(int)f.length()];
        dis.readFully(keyBytes);
        dis.close();
        X509EncodedKeySpec spec = new X509EncodedKeySpec(keyBytes);
        KeyFactory kf = KeyFactory.getInstance("RSA");
        return kf.generatePublic(spec);
    }


    public static PrivateKey getPrivateKey(String filename)throws Exception {
        File f = new File(filename);
        FileInputStream fis = new FileInputStream(f);
        DataInputStream dis = new DataInputStream(fis);
        byte[] keyBytes = new byte[(int)f.length()];
        dis.readFully(keyBytes);
        dis.close();
        PKCS8EncodedKeySpec spec =new PKCS8EncodedKeySpec(keyBytes);
        KeyFactory kf = KeyFactory.getInstance("RSA");
        return kf.generatePrivate(spec);
    }

}



2.RsaTool.java

package com.test;


import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.ObjectInputStream;
import java.security.PrivateKey;
import java.security.PublicKey;
import java.security.interfaces.RSAPrivateKey;
import java.security.interfaces.RSAPublicKey;


import javax.crypto.Cipher;


public class RsaTool {
public static void enCryptFor(File file)
    {
        try
        {
                  //得到要加密文件
                  FileInputStream fileInputStream = new FileInputStream(file);
                  byte[] decryptedFileBytes = new byte[fileInputStream.available()];
                  fileInputStream.read(decryptedFileBytes);
                  fileInputStream.close();


                //得到公钥
             
              
                  PublicKey publicKey =(RSAPublicKey)GetKey.getPublicKey("c:/key/PUBLIC_KEY.key");
            //加密
            Cipher cipher = Cipher.getInstance("RSA");
            cipher.init(Cipher.ENCRYPT_MODE, publicKey);


                  //Rsa要求不得超过117
              int decryptedFileBytesChunkLength = 100;
              int numberenOfDecryptedChunks = (decryptedFileBytes.length-1) / decryptedFileBytesChunkLength + 1;


                  //RSA需要输出128
              int encryptedFileBytesChunkLength = 128;
              int encryptedFileBytesLength = numberenOfDecryptedChunks * encryptedFileBytesChunkLength;



            byte[] encryptedFileBytes = new byte[ encryptedFileBytesLength ];


    
            int decryptedByteIndex = 0;
            int encryptedByteIndex = 0;


            for(int i = 0; i < numberenOfDecryptedChunks; i++)
            {
                        if(i < numberenOfDecryptedChunks - 1)
                        {
                      encryptedByteIndex = encryptedByteIndex + cipher.doFinal(decryptedFileBytes, decryptedByteIndex, decryptedFileBytesChunkLength, encryptedFileBytes, encryptedByteIndex);
                      decryptedByteIndex = decryptedByteIndex + decryptedFileBytesChunkLength;
                        }
                        else
                        {
                              cipher.doFinal(decryptedFileBytes, decryptedByteIndex, decryptedFileBytes.length - decryptedByteIndex, encryptedFileBytes, encryptedByteIndex);
                        }
                  }


            //保存
            FileOutputStream fileOutputStream = new FileOutputStream(file);
                  fileOutputStream.write(encryptedFileBytes);
                  fileOutputStream.flush();
                  fileOutputStream.close();


                  System.out.println("length: "+ decryptedFileBytes.length);
                  System.out.println("length: "+ encryptedFileBytes.length);
                  System.out.println("Encryption done");
        }
        catch (Exception e)
        {
            e.printStackTrace();
        }
    }


      public static void deCryptFor(File file)
      {
            try
            {
                  //得到要解密文件
                  FileInputStream fileInputStream = new FileInputStream(file);
                  byte[] encryptedFileBytes = new byte[fileInputStream.available()];
                  fileInputStream.read(encryptedFileBytes);
                  fileInputStream.close();


                  //得到密钥
                  
             
                  PrivateKey privateKey =(RSAPrivateKey)GetKey.getPrivateKey("c:/key/PRIVATE_KEY.key");
                  //解密
                  Cipher cipher = Cipher.getInstance("RSA");
                cipher.init(Cipher.DECRYPT_MODE, privateKey);


              //RSA 需要输出128
              int encryptedFileBytesChunkLength = 128;
                  int numberOfEncryptedChunks = encryptedFileBytes.length / encryptedFileBytesChunkLength;


                  //rsa每次输入长度不得超过117
              int decryptedFileBytesChunkLength = 100;
              int decryptedFileBytesLength = numberOfEncryptedChunks * encryptedFileBytesChunkLength;

                

                 byte[] decryptedFileBytes = new byte[decryptedFileBytesLength];



             
                int decryptedByteIndex = 0;
                int encryptedByteIndex = 0;


                  for(int i = 0; i < numberOfEncryptedChunks; i++)
                  {
                        if( i < numberOfEncryptedChunks -1 )
                        {
                              decryptedByteIndex = decryptedByteIndex + cipher.doFinal(encryptedFileBytes, encryptedByteIndex, encryptedFileBytesChunkLength, decryptedFileBytes, decryptedByteIndex);
                              encryptedByteIndex = encryptedByteIndex + encryptedFileBytesChunkLength;
                        }
                        else
                        {
                              decryptedByteIndex = decryptedByteIndex + cipher.doFinal(encryptedFileBytes, encryptedByteIndex, encryptedFileBytes.length - encryptedByteIndex, decryptedFileBytes, decryptedByteIndex);
                        }
                  }


                  //保存解密文件
                  FileOutputStream fileOutputStream = new FileOutputStream(file);
                  fileOutputStream.write(decryptedFileBytes);
                  fileOutputStream.flush();
                  fileOutputStream.close();


                  System.out.println("length: "+ encryptedFileBytes.length);
                  System.out.println("length: "+ decryptedFileBytes.length);
                  System.out.println("Decryption done");
            }
            catch (Exception e)
            {
                e.printStackTrace();
            }
      }
}


3.TestRsa

package com.test;


import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.ObjectInputStream;
import java.security.PrivateKey;
import java.security.PublicKey;


import javax.crypto.Cipher;


public class TestRsa {

public static void main(String[] args) {
File file=new File("c:/key/123.xls");

RsaTool tool=new RsaTool();
    
tool.enCryptFor(file);

tool.deCryptFor(file);
}
}

测试结果:

未加密前-》


加密后-》


解密-》



欢迎大家指正。。。


猜你喜欢

转载自blog.csdn.net/weixin_37595711/article/details/80537165