在 java 中加密文本文件的最简单方法
Simplest way to encrypt a text file in java
对于我的学校项目,我必须证明我可以在程序中使用文件处理。为此,我做了一个非常简单的登录过程,您可以创建一个帐户,将用户名和密码写入位于资源文件夹中的文本文件。显然,这根本没有安全性,因为它的设计目的并不是为了展示文件处理的安全性,但是我的老师说我也应该尝试为文件添加一些加密以获得更好的成绩。
我做了一些研究,很多人都在推荐 DES。
我遇到的问题是我没有太多时间留给我的项目,需要尽快完成它。使用 DES 似乎需要一段时间才能实现所有额外的代码。
在我的程序中,我使用一个简单的 lineNumberReader 逐行读取文件。要写入我正在使用 BufferedWriter 的文件。
有没有办法非常简单地加密这些数据?它不必非常安全,但我需要证明我至少尝试过加密数据。加密和解密都将在同一个应用程序上完成,因为数据没有被传输。
可能是我自己创建一个非常简单的加密和解密算法的方法?
您可以使用简单的 ceasar 密码 (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 有加密的本地解决方案,当涉及到密码时,最好只是散列它们并比较散列,因为通常不需要解密它们。
一个简单有趣的加扰算法是 Burrows-Wheeler transform。不是真正的安全加密,但说真的,这是一项学校作业,这太棒了。
使用简单的加密算法,将每个字符转换成数字或其他字符。
- 获取字符串中的每个字符。
- 获取字符串的ascii值。
- 添加具有特定整数的 ascii 值(这将是您的加密密钥)
- 显示结果
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 ) );
}
}
一种非常基本的方法是使用密钥对数据进行异或运算。此方法是对称的,即您可以使用与编码相同的密钥进行解码。
如果我们选择一个 1 字节的密钥,它既好又简单,足以使其不可读(但一点也不安全!):
private void encodeDecode(byte[] bytes, byte key) {
for(int i=0; i<bytes.length; i++)
bytes[i] = (byte) (bytes[i]^key);
}
试试这个,...很简单
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");
}
}
}
所以基本上在写入文件之前你会加密,在读取之后你需要解密它。
不知道谁推荐DES加密密码。
如果您想给老师留下深刻印象,我建议您按照以下步骤操作:
- 引用您的参考作为对您的密码解决方案的理论支持。我建议你这个 OWSAP - Password Storage Cheat Sheet
- 解释您的代码在哪里符合规范。对于带有示例代码的良好教程,我建议您使用此 secure password hash
此解决方案使您的项目成为现实,您可以重复使用它来通过未来加密模块的考试:)。否则我喜欢 StanislavL 提出的解决方案。
尽情享受吧!
在Java中加密简单字符串的方法太多了。如果是学校的project,我真的不认为光靠用一些第三方的libs来完成加密工作就可以获得更高的band。
如果你有时间,可以尝试了解Base64的工作原理,然后尝试自己创建一些加密算法。
但是,如果你坚持在Java中使用一些API,我不得不说DES确实是加密文本的老方法,3DEs(DESede)或AES会更好并且更安全,自 Java6.
以来,它们都已得到支持
如果一定要导入BouncyCastle lib,我更喜欢IDEA,它是最安全的算法之一,可能会让你取得好成绩。
我不会给你任何演示代码,但你可以通过 google 我提到的所有算法轻松找到一些。
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();
}
}
}
我的建议:根本不要使用加密。
这里有更好的东西:(我希望)
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(真,真),
然后关闭输出流后,
f.setReadOnly();
再次...
但是文件仍然可以被替换,因此第一个和更多
有效的。
谢谢
您可以使用这些函数对简单文本进行加密和解密
//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");
}
对于我的学校项目,我必须证明我可以在程序中使用文件处理。为此,我做了一个非常简单的登录过程,您可以创建一个帐户,将用户名和密码写入位于资源文件夹中的文本文件。显然,这根本没有安全性,因为它的设计目的并不是为了展示文件处理的安全性,但是我的老师说我也应该尝试为文件添加一些加密以获得更好的成绩。
我做了一些研究,很多人都在推荐 DES。
我遇到的问题是我没有太多时间留给我的项目,需要尽快完成它。使用 DES 似乎需要一段时间才能实现所有额外的代码。
在我的程序中,我使用一个简单的 lineNumberReader 逐行读取文件。要写入我正在使用 BufferedWriter 的文件。
有没有办法非常简单地加密这些数据?它不必非常安全,但我需要证明我至少尝试过加密数据。加密和解密都将在同一个应用程序上完成,因为数据没有被传输。
可能是我自己创建一个非常简单的加密和解密算法的方法?
您可以使用简单的 ceasar 密码 (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 有加密的本地解决方案,当涉及到密码时,最好只是散列它们并比较散列,因为通常不需要解密它们。
一个简单有趣的加扰算法是 Burrows-Wheeler transform。不是真正的安全加密,但说真的,这是一项学校作业,这太棒了。
使用简单的加密算法,将每个字符转换成数字或其他字符。
- 获取字符串中的每个字符。
- 获取字符串的ascii值。
- 添加具有特定整数的 ascii 值(这将是您的加密密钥)
- 显示结果
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 ) );
}
}
一种非常基本的方法是使用密钥对数据进行异或运算。此方法是对称的,即您可以使用与编码相同的密钥进行解码。
如果我们选择一个 1 字节的密钥,它既好又简单,足以使其不可读(但一点也不安全!):
private void encodeDecode(byte[] bytes, byte key) {
for(int i=0; i<bytes.length; i++)
bytes[i] = (byte) (bytes[i]^key);
}
试试这个,...很简单
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");
}
}
}
所以基本上在写入文件之前你会加密,在读取之后你需要解密它。
不知道谁推荐DES加密密码。 如果您想给老师留下深刻印象,我建议您按照以下步骤操作:
- 引用您的参考作为对您的密码解决方案的理论支持。我建议你这个 OWSAP - Password Storage Cheat Sheet
- 解释您的代码在哪里符合规范。对于带有示例代码的良好教程,我建议您使用此 secure password hash
此解决方案使您的项目成为现实,您可以重复使用它来通过未来加密模块的考试:)。否则我喜欢 StanislavL 提出的解决方案。
尽情享受吧!
在Java中加密简单字符串的方法太多了。如果是学校的project,我真的不认为光靠用一些第三方的libs来完成加密工作就可以获得更高的band。
如果你有时间,可以尝试了解Base64的工作原理,然后尝试自己创建一些加密算法。
但是,如果你坚持在Java中使用一些API,我不得不说DES确实是加密文本的老方法,3DEs(DESede)或AES会更好并且更安全,自 Java6.
以来,它们都已得到支持如果一定要导入BouncyCastle lib,我更喜欢IDEA,它是最安全的算法之一,可能会让你取得好成绩。
我不会给你任何演示代码,但你可以通过 google 我提到的所有算法轻松找到一些。
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();
}
}
}
我的建议:根本不要使用加密。 这里有更好的东西:(我希望)
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(真,真), 然后关闭输出流后, f.setReadOnly(); 再次... 但是文件仍然可以被替换,因此第一个和更多 有效的。 谢谢
您可以使用这些函数对简单文本进行加密和解密
//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");
}