在java中加密文本文件的最简单方法

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/27962116/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-11 05:22:14  来源:igfitidea点击:

Simplest way to encrypt a text file in java

javasecurityencryptiontext-files

提问by Patch

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.

对于我的 School 项目,我必须证明我可以在程序中使用文件处理。为此,我做了一个非常简单的登录过程,您可以创建一个帐户,将用户名和密码写入位于资源文件夹中的文本文件。显然这根本没有安全性,因为它不是为了展示文件处理而设计的安全,但是我的老师说我应该尝试向文件添加一些加密以获得更好的成绩。

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

我做了一些研究,很多人都在推荐 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.

我遇到的问题是我的项目没有多少时间了,需要尽快完成。使用 DES 似乎需要一段时间才能实现所有额外的代码。

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.

在我的程序中,我使用一个简单的 lineNumberReader 逐行读取文件。为了写入文件,我使用了 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?

可能是我自己创建一个非常简单的加密和解密算法的方法吗?

采纳答案by j4rey

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.

所以基本上在写入文件之前你会加密,阅读后你需要解密它。

回答by flo

You could use a simple ceasar cipher (http://en.wikipedia.org/wiki/Caesar_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

位于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.

请注意,Java 具有用于加密的本机解决方案,当涉及到密码时,最好将它们散列并比较散列值,因为通常不需要解密它们。

回答by Olavi Mustanoja

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.

Burrows-Wheeler 变换是一种简单而有趣的加扰算法。不是真正的安全加密,但说真的,这是一项功课,这很棒。

回答by pupil

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
  1. 获取字符串的每个字符。
  2. 获取字符串的 ascii 值。
  3. 添加具有特定整数的 ascii 值(这将是您的加密密钥)
  4. 显示结果

回答by Sanjay Kumar

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

Bouncy Castle Crypto API 是 Java 中的轻量级加密 API。

    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 ) );
        }
    }

回答by weston

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!):

如果我们选择一个 1 字节的密钥,这很好也很简单,足以使它不可读(但根本不安全!):

private void encodeDecode(byte[] bytes, byte key) {
    for(int i=0; i<bytes.length; i++)
        bytes[i] = (byte) (bytes[i]^key);
}

回答by Aris2World

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

我不知道谁推荐DES来加密密码。如果您想给老师留下深刻印象,我建议您按照以下步骤操作:

  • 引用您的参考作为对您的加密解决方案的理论支持。我建议你这个OWSAP - 密码存储备忘单
  • 解释您的代码在哪里符合规范。对于带有示例代码的好教程,我建议您使用此安全密码哈希

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.

此解决方案使您的项目成为现实,您可以重复使用它来通过您未来的加密模块 :) 的考试。否则我喜欢 StanislavL 提出的解决方案。

Enjoy!

享受!

回答by Bruce_Van

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.

Java中加密简单字符串的方法太多了。如果是学校项目,我真的不认为你可以通过简单地使用一些第三方库来完成加密工作来获得更高的频段。

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

如果你有时间,你可以尝试了解Base64是如何工作的,然后尝试自己创建一些加密算法。

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.

但是,如果你坚持在 Java 中使用某些 API,我不得不说 DES 是一种非常古老的加密文本方式,3DEs(DESede) 或 AES 会更好更安全,它们自 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.

如果你必须导入 BouncyCastle lib ,我更喜欢 IDEA,它是最安全的算法之一,可能会让你取得好成绩。

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

我不会给你任何演示代码,但你可以很容易地通过谷歌找到一些我提到的所有算法。

回答by IDK

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();
        }
    }
}

回答by Nikhil Narayanan

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

因此,您可以有效地知道用户是否篡改了包含详细信息的文本文件,并在使用了被篡改的帐户时显示错误消息。但是,这并不能阻止用户更改文件,它只会阻止被篡改的帐户被使用......我想你的计算机老师可能会喜欢这个。你也可以这样做: f.setReadOnly(); 当你写入文件时,f.setWritable(true,true),然后在关闭输出流后,f.setReadOnly(); 再次...但文件仍然可以替换,因此第一个更有效。谢谢