pkcs1填充算法(源)

来源:互联网 发布:ubuntu搜狗输入法 使用 编辑:程序博客网 时间:2024/06/06 04:04

import java.security.SecureRandom;

 

/**
 * 用于RSA非对称密钥运算时,运算数据的是填充
 * @author lvLiang
 * @Aug 31, 2010 4:47:23 PM
 * @version 1.00
 */
public class PKCS1Encoding  {
 
 
 private static final int HEADER_LENGTH = 10;
 private SecureRandom random;
 private int bitSize;
 private boolean forEncryption;
 private boolean forPrivateKey;
 private int inblockSize;
 private int outblockSize;
 
 /**
  *
  * @param modulus RSA 密钥的模长
  * @param forEncryption true加密填充 false 解密填充
  * @param forPrivateKey true私钥  false公钥
  */
 public PKCS1Encoding(int modulus,boolean forEncryption,boolean forPrivateKey) {
  bitSize = modulus;
  this.random = new SecureRandom();
  this.forPrivateKey = forPrivateKey;
  this.forEncryption = forEncryption;
  if(forEncryption){
   inblockSize = (bitSize + 7) / 8 - 1;
   outblockSize = (bitSize + 7) / 8;
  }else{
   inblockSize = (bitSize + 7) / 8;
   outblockSize = (bitSize + 7) / 8 - 1;
  }
 }

 /**
  * 得到输入的数据大小(数据应该不大于此大小)
  * @return 输入的数据大小(数据应该不大于此大小)
  */
 public int getInputBlockSize() {
  
  if (forEncryption) {
   return inblockSize - HEADER_LENGTH;
  } else {
   return inblockSize;
  }
 }

 
 /** 
  * 得到输出的数据大小
  * @return 输出的数据大小
  */
 public int getOutputBlockSize() {

  if (forEncryption) {
   return outblockSize;
  } else {
   return outblockSize - HEADER_LENGTH;
  }
 }

 /**
  * 返回pkcs1填充后的数据
  * @param inData 要进行填充的数据(不能超过128字节)
  * @param inOff 填充起始位置
  * @param inLen 要填充的数据长度
  * @return pkcs1填充后的数据
  * @throws InvalidCipherTextException
  */
 public byte[] processBlock(byte[] inData, int inOff, int inLen)
   throws InvalidCipherTextException {
  if (forEncryption) {
   return encodeBlock(inData, inOff, inLen);
  } else {
   return decodeBlock(inData, inOff, inLen);
  }
 }

 private byte[] encodeBlock(byte[] in, int inOff, int inLen)
   throws InvalidCipherTextException {
  if (inLen > getInputBlockSize()) {
   throw new InvalidCipherTextException("input data too large");
  }

  byte[] block = new byte[inblockSize+1];
  if (forPrivateKey) {
   block[0] = 0x00; // type code 1
   block[1] = 0x01; // type code 2
   for (int i = 2; i != block.length - inLen - 1; i++) {
    block[i] = (byte) 0xFF;
   }
  } else {
   random.nextBytes(block); // random fill
   block[0] = 0x00; // type code 2
   block[1] = 0x02; // type code 2

   //
   // a zero byte marks the end of the padding, so all
   // the pad bytes must be non-zero.
   //
   for (int i = 2; i != block.length - inLen - 1; i++) {
    while (block[i] == 0) {
     block[i] = (byte) random.nextInt();
    }
   }
  }

  block[block.length - inLen - 1] = 0x00; // mark the end of the padding
  System.arraycopy(in, inOff, block, block.length - inLen, inLen);
  
  return block;
 }

 
 
 private byte[] decodeBlock(byte[] block, int inOff, int inLen)
   throws InvalidCipherTextException {
  //输入必须大于117
  if (block.length < getOutputBlockSize()) {
   throw new InvalidCipherTextException("block truncated");
  }

  byte type = block[1];

  if (type != 1 && type != 2) {
   throw new InvalidCipherTextException("unknown block type");
  }
  //并且输入数据长度必须等于128
  if (block.length != outblockSize + 1) {
   throw new InvalidCipherTextException("block incorrect size");
  }

  //
  // find and extract the message block.
  //
  int start;

  for (start = 2; start != block.length; start++) {
   byte pad = block[start];

   if (pad == 0) {
    break;
   }
   if (type == 1 && pad != (byte) 0xff) {
    throw new InvalidCipherTextException("block padding incorrect");
   }
  }

  start++; // data should start at the next byte

  if (start > block.length || start < HEADER_LENGTH) {
   throw new InvalidCipherTextException("no data in block");
  }

  byte[] result = new byte[block.length - start];

  System.arraycopy(block, start, result, 0, result.length);

  return result;
 }
}

原创粉丝点击