⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 rsaencryption.java

📁 对称和非对称加密
💻 JAVA
📖 第 1 页 / 共 2 页
字号:
package com.dmgc.security.cipher.unsymmetic.rsa;

import com.dmgc.security.cipher.util.*;
import java.io.*;

/**
 * <p>Title: DMGC SECURITY CIPHER LIB</p>
 * <p>Description: 上海信宁科技有限公司 安全密码库(JAVA version)</p>
 * <p>Copyright: Copyright (c) 2003</p>
 * <p>Company: 上海信宁科技有限公司</p>
 * <p>RSA加密算法:主要有四种方式
 * <p>对短信息的加密:这里短信息可以是会话双方的交换密钥,对于1024比特的RSA加密
 * 算法短信息长度小于等于117个字节,这是因为128-3-8,减去3个标志位,减去大于等于8个
 * 填空位.所得.
 * <p>方法一:公钥N,E是字符串(DMGCMPINTEGER)形式,输入消息是字节数组,输出消息是字节数组
 * <p>方法二:公钥N,E是文件(二进制文件)形式,输入消息是字节数组,输出消息是字节数组
 * <p>对文件的加密:
 * <p>1.将文件每次读取7488   (8192)字节到缓冲区
 * <p>2.计算模n的大小k
 * <p>3.每次选择s=k-11字节,最后一次可能S小于k-11
 * <p>4.0x00 0x02作为开头两个字节 填充k-s-3个非0x00字节,再加上0x00字节,最后接上s个字节
 * <p>5.加密这个k的明文消息
 * <p>6.转化为大整数m
 * <p>7.加密得到密文大整数c
 * <p>8.恢复为字节数组,如果长度小于k,则前面填充若干个0x00,构成k长度,然后将字节数组写入输出文件
 * <p>9.每次读缓存里,最后一块的填充位可能会多一些
 * <p>10.通过这种方式,密文扩张约等于8%. 密文:明文=108.6%
 * <p>方法三:公钥N,E是字符串(DMGCMPINTEGER)形式,输入是文件,输出是文件
 * <p>方法四:公钥N,E是文件(二进制文件)形式,输入是文件,输出是文件
 * @author 陆荣幸  周渊   潘勇
 * @version 1.0
 */

public class RSAEncryption {
  /**
   * 构造函数
   */
  public RSAEncryption() {
  }

  /**
   * 测试用
   * @param args
   */
  public static void main(String[] args) {
    RSAEncryption RSAEncryption1 = new RSAEncryption();
    try {
      RSAEncryption1.FileEncryptionF("D:\\lurongxing.modulus", "D:\\lurongxing.public",
                                     "D:\\test.gz", "d:\\abc");
    }
    catch (IOException ex) {
      ex.printStackTrace();
    }
  }

  /**
   * 生成非零填充位
   * @param k 字节数组长度
   * @return 非零字节数组
   */
  private byte[] getPadding(int k) {
    byte[] ret = new byte[k];
    for (int i = 0; i < k; i++) {
      ret[i] = DmgcMpInteger.getOneNonZeroByte();
    }
    return ret;
  }

  /**
   * 第一种方式对短消息进行加密
   * @param n RSA大整数模
   * @param e RSA加密指数
   * @param plainText RSA明文
   * @return  返回密文字节数组
   * @throws MessageTooLongException  如果消息太长,抛这个异常
   */
  public byte[] MessageEncryption(String n, String e, byte[] plainText) throws
      MessageTooLongException {
    byte[] ret = new byte[128];
    byte[] org = new byte[128];
    int length = plainText.length;
    if (length > 117) {
      throw new MessageTooLongException("too large message");
    }
    // 开头两位标志位
    org[0] = 0x00;
    org[1] = 0x02;
    int padCount = 128 - length - 3;
    // 填空位
    byte[] padding = getPadding(padCount);
    System.arraycopy(padding, 0, org, 2, padCount);
    //标志位
    org[padCount + 2] = 0x00;
    //明文位
    System.arraycopy(plainText, 0, org, padCount + 3, length);
    //加密
    DmgcMpInteger ee = new DmgcMpInteger(e);
    DmgcMpInteger nn = new DmgcMpInteger(n);
    DmgcMpInteger ppp = new DmgcMpInteger(org);
    DmgcMpInteger cc = ppp.modPow(ee, nn);
    // 如果密文不是128字节也要填充0x00
    byte[] temp = cc.toByteArray();
    length = temp.length;
    padCount = 128 - length;
    if (padCount > 0) {
      byte[] paddZero = new byte[padCount];
      for (int i = 0; i < padCount; i++) {
        paddZero[i] = 0x00;
      }
      System.arraycopy(paddZero, 0, ret, 0, padCount);
      System.arraycopy(temp, 0, ret, padCount, length);
    }
    else {
      System.arraycopy(temp, 0, ret, padCount, length);
    }
    return ret;
  }

  /**
   * 第二种方式对短消息进行加密
   * @param nfilename RSA大整数模的文件
   * @param efilename RSA加密指数的文件
   * @param plainText RSA明文
   * @return  返回密文字节数组
   * @throws MessageTooLongException  如果消息太长,抛这个异常
   * @throws FileNotFoundException  如果密钥文件没有找到,抛这个异常
   * @throws IOException  如果读取文件有问题,抛这个异常
   */
  public byte[] MessageEncryptionF(String nfilename, String efilename,
                                   byte[] plainText) throws
      MessageTooLongException, FileNotFoundException, IOException {
    byte[] ret = new byte[128];
    byte[] org = new byte[128];
    int length = plainText.length;
    if (length > 117) {
      throw new MessageTooLongException("too large message");
    }
    // 开头两位标志位
    org[0] = 0x00;
    org[1] = 0x02;
    int padCount = 128 - length - 3;
    // 填空位
    byte[] padding = getPadding(padCount);
    System.arraycopy(padding, 0, org, 2, padCount);
    //标志位
    org[padCount + 2] = 0x00;
    //明文位
    System.arraycopy(plainText, 0, org, padCount + 3, length);
    //加密
    //  输入文件
    try {
      FileInputStream fInputN = new FileInputStream(nfilename);
      FileInputStream fInputE = new FileInputStream(efilename);
      byte[] BufferN = new byte[128];
      byte[] BufferE = new byte[128];
      int lengthN = fInputN.read(BufferN);
      int lengthE = fInputE.read(BufferE);
      byte[] N = new byte[lengthN];
      System.arraycopy(BufferN, 0, N, 0, lengthN);
      byte[] E = new byte[lengthE];
      System.arraycopy(BufferE, 0, E, 0, lengthE);

      fInputN.close();
      fInputE.close();

      DmgcMpInteger ee = new DmgcMpInteger(E);
      DmgcMpInteger nn = new DmgcMpInteger(N);
      DmgcMpInteger ppp = new DmgcMpInteger(org);
      DmgcMpInteger cc = ppp.modPow(ee, nn);
      // 如果密文不是128字节也要填充0x00
      byte[] temp = cc.toByteArray();
      length = temp.length;
      padCount = 128 - length;
      if (padCount > 0) {
        byte[] paddZero = new byte[padCount];
        for (int i = 0; i < padCount; i++) {
          paddZero[i] = 0x00;
        }
        System.arraycopy(paddZero, 0, ret, 0, padCount);
        System.arraycopy(temp, 0, ret, padCount, length);
      }
      else {
        System.arraycopy(temp, 0, ret, padCount, length);
      }
    }
    catch (FileNotFoundException ex) {
      throw new FileNotFoundException("file not found");
    }
    catch (IOException ex) {
      throw new IOException("IO  Exception");
    }

    return ret;
  }

  /**
   * 第三方式:对文件进行加密操作
   * @param n RSA大整数模
   * @param e RSA加密指数
   * @param inFile 要加密的文件
   * @param outFile  输出的密文文件
   * @return  真,操作成功,假,操作失败
   * @throws FileNotFoundException 文件异常
   * @throws IOException 输入输出异常
   */
  public boolean FileEncryption(String n, String e, String inFile,
                                String outFile) throws FileNotFoundException,
      IOException {
    boolean ret = false;
    // 加密指数  模
    DmgcMpInteger ee = new DmgcMpInteger(e);
    DmgcMpInteger nn = new DmgcMpInteger(n);
    //
    byte[] dest = new byte[128];
    byte[] org = new byte[128];
    byte[] temp = new byte[117];
    //
    byte[] buffer = new byte[7488];
    int bufferLength = 0;
    //
    FileInputStream fInput = null;
    FileOutputStream fOutput = null;
    //
    try {
      //  输入文件
      fInput = new FileInputStream(inFile);
      //  输出文件
      fOutput = new FileOutputStream(outFile);

      //
      while ( (bufferLength = fInput.read(buffer)) != -1) {
        int i = 0;
        for (i = 0; i < bufferLength; i = i + 117) {
          // 每次读取117个字节
          // 如果取到最后一次,则跳出
          if (i + 117 > bufferLength) {
            break;
          }
          // 每次117字节
          System.arraycopy(buffer, i, temp, 0, 117);
          // 开头两位标志位
          org[0] = 0x00;
          org[1] = 0x02;
          int padCount = 8; //128 -length - 3;
          // 填空位
          byte[] padding = getPadding(padCount);
          System.arraycopy(padding, 0, org, 2, padCount);
          //标志位
          org[padCount + 2] = 0x00;
          //明文位
          System.arraycopy(temp, 0, org, padCount + 3, 117);
          // 加密
          DmgcMpInteger ppp = new DmgcMpInteger(org);
          DmgcMpInteger cc = ppp.modPow(ee, nn);
          // 如果密文不是128字节也要填充0x00
          byte[] tempc = cc.toByteArray();
          int length = tempc.length;
          padCount = 128 - length;
          if (padCount > 0) {
            byte[] paddZero = new byte[padCount];
//            for (int j = 0; j < padCount; j++) {
//              paddZero[j] = 0x00;
//            }
            System.arraycopy(paddZero, 0, dest, 0, padCount);
            System.arraycopy(tempc, 0, dest, padCount, length);
          }
          else {
            System.arraycopy(tempc, 0, dest, padCount, length);
          }
          //
          fOutput.write(dest, 0, 128);

        } // end for
        // 如果有多余字节则进行下面操作
        if ((i !=0)&& (i < bufferLength) && ( (bufferLength - i) > 0)) {
          int length = bufferLength - i;
          System.arraycopy(buffer, i, temp, 0, length);
          byte[] temp2 = new byte[length];
          System.arraycopy(temp, 0, temp2, 0, length);
          // 开头两位标志位
          org[0] = 0x00;
          org[1] = 0x02;
          int padCount = 128 - length - 3;
          // 填空位
          byte[] padding = getPadding(padCount);
          System.arraycopy(padding, 0, org, 2, padCount);
          //标志位
          org[padCount + 2] = 0x00;
          //明文位
          System.arraycopy(temp2, 0, org, padCount + 3, length);
          //加密
          DmgcMpInteger ppp = new DmgcMpInteger(org);
          DmgcMpInteger cc = ppp.modPow(ee, nn);
          // 如果密文不是128字节也要填充0x00
          byte[] tempc = cc.toByteArray();
          length = tempc.length;
          padCount = 128 - length;
          if (padCount > 0) {
            byte[] paddZero = new byte[padCount];
//            for (int j = 0; j < padCount; j++) {
//              paddZero[j] = 0x00;
//            }

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -