13

For my School project I had to show that I can utilize file handling within a program. For this I made a very simple login process that you can create an account on that writes a username and password to a text file located in the resource folder. Obviously this has no security at all as it wasn't designed to be secure just to showcase file handling however my teacher has said that I should attempt to add some encryption to the file as well to get a better grade.

I have done some research and many people are recommending DES.

The problem I'm having is I don't have much time left for my project and need to finish it asap. Using DES seems like it would take a while to implement all the extra code.

In my program I am using a simple lineNumberReader to read the files line by line. To write to the files I am using a BufferedWriter.

Is there anyway to encrypt this data very simply? It doesn't have to be very secure but I need to show that I have atleast attempted to encrypt the data. The encryption and decryption would all be completed on the same application as data isn't being transferred.

Potentially a way I can create a very simple encryption and decryption algorithm myself?

Patch
  • 203
  • 2
  • 3
  • 6
  • 1
    If I were to grade this, I would prefer the student finding out how to use the existing JDK crypto functions (for example AES). The API is a bit verbose, but you can find sample code on this site. Like this one: http://stackoverflow.com/a/20796446/14955 – Thilo Jan 15 '15 at 11:16
  • A good starting point might be the (Java Cryptography Architecture guide)[http://docs.oracle.com/javase/7/docs/technotes/guides/security/crypto/CryptoSpec.html] – SubOptimal Jan 15 '15 at 11:17
  • Consider that password are usually stored with one way function (SHA for example). Are you sure the request is also for decryption? – Aris2World Jan 15 '15 at 11:19
  • 1
    http://www.ecestudents.ul.ie/Course_Pages/Btech_ITT/Modules/ET4263/More%20Samples/CEncrypt.java.html – StanislavL Jan 15 '15 at 11:21

11 Answers11

29

Try this,... Its pretty simple

import javax.crypto.Cipher;
import javax.crypto.KeyGenerator;
import javax.crypto.SecretKey;

public class HelloWorld{
    public static void main(String[] args) {

        try{
            KeyGenerator keygenerator = KeyGenerator.getInstance("DES");
            SecretKey myDesKey = keygenerator.generateKey();

            Cipher desCipher;
            desCipher = Cipher.getInstance("DES");


            byte[] text = "No body can see me.".getBytes("UTF8");


            desCipher.init(Cipher.ENCRYPT_MODE, myDesKey);
            byte[] textEncrypted = desCipher.doFinal(text);

            String s = new String(textEncrypted);
            System.out.println(s);

            desCipher.init(Cipher.DECRYPT_MODE, myDesKey);
            byte[] textDecrypted = desCipher.doFinal(textEncrypted);

            s = new String(textDecrypted);
            System.out.println(s);
        }catch(Exception e)
        {
            System.out.println("Exception");
        }
    }
}

So basically before writing to file you will encrypt and after reading you will need to decrypt it.

j4rey
  • 2,582
  • 20
  • 34
  • 4
    `getBytes()` should be called with the specific encoding like `"UTF-8"`. Otherwise, if it is decrypted on a different machine, it won't decrypt correctly when a different system encoding is used. – Artjom B. Jan 15 '15 at 11:36
  • Thanks for the answer, I am accessing the file quite a few times is it worth putting the encryption and decryption in it's own class from which it can be called? – Patch Jan 17 '15 at 10:40
  • 1
    yeah, anything that can make your code cleaner and modular, do it....d(-_^)good!! – j4rey Jan 19 '15 at 05:19
  • You should specify the mode of operations and not just a blockcipher. – CodesInChaos Jan 22 '15 at 16:14
  • 3
    wouldn't this just generate a new key every time it is run? doesn't it also not provide any way to save that key? – ifly6 May 29 '16 at 03:14
  • 1
    `DES` is not longer considered secure, try `AES` instead. – Captain Man May 03 '21 at 21:46
  • Please update the comment for upgrading algorithm to AES (for now). The security is a big issue when algorithm are obsolete and the better advice should be given to every developers. – pdem Mar 30 '23 at 08:22
3

An easy and fun scrambling algorithm would be the Burrows-Wheeler transform. Not really a secure encryption, but seriously, it's a school work and this is awesome.

Olavi Mustanoja
  • 2,045
  • 2
  • 23
  • 34
3

use simple subtitute encryption algorythm, change every character into number or other character.

  1. get every character of your string.
  2. get the ascii value of the string.
  3. add the ascii value with specific integer (this will be your encryption key)
  4. display the result
pupil
  • 318
  • 2
  • 16
3

A very basic method would be to xor the data with a key. This method is symmetrical, i.e you can use the same key to decode as encode.

If we choose a 1 byte key it's nice and simple, enough to make it unreadable (but not at all secure!):

private void encodeDecode(byte[] bytes, byte key) {
    for(int i=0; i<bytes.length; i++)
        bytes[i] = (byte) (bytes[i]^key);
}
weston
  • 54,145
  • 21
  • 145
  • 203
2

You could use a simple ceasar cipher (http://en.wikipedia.org/wiki/Caesar_cipher)

public class Cipher {
public static void main(String[] args) {

    String str = "The quick brown fox Jumped over the lazy Dog";

    System.out.println( Cipher.encode( str, 12 ));
    System.out.println( Cipher.decode( Cipher.encode( str, 12), 12 ));
}

public static String decode(String enc, int offset) {
    return encode(enc, 26-offset);
}

public static String encode(String enc, int offset) {
    offset = offset % 26 + 26;
    StringBuilder encoded = new StringBuilder();
    for (char i : enc.toCharArray()) {
        if (Character.isLetter(i)) {
            if (Character.isUpperCase(i)) {
                encoded.append((char) ('A' + (i - 'A' + offset) % 26 ));
            } else {
                encoded.append((char) ('a' + (i - 'a' + offset) % 26 ));
            }
        } else {
            encoded.append(i);
        }
    }
    return encoded.toString();
}
}

Found at http://rosettacode.org/wiki/Caesar_cipher#Java

Note that Java has native solutions for encryption and when it comes to passwords, it is much better to just hash them and compare hashes as there usually is no need to decrypt them.

flo
  • 9,713
  • 6
  • 25
  • 41
1

Bouncy Castle Crypto API is a lightweight cryptography API in Java.

    import org.bouncycastle.crypto.*;
    import org.bouncycastle.crypto.engines.*;
    import org.bouncycastle.crypto.modes.*;
    import org.bouncycastle.crypto.params.*;

    // A simple example that uses the Bouncy Castle
    // lightweight cryptography API to perform DES
    // encryption of arbitrary data.


     public class Encryptor {

            private BufferedBlockCipher cipher;
            private KeyParameter key;


            // Initialize the cryptographic engine.
            // The key array should be at least 8 bytes long.


            public Encryptor( byte[] key ){
            /*
            cipher = new PaddedBlockCipher(
                       new CBCBlockCipher(new DESEngine()));
            */
            cipher = new PaddedBlockCipher(
                        new CBCBlockCipher(new BlowfishEngine()));
            this.key = new KeyParameter( key );
            }        

            // Initialize the cryptographic engine.
            // The string should be at least 8 chars long.

            public Encryptor( String key ){
            this( key.getBytes());
            }
            // Private routine that does the gritty work.

            private byte[] callCipher( byte[] data )
            throws CryptoException {
            int    size = cipher.getOutputSize( data.length );

            byte[] result = new byte[ size ];
            int    olen = cipher.processBytes(data,0,data.length result, 0);
                   olen += cipher.doFinal( result, olen );

            if( olen < size ){
                byte[] tmp = new byte[ olen ];
                System.arraycopy(
                        result, 0, tmp, 0, olen );
                result = tmp;
            }

            return result;
        }
        // Encrypt arbitrary byte array, returning the
        // encrypted data in a different byte array.

        public synchronized byte[] encrypt( byte[] data )
        throws CryptoException {
            if( data == null || data.length == 0 ){
                return new byte[0];
            }

            cipher.init( true, key );
            return callCipher( data );
        }
       // Encrypts a string.

        public byte[] encryptString( String data )
        throws CryptoException {
            if( data == null || data.length() == 0 ){
                return new byte[0];
            }

            return encrypt( data.getBytes() );
        }
        // Decrypts arbitrary data.

        public synchronized byte[] decrypt( byte[] data )
        throws CryptoException {
            if( data == null || data.length == 0 ){
                return new byte[0];
            }

            cipher.init( false, key );
            return callCipher( data );
        }
        // Decrypts a string that was previously encoded
        // using encryptString.

        public String decryptString( byte[] data )
        throws CryptoException {
            if( data == null || data.length == 0 ){
                return "";
            }

            return new String( decrypt( data ) );
        }
    }
Sanjay Kumar
  • 369
  • 6
  • 23
1

I don't know who recommends DES to encrypt password. I suggest you to follow these step if you would to impress your teacher:

This solution makes your project real and you can reuse it to pass the exam of your future Crypto Module :) . Otherwise I like the solution proposed from StanislavL.

Enjoy!

Aris2World
  • 1,214
  • 12
  • 22
0

There are too many ways to encrypted simple string in Java. If it is a school project , I really don't think you can get a higher band by simply using some third-part libs to finish the encrypted work.

If you have some time, you could try to understand how Base64 works, then try to create some encrypted algorithm by yourself.

How ever, if you insist to use some API in Java , I have to say that DES is really old way to encrypted text , 3DEs(DESede) or AES will be better and safer , both of them have already been supported since Java6.

If you have to import the BouncyCastle lib , I prefer IDEA, it's one of the safest algorithm, may have you achieve a good score.

I won't give you any demo code, but you can easily find some by google all the algorithm I have mentioned.

Bruce_Van
  • 46
  • 5
-3
public class CryptoUtils {

    public static void encrypt(String key, File inputFile, File outputFile)
            throws CryptoException {
        doCrypto(Cipher.ENCRYPT_MODE, key, inputFile, outputFile);
    }

    public static void decrypt(String key, File inputFile, File outputFile)
            throws CryptoException {
        doCrypto(Cipher.DECRYPT_MODE, key, inputFile, outputFile);
    }

    private static void doCrypto(int cipherMode, String key, File inputFile,
            File outputFile) throws CryptoException {
        try {
            Key secretKey = new SecretKeySpec(key.getBytes(), ALGORITHM);
            Cipher cipher = Cipher.getInstance(TRANSFORMATION);
            cipher.init(cipherMode, secretKey);

            FileInputStream inputStream = new FileInputStream(inputFile);
            byte[] inputBytes = new byte[(int) inputFile.length()];
            inputStream.read(inputBytes);

            byte[] outputBytes = cipher.doFinal(inputBytes);

            FileOutputStream outputStream = new FileOutputStream(outputFile);
            outputStream.write(outputBytes);

            inputStream.close();
            outputStream.close();

        } catch (NoSuchPaddingException | NoSuchAlgorithmException
                | InvalidKeyException | BadPaddingException
                | IllegalBlockSizeException | IOException ex) {
            throw new CryptoException("Error encrypting/decrypting file", ex);
        }
    }
}

package net.codejava.crypto;

import java.io.File;

public class CryptoException extends Exception {

    public CryptoException() {
    }

    public CryptoException(String message, Throwable throwable) {
        super(message, throwable);
    }

    public static void main(String[] args) {
        String key = "Mary has one cat1";
        File inputFile = new File("document.txt");
        File encryptedFile = new File("document.encrypted");
        File decryptedFile = new File("document.decrypted");

        try {
            CryptoUtils.encrypt(key, inputFile, encryptedFile);
            CryptoUtils.decrypt(key, encryptedFile, decryptedFile);
        } catch (CryptoException ex) {
            System.out.println(ex.getMessage());
            ex.printStackTrace();
        }
    }
}
Willington Vega
  • 4,732
  • 3
  • 21
  • 19
IDK
  • 1
  • Welcome to Stack Overflow! Thank you for this code snippet, which might provide some limited, immediate help. A proper explanation [would greatly improve](//meta.stackexchange.com/q/114762) its long-term value by showing *why* this is a good solution to the problem, and would make it more useful to future readers with other, similar questions. Please [edit] your answer to add some explanation, including the assumptions you've made. – Toby Speight Nov 15 '17 at 16:17
-4

My suggestion: don't use encryption at all. Here's something better:(I hope)

Scanner sc=new Scanner(System.in);
String name=sc.next();
//for inputting user name
File f= new File("d://"+name+".txt");
if(f.exists())
{
if(f.lastModified()!=0)
{ 
System.out.println("Account data tampered...cannot be accessed"); 
}
else{
String data="";
System.out.println(data); //data should contain 
//data from file read using BufferedReader
f.setLastModified(0);
}
}
else
{
f.createNewFile();//Write whatever you want to to the file 
f.setLastModified(0);
}

So, you can effectively know whether the user has tampered with the text file with the details and display an error message if the tampered account is used. However, This does not prevent the user from changing the file, it will just prevent a tampered account from being used....I think your computer teacher might like this. You could also do: f.setReadOnly(); and when you write to the file, f.setWritable(true,true), then after closing the output stream, f.setReadOnly(); again... But the file can still be replaced, therefore the 1st and is more Effective. Thanks

  • 4
    This doesn't make much sense. The file just contains the username and password. Why would anyone want or need to change the file when they can just read the username/password from it? – JJJ Jul 08 '18 at 17:09
-4

you can use these function to encrypt and decrypt simple text

//Encrypt simple text
public String EncryptSimpleText (String text2Encrypt) throws Exception {
    byte[] encryptArray = Base64.getEncoder().encode(text2Encrypt.getBytes());
    return new String(encryptArray,"UTF-8");
}

//Decrypt simple text
public String Decrypt2SimpleText(String textEncrypted) throws Exception {
    byte[] dectryptArray = textEncrypted.getBytes();
    byte[] decarray = Base64.getDecoder().decode(dectryptArray);
    return new String(decarray,"UTF-8");
}
Dan
  • 171
  • 1
  • 6
  • sounds like a mis-understanding: your answer certainly related to the question (afaics), my comment is not related to the content of _your answer_ :) – kleopatra Aug 19 '19 at 11:33