DZone Snippets is a public source code repository. Easily build up your personal collection of code snippets, categorize them with tags / keywords, and share them with the world
OnePad, RC4 Encrypt/decrypt
// description of your code here
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.Scanner;
/**
*
*/
/**
* @author Micheal Vu
*
* 9600278
*/
public class cCipherAss {
/*
* Loads file and store in a byte-array
* An IOException will be throw if opening file occurred error (file not found, has no reading permission)
* @param sFileName The filename (full-path) which will be load.
* @return an array of bytes if file-size < Integer.MAX_VALUE. Otherwise return null
*/
private static byte[] loadTextFile( String sFileName) throws IOException{
File fTmp = new File( sFileName);
InputStream isFile = new FileInputStream(fTmp);
long lFileSize = fTmp.length();
if( lFileSize > Integer.MAX_VALUE){
// raise error here
}
else{
int iFileSize = (int)lFileSize;
byte[] buffRet = new byte[iFileSize];
int iNumberRead =0;
int iCurrentRead=1;
while( iCurrentRead >0){
iCurrentRead = isFile.read(buffRet, iNumberRead, iFileSize-iNumberRead);
iNumberRead+= iCurrentRead;
}
isFile.close();
return buffRet;
}
return null;
}
/*
* Encrypt/Decrypt data by the OnePad Cipher Algorithm. This function uses XOR-bit operator to encrypt/decrypt.
* @param bufSrc Source data which want to be encrypted/decrypted.
* @param bufKey Key which will be used to encrypt/decrypt
* @param iSeg Start-position of source data
* @param iLen The number of bytes which want to be encrypted/decrypted
* @return the data after encrypting/decrypting
*/
private static byte[] encrypOnePadByte( byte[] bufSrc, byte[] bufKey, int iSeg, int iLen){
byte[] bufRet = null;
if( iSeg<0 || iLen <0 || iSeg+iLen> bufSrc.length){
//raise error here
}
else{
bufRet = new byte[ iLen];
for( int i=iSeg, k=0; i< iLen; i++, k++){
bufRet[k] =(byte)( bufSrc[i] ^ bufKey[i]);
}
}
return bufRet;
}
/*
* Encrypt/Decrypt data in file by the OnePad Cipher Algorithm. This function uses XOR-bit operator to encrypt/decrypt.
* @param sSrcFile Source data file which want to be encrypted/decrypted.
* @param sKeyFile Key file which will be used to encrypt/decrypt. The length of key-file must be greater or equal the one of source file.
* @return filename (full path) which stores the data after encrypting/decrypting (it's will be stored temporary-folder). An empty String will be return if it has any error (read error message at ERR STANDARD OUTPUT).
*/
public static String encryptOnePadFile( String sSrcFile, String sKeyFile){
try{
//missing check existed of files here
File fSrc = new File(sSrcFile);
File fTmp = File.createTempFile(fSrc.getName(), ".enc");
byte[] bufSrc = loadTextFile(sSrcFile);
byte[] bufKey = loadTextFile(sKeyFile);
if( bufKey.length< bufSrc.length){
// raise error here
}
else{
byte[] bufData = encrypOnePadByte(bufSrc, bufKey, 0, bufSrc.length);
OutputStream osFile = new FileOutputStream(fTmp);
osFile.write(bufData);
osFile.close();
}
return fTmp.getAbsolutePath();
}
catch( IOException e){
//raise error here
System.err.println(e.getMessage());
return "";
}
}
/*
* generates the KSA
* @param sKey the key as a seed for key-string generator
* @param iLen the length of KSA
* @return key-stream (array of byte)
*/
private static byte[] genKSAKeyStream(String sKey, int iLen){
if( iLen<1|| iLen>256){
iLen= 256;
}
if(sKey== null || sKey.length()==0){
sKey = "MichealVu";
}
byte[] bufKeyStream = new byte[iLen];
byte[] bufKeySeeder = sKey.getBytes();
int iSLen = bufKeySeeder.length;
byte bTmp;
// init KeyStream
for( int i=0; i<iLen; i++){
bufKeyStream[i] = (byte) i;
}
//swapping
for(int i=0, k=0; i<iLen; i++){
// byte in java is signed-number
k=(k + bufKeyStream[i]+ bufKeySeeder[i% iSLen]+ iLen) % iLen;
bTmp = bufKeyStream[i];
bufKeyStream[i] = bufKeyStream[k];
bufKeyStream[k] = bTmp;
}
return bufKeyStream;
}
private static final int KS_LEN = 256;
/*
* Encrypt/Decrypt data by the RC4 Cipher Algorithm. This function uses XOR-bit operator to encrypt/decrypt.
* @param bufSrc Source data which want to be encrypted/decrypted.
* @param sKey key which will be used to generate the key stream
* @return the data after encrypting/decrypting
*/
private static byte[] encryptRC4Byte( byte[] bufSrc, String sKey){
byte[] bufRet = null;
int iLen = bufSrc.length;
bufRet = new byte[ iLen];
byte[] bufKeyStream = genKSAKeyStream(sKey, KS_LEN);
for( int i=0; i< iLen; i++){
bufRet[i] =(byte)( bufSrc[i] ^ bufKeyStream[i% KS_LEN]);
}
return bufRet;
}
/*
* Encrypt/Decrypt data in file by the RC4 Cipher Algorithm. This function uses XOR-bit operator to encrypt/decrypt.
* @param sSrcFile Source data file which want to be encrypted/decrypted.
* @param sKey Key String which will be used to generate the key-stream. The length of key-stream is KS_LEN .
* @return filename (full path) which stores the data after encrypting/decrypting (it's will be stored temporary-folder). An empty String will be return if it has any error (read error message at ERR STANDARD OUTPUT).
*/
public static String encryptRC4File( String sSrcFile, String sKey){
try{
//missing check existed of files here
File fSrc = new File(sSrcFile);
File fTmp = File.createTempFile(fSrc.getName(), ".enc");
byte[] bufSrc = loadTextFile(sSrcFile);
byte[] bufData = encryptRC4Byte(bufSrc, sKey);
OutputStream osFile = new FileOutputStream(fTmp);
osFile.write(bufData);
osFile.close();
return fTmp.getAbsolutePath();
}
catch( IOException e){
//raise error here
System.err.println( e.getMessage());
return "";
}
}
/*
* Testing encryptOnePadFile function
*/
private static void encryptOnePadFileDemo(){
Scanner in = new Scanner(System.in);
String sSrcFile, sKeyFile;
System.out.print("Input Source File:"); sSrcFile = in.nextLine();
System.out.print("Input Key File:"); sKeyFile = in.nextLine();
String sFileName = encryptOnePadFile(sSrcFile, sKeyFile);
System.out.println( "Result file: "+ sFileName);
}
/*
* Testing encryptRC4File function
*/
private static void encryptRC4FileDemo(){
Scanner in = new Scanner(System.in);
String sSrcFile, sKey;
System.out.print("Input Source File:"); sSrcFile = in.nextLine();
System.out.print("Input Key :"); sKey = in.nextLine();
String sFileName = encryptRC4File(sSrcFile, sKey);
System.out.println( "Result file: "+ sFileName);
}
private static void encryptRC4ByteDemo(){
Scanner in = new Scanner(System.in);
String sMsg, sKey;
System.out.print("Input Message:"); sMsg = in.nextLine();
System.out.print("Input Key :"); sKey = in.nextLine();
byte[] bufData = encryptRC4Byte(sMsg.getBytes(), sKey);
for(int i=0; i<bufData.length; i++){
System.out.print(Integer.toHexString(bufData[i]));
}
}
/**
* @param args
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
//encryptOnePadFileDemo();
encryptRC4FileDemo();
//encryptRC4ByteDemo();
}
}





