📄 richrsacipher.java
字号:
//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 + -