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

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

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

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

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

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

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

【问题讨论】:

标签: java security encryption text-files


【解决方案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】:

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

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

    【讨论】:

    • 更好的方法是对它们做一个复杂的数学方程: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 来加密密码。 如果您想给老师留下深刻印象,我建议您按照以下步骤操作:

      此解决方案使您的项目变得真实,您可以重复使用它来通过未来加密模块的考试:)。否则我喜欢 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(); 再次... 但是文件仍然可以被替换,因此第一个和更多 有效的。 谢谢

            【讨论】:

            • 这没有多大意义。该文件仅包含用户名和密码。当他们可以从中读取用户名/密码时,为什么有人想要或需要更改文件?
            猜你喜欢
            • 2013-11-26
            • 1970-01-01
            • 2017-12-31
            • 1970-01-01
            • 2010-09-13
            • 2016-03-24
            • 2014-05-16
            • 1970-01-01
            • 2016-08-21
            相关资源
            最近更新 更多