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

📄 richrsacipher.java

📁 加密算法
💻 JAVA
📖 第 1 页 / 共 2 页
字号:
//package com.richware.chap12;

import java.io.*;
import java.math.BigInteger;
import java.security.*;
import java.security.interfaces.*;
import java.security.spec.*;
import javax.crypto.*;
import sun.misc.*;


/**
 * Class RichRSACipher
 * Description: This is an example of a
 * simple RSA Encryption
 * RSA information is from PKCS#1v2.0
 * a publicaton from RSA Security
 *
 * Copyright:    Copyright (c) 2002 Wiley Publishing, Inc.
 * @author Rich Helton <rhelton@richware.com>
 * @version 1.0  01-FEB-2002
* DISCALIMER: Limit of Liability/Disclaimer of Warranty:
* This code is used for educational purposes only. This software is provided "As Is" and
* there are no implied warranties. While the publisher and author
* have used their best efforts in preparing this book and software, they make no
* representations or warranties and specifically disclaim any implied
* warranties of merchantability or fitness for a particular purpose. No
* warranty may be created or extended by sales representatives or written
* sales materials. The advice and strategies contained herein may not be
* suitable for your situation. You should consult with a professional where
* appropriate. Neither the publisher nor author shall be liable for any loss
* of profit or any other commercial damages, including but not limited to
* special, incidental, consequential, or other damages, including, but not limited to,
* procurement of substitute goods or services, loss of use, data, profits, or business
* interruption by cause of use or theory of use arising in any damage.
 */
public final class RichRSACipher extends CipherSpi
 {

  private RSAKeyGenParameterSpec params_;//该类对象用来接收rsa算法的密钥对生成参数:即密钥长度和模数.
                                         //该类有一个方法public RSAKeyGenParameterSpec(int keysize, BigInteger publicExponent)
  private SecureRandom           random_;

  private final static boolean   TESTNEEDED = true;

  private int                    opmode_;//有四种模式:ENCRYPT_MODE(加密)DECRYPT_MODE(解密)WRAP_MODE(包装)UNWRAP_MODE(解包)
                                         //后两种用于利用一个密钥对另一个密钥加密.
  private Key                    key_;

  private byte[]                 internal_buffer_;

  /**
   * Constructor RichRSACipher
   *
   *
   */
  public RichRSACipher() {}

  /**
   * Method engineDoFinal
   * Description: See CipherSpi
   */
  protected byte[] engineDoFinal(
          byte[] input, int inputOffset, int inputLen)
            throws IllegalBlockSizeException,
                   BadPaddingException
   {

    byte[] output = engineUpdate(input, inputOffset, inputLen);

    internal_buffer_ = null;

    return output;
  }

  /**
   * Method engineDoFinal
   * Description: See CipherSpi
   */
  protected int engineDoFinal(
          byte[] input, int inputOffset, int inputLen, byte[] output, int outputOffset)
            throws ShortBufferException,
                   IllegalBlockSizeException,
                   BadPaddingException
   {

    byte[] buffer;

    buffer = engineDoFinal(input, inputOffset, inputLen);

    if (output.length - outputOffset < buffer.length)
     {
      throw new ShortBufferException(
        "Output longer than buffer");
    }

    System.arraycopy(buffer, 0, output, outputOffset,
                     buffer.length);

    return buffer.length;
  }

  /**
   * Method engineGetBlockSize
   * Description: See CipherSpi
   */
  protected int engineGetBlockSize()
   {

    if ((opmode_ == Cipher.ENCRYPT_MODE)
            || (opmode_ == Cipher.WRAP_MODE))
     {
      return params_.getKeysize();
     }
    else
     {
      return params_.getKeysize() - 1;
     }
  }

  /**
   * Method engineGetIV
   * Description: See CipherSpi
   */
  protected byte[] engineGetIV()
   {
    return null;  // If not supported 本算法不需要此项,该函数是父类的抽象函数,必须实现的.所以可以什么也不干,因为不会用到.
  }


  /**
   * Method engineGetKeySize
   * Description: See CipherSpi
   */
  protected int engineGetKeySize(Key key)
          throws InvalidKeyException
   {

    /*
     * Get the key size based on bit length
     */
    if (key instanceof RSAPrivateKey)
     {
      RSAPrivateKey k = (RSAPrivateKey) key;

      return k.getModulus().bitLength();
    }
    else if (key instanceof RSAPublicKey)
     {
      RSAPublicKey k = (RSAPublicKey) key;

      return k.getModulus().bitLength();
    }

    throw new InvalidKeyException("Unsupported RSA key!");
  }



  /**
   * Method engineGetOutputSize
   * Description: See CipherSpi
   */
  protected int engineGetOutputSize(int inputLen)
   {

    if ((opmode_ == Cipher.ENCRYPT_MODE)
            || (opmode_ == Cipher.WRAP_MODE))
     {
      return params_.getKeysize();
    }
    else
     {
      return params_.getKeysize() - 1;
    }
  }

  /**
   * Method engineGetParameters
   * Description: See CipherSpi
   */
  protected AlgorithmParameters engineGetParameters()
   {
    return null;
  }//not supported!

  /**
   * Method engineInit
   * Description: See CipherSpi
   */
  protected void engineInit(
          int opmode, Key _key, AlgorithmParameterSpec params, SecureRandom _random)
            throws InvalidKeyException,
                   InvalidAlgorithmParameterException
   {

    // Check for valid key
    if ((!(_key instanceof RSAPublicKey))
            && (!(_key instanceof RSAPrivateKey)))
     {
      throw new InvalidKeyException("Unsupported RSA Key!");
    }

    // Check for valid Parameter Spec
    if ((params != null)
            && (!(params instanceof RSAKeyGenParameterSpec)))
     {
      throw new InvalidAlgorithmParameterException(
        "Unsupported RSA AlgorithmParameterSpec!");
    }

    // Initialize the params
    if (params != null)
     {
      params_ = (RSAKeyGenParameterSpec) params;
    }
    else
     {
      int        keysize   = 0;
      BigInteger publicExp = null;

      if (_key instanceof RSAPublicKey)
       {
        publicExp = ((RSAPublicKey) _key).getPublicExponent();

        int modulusLength =
          ((RSAPublicKey) _key).getModulus().bitLength();

        keysize = (modulusLength + 7) / 8;//为填充做准备.keysize为字节数
      }
      else if (_key instanceof RSAPrivateKey)
       {
        int modulusLength =
          ((RSAPrivateKey) _key).getModulus().bitLength();

        keysize = (modulusLength + 7) / 8;
      }
          if(TESTNEEDED){
           System.out.println("RichRSACipher:engineInit:keysize:" + keysize);
          }

      params_ = new RSAKeyGenParameterSpec(keysize, publicExp);
    }

    random_ = _random;

    // Check for valid types of opmode
    if ((opmode == Cipher.DECRYPT_MODE)
            || (opmode == Cipher.ENCRYPT_MODE)
            || (opmode == Cipher.UNWRAP_MODE)
            || (opmode == Cipher.WRAP_MODE))
     {
      if (((opmode == Cipher.DECRYPT_MODE) || (opmode == Cipher
              .UNWRAP_MODE)) && (_key instanceof RSAPublicKey))
       {
        throw new InvalidKeyException(
          "Unsupported: Decrypt/UnWrap mode must use RSAPrivateKey");
      }

      if (((opmode == Cipher.ENCRYPT_MODE) || (opmode == Cipher
              .WRAP_MODE)) && (_key instanceof RSAPrivateKey))
       {
        throw new InvalidKeyException(
          "Unsupported: Encrypt/Wrap mode must use RSAPublicKey");
      }
      if(TESTNEEDED){
        if ((opmode == Cipher.DECRYPT_MODE) || (opmode == Cipher.UNWRAP_MODE)){
           System.out.println("RichRSACipher:engineInit:DECRYPT_MODE");
        }else{
           System.out.println("RichRSACipher:engineInit:ENCRYPT_MODE");
        }
       }
    }
    else
     {
      throw new InvalidKeyException("Unsupported opmode!");
    }
    opmode_ = opmode;
    key_ = _key;
  }

  /**
   * Method engineInit
   * Description: See CipherSpi
   */
  protected void engineInit(
          int opmode, Key _key, AlgorithmParameters params, SecureRandom _random)
            throws InvalidKeyException,
                   InvalidAlgorithmParameterException
   {

    /*
     * Note _key is used instead of key, becauuase Key is a class.
     * Random is also a class.
     */
    engineInit(opmode, _key, (AlgorithmParameterSpec) null,
               _random);
  }

  /**
   * Method engineInit
   * Description: See CipherSpi
   */
  protected void engineInit(
          int opmode, Key _key, SecureRandom _random)
            throws InvalidKeyException
   {

    try
     {
      engineInit(opmode, _key, (AlgorithmParameterSpec) null,
                 _random);
    }
    catch (InvalidAlgorithmParameterException ex)
     {
      throw new InvalidKeyException(ex.getMessage());
    }
  }

  /**
   * Method engineSetMode
   * Description: See CipherSpi
   */
  protected void engineSetMode(String mode)
          throws NoSuchAlgorithmException
   {

    if (!mode.equalsIgnoreCase("ECB"))
     {
      throw new NoSuchAlgorithmException(
        "RSA supports only ECB mode");
    }
  }

  /**
   * Method engineSetPadding
   * Description: See CipherSpi
   */
  protected void engineSetPadding(String s)
          throws NoSuchPaddingException
   {

    // Only accepts avaliable padding
    if (!s.equalsIgnoreCase("PKCS1_V1_5"))
     {
      throw new NoSuchPaddingException("Unknown padding: "
                                       + s);
    }
  }//pkcs1_v1_5 is default padding mode

  /**
   * Method engineUpdate
   * Description: See CipherSpi
   */
  protected byte[] engineUpdate(byte[] input, int inputOffset,
                             int inputLen)
   {//这个函数的意思:将input数组加密,加密范围从第一个字节到inputOffset+inputLen,也就是说后面的内容加密不加密不用考虑了.
    //其实这个是个比较差劲的方法,不过cipher类中有这个方法,就先实现吧.在毕业设计中将不使用此算法,仅仅是为了完善rsa算法供其他用途用.

    try
     {
      if (inputOffset > 0)
       {
        int    outputSize = inputOffset + inputLen;
        byte[] tmp        = new byte[outputSize];

        System.arraycopy(input, inputOffset, internal_buffer_,
                         internal_buffer_.length, inputLen);

        if ((opmode_ == Cipher.ENCRYPT_MODE)
                || (opmode_ == Cipher.WRAP_MODE))
         {
          return (encrypt(internal_buffer_));
         }
        else
         {
          return (decrypt(internal_buffer_));
         }
       }
      else//inpuOffset<=0
       {
        internal_buffer_ = new byte[inputLen];//第一次,需要初始化,所以和上面的分开,因为没有初始化必须初始化,上面的函数是已经初始化了的,不能再初始化

        System.arraycopy(input, 0, internal_buffer_,0, inputLen);

        if ((opmode_ == Cipher.ENCRYPT_MODE)
                || (opmode_ == Cipher.WRAP_MODE))
         {
          if(TESTNEEDED){
           System.out.println("RichRSACipher:engineUpdate:encrypting");
          }
          return (encrypt(internal_buffer_));
        }
        else
         {
          if(TESTNEEDED){
           System.out.println("RichRSACipher:engineUpdate:decrypting");
          }
          return (decrypt(internal_buffer_));
        }
      }
    }

    /*
     * Catches
     */
    catch (Exception ex)
     {
      ex.printStackTrace();
    }

    return null;
  }

  /**
   * Method engineUpdate
   * Description: See CipherSpi
   */
  protected int engineUpdate(
          byte[] input, int inputOffset, int inputLen, byte[] output, int outputOffset)
            throws ShortBufferException
   {

    byte[] buffer;

    buffer = engineUpdate(input, inputOffset, inputLen);

    if (output.length - outputOffset < buffer.length)
     {
      throw new ShortBufferException(
        "Output longer than buffer");
    }

    System.arraycopy(buffer, 0, output, outputOffset,
                     buffer.length);

    return buffer.length;
  }

  /**
   * Method I2OSP
   * Description: Integer to Octet String Primitive
   * See PKCS#1
   */
  private byte[] I2OSP(BigInteger x, int l)//********************************
          throws IllegalBlockSizeException
   {

    /*
     * Section 4.1 of PKCS#1v2.0
     * I2OSP converts a nonnegative integer to an octet string
     * of a specified length. I2OSP (x, l)
     * Input: x nonnegative integer to be converted
     * l intended length of the resulting octet string
     * Output: X corresponding octet string of length l; or
     * integer too large
     * Steps:
     */

⌨️ 快捷键说明

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