This program tests the RSA cipher
/*
This program is a part of the companion code for Core Java 8th ed.
(http://horstmann.com/corejava)
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.OutputStream;
import java.security.GeneralSecurityException;
import java.security.Key;
import java.security.KeyPair;
import java.security.KeyPairGenerator;
import java.security.SecureRandom;
import javax.crypto.Cipher;
import javax.crypto.KeyGenerator;
import javax.crypto.SecretKey;
/**
* This program tests the RSA cipher. Usage:<br>
* java RSATest -genkey public private<br>
* java RSATest -encrypt plaintext encrypted public<br>
* java RSATest -decrypt encrypted decrypted private<br>
* @author Cay Horstmann
* @version 1.0 2004-09-14
*/
public class RSATest
{
public static void main(String[] args)
{
try
{
if (args[0].equals("-genkey"))
{
KeyPairGenerator pairgen = KeyPairGenerator.getInstance("RSA");
SecureRandom random = new SecureRandom();
pairgen.initialize(KEYSIZE, random);
KeyPair keyPair = pairgen.generateKeyPair();
ObjectOutputStream out = new ObjectOutputStream(new FileOutputStream(args[1]));
out.writeObject(keyPair.getPublic());
out.close();
out = new ObjectOutputStream(new FileOutputStream(args[2]));
out.writeObject(keyPair.getPrivate());
out.close();
}
else if (args[0].equals("-encrypt"))
{
KeyGenerator keygen = KeyGenerator.getInstance("AES");
SecureRandom random = new SecureRandom();
keygen.init(random);
SecretKey key = keygen.generateKey();
// wrap with RSA public key
ObjectInputStream keyIn = new ObjectInputStream(new FileInputStream(args[3]));
Key publicKey = (Key) keyIn.readObject();
keyIn.close();
Cipher cipher = Cipher.getInstance("RSA");
cipher.init(Cipher.WRAP_MODE, publicKey);
byte[] wrappedKey = cipher.wrap(key);
DataOutputStream out = new DataOutputStream(new FileOutputStream(args[2]));
out.writeInt(wrappedKey.length);
out.write(wrappedKey);
InputStream in = new FileInputStream(args[1]);
cipher = Cipher.getInstance("AES");
cipher.init(Cipher.ENCRYPT_MODE, key);
crypt(in, out, cipher);
in.close();
out.close();
}
else
{
DataInputStream in = new DataInputStream(new FileInputStream(args[1]));
int length = in.readInt();
byte[] wrappedKey = new byte[length];
in.read(wrappedKey, 0, length);
// unwrap with RSA private key
ObjectInputStream keyIn = new ObjectInputStream(new FileInputStream(args[3]));
Key privateKey = (Key) keyIn.readObject();
keyIn.close();
Cipher cipher = Cipher.getInstance("RSA");
cipher.init(Cipher.UNWRAP_MODE, privateKey);
Key key = cipher.unwrap(wrappedKey, "AES", Cipher.SECRET_KEY);
OutputStream out = new FileOutputStream(args[2]);
cipher = Cipher.getInstance("AES");
cipher.init(Cipher.DECRYPT_MODE, key);
crypt(in, out, cipher);
in.close();
out.close();
}
}
catch (IOException e)
{
e.printStackTrace();
}
catch (GeneralSecurityException e)
{
e.printStackTrace();
}
catch (ClassNotFoundException e)
{
e.printStackTrace();
}
}
/**
* Uses a cipher to transform the bytes in an input stream and sends the transformed bytes to an
* output stream.
* @param in the input stream
* @param out the output stream
* @param cipher the cipher that transforms the bytes
*/
public static void crypt(InputStream in, OutputStream out, Cipher cipher) throws IOException,
GeneralSecurityException
{
int blockSize = cipher.getBlockSize();
int outputSize = cipher.getOutputSize(blockSize);
byte[] inBytes = new byte[blockSize];
byte[] outBytes = new byte[outputSize];
int inLength = 0;
;
boolean more = true;
while (more)
{
inLength = in.read(inBytes);
if (inLength == blockSize)
{
int outLength = cipher.update(inBytes, 0, blockSize, outBytes);
out.write(outBytes, 0, outLength);
}
else more = false;
}
if (inLength > 0) outBytes = cipher.doFinal(inBytes, 0, inLength);
else outBytes = cipher.doFinal();
out.write(outBytes);
}
private static final int KEYSIZE = 512;
}
Related examples in the same category