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

Posted

技术标签:

【中文标题】在java中加密文本文件的最简单方法【英文标题】:Simplest way to encrypt a text file in java 【发布时间】:2015-03-13 18:26:39 【问题描述】:

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

我做了一些研究,很多人都在推荐 DES。

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

在我的程序中,我使用一个简单的 lineNumberReader 逐行读取文件。要写入我正在使用 BufferedWriter 的文件。

有没有办法非常简单地加密这些数据?它不必非常安全,但我需要证明我至少尝试过加密数据。由于没有传输数据,加密和解密都将在同一个应用程序上完成。

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

【问题讨论】:

如果我要给这个评分,我希望学生了解如何使用现有的 JDK 加密函数(例如 AES)。 API 有点冗长,但您可以在此站点上找到示例代码。喜欢这个:***.com/a/20796446/14955 一个好的起点可能是(Java Cryptography Architecture guide)[docs.oracle.com/javase/7/docs/technotes/guides/security/crypto/… 请考虑密码通常以单向函数存储(例如 SHA)。你确定这个请求也是为了解密吗? ecestudents.ul.ie/Course_Pages/Btech_ITT/Modules/ET4263/… 【参考方案1】:

试试这个,...它很简单

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

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

【讨论】:

getBytes() 应该使用特定的编码来调用,例如"UTF-8"。否则,如果在不同的机器上解密,使用不同的系统编码时将无法正确解密。 感谢您的回答,我多次访问该文件是否值得将加密和解密放在可以调用它的自己的类中? 是的,任何可以让你的代码更简洁和模块化的东西,去做吧....d(-_^)good!! 您应该指定操作模式,而不仅仅是块密码。 这不是每次运行时都会生成一个新密钥吗?难道它也没有提供任何保存该密钥的方法吗?【参考方案2】:

Burrows-Wheeler transform 是一种简单而有趣的加扰算法。不是真正的安全加密,但说真的,这是一项学校作业,这太棒了。

【讨论】:

【参考方案3】:

使用简单的替代加密算法,将每个字符转换为数字或其他字符。

    获取字符串的每个字符。 获取字符串的ascii值。 用特定整数添加 ascii 值(这将是您的加密密钥) 显示结果

【讨论】:

更好的方法是对它们做一个复杂的数学方程:P【参考方案4】:

一个非常基本的方法是用一个键对数据进行异或。这种方法是对称的,即可以使用与encode相同的key进行解码。

如果我们选择一个 1 字节的密钥,它既好又简单,足以让它不可读(但一点也不安全!):

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

【讨论】:

【参考方案5】:

您可以使用简单的凯撒密码 (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();


发现于http://rosettacode.org/wiki/Caesar_cipher#Java

请注意,Java 有本地加密解决方案,当涉及到密码时,最好只对它们进行散列并比较散列,因为通常不需要解密它们。

【讨论】:

这是一个很酷的方法,但是很容易破解。不推荐。【参考方案6】:

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

引用您的参考资料作为对您的加密解决方案的理论支持。我建议你这个OWSAP - Password Storage Cheat Sheet 说明您的代码在哪里符合规范。对于一个带有示例代码的好教程,我建议你这个secure password hash

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

享受吧!

【讨论】:

【参考方案7】:

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

【讨论】:

【参考方案8】:

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

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

然而,如果你坚持在 Java 中使用一些 API,我不得不说 DES 确实是加密文本的老方法,3DEs(DESede) 或 AES 会更好更安全,因为它们都已经得到支持Java6.

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

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

【讨论】:

【参考方案9】:
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();
        
    

【讨论】:

欢迎来到 Stack Overflow!感谢您提供此代码 sn-p,它可能会提供一些有限的即时帮助。一个正确的解释would greatly improve 它的长期价值通过展示为什么这是一个很好的解决问题的方法,并将使它对未来有其他类似问题的读者更有用。请edit您的回答添加一些解释,包括您所做的假设。【参考方案10】:

您可以使用这些功能对简单文本进行加密和解密

//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");

【讨论】:

听起来像是一种误解:您的回答肯定与问题(afaics)有关,我的评论与您的回答的内容无关:)【参考方案11】:

我的建议:根本不要使用加密。 这里有更好的:(我希望)

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

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

【讨论】:

这没有多大意义。该文件仅包含用户名和密码。当他们可以从中读取用户名/密码时,为什么有人想要或需要更改文件?

以上是关于在java中加密文本文件的最简单方法的主要内容,如果未能解决你的问题,请参考以下文章

QT中怎样读取中文文本文件!

关于C语言中文本文件的逐行读取的实现

C语言如何写入文本文件

C语言英文文本加密

delphi写多行文本文件操作

C语言打开其他目录下的文本文件