私の学校プロジェクトでは、プログラム内でファイル処理を利用できることを示さなければなりませんでした。このために、リソースフォルダーにあるテキストファイルにユーザー名とパスワードを書き込むアカウントを作成できる非常に簡単なログインプロセスを作成しました。明らかに、これはファイル処理を示すためだけに安全になるように設計されていないため、まったくセキュリティがありませんが、教師は、より良い成績を得るためにファイルに暗号化を追加することを試みるべきだと言っています。
私はいくつかの研究を行ってきましたが、多くの人がDESを推奨しています。
私が抱えている問題は、プロジェクトに残された時間があまりなく、できるだけ早く終了する必要があることです。 DESを使用すると、余分なコードをすべて実装するのに時間がかかるようです。
私のプログラムでは、単純なlineNumberReaderを使用して、ファイルを1行ずつ読み取ります。ファイルに書き込むには、BufferedWriterを使用しています。
とにかくこのデータを非常に簡単に暗号化する方法はありますか?それほど安全である必要はありませんが、少なくともデータを暗号化しようとしたことを示す必要があります。データが転送されていないため、暗号化と復号化はすべて同じアプリケーションで完了します。
非常に簡単な暗号化および復号化アルゴリズムを自分で作成する方法はありますか?
これを試してください...その非常にシンプルな
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");
}
}
}
したがって、基本的にファイルに書き込む前に暗号化し、読み取り後に復号化する必要があります。
非常に基本的な方法は、データをキーでxorすることです。この方法は対称的です。つまり、同じキーを使用してエンコードとしてデコードできます。
1バイトのキーを選択する場合、それは読みやすくするのに十分である(しかし、まったく安全ではありません!)素敵でシンプルです:
private void encodeDecode(byte[] bytes, byte key) {
for(int i=0; i<bytes.length; i++)
bytes[i] = (byte) (bytes[i]^key);
}
シンプルなシーザー暗号を使用できます( 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変換 です。本当に安全な暗号化ではありませんが、真剣に、それは学校の仕事であり、これは素晴らしいです。
Javaで単純な文字列を暗号化する方法は多すぎます。学校のプロジェクトの場合、暗号化された作業を完了するためにサードパーティのライブラリを使用するだけでは、より高い帯域を獲得できるとは本当に思いません。
時間があれば、Base64の仕組みを理解してから、自分で暗号化アルゴリズムを作成してみてください。
ただし、JavaでAPIを使用することを主張する場合、DESは暗号化されたテキスト、3DEs(DESede)またはAESはより良く安全になります。どちらもJava6以降で既にサポートされています。
BouncyCastle libをインポートする必要がある場合、IDEAをお勧めします。これは最も安全なアルゴリズムの1つであり、良いスコアを達成できる可能性があります。
デモコードは提供しませんが、Googleで説明したすべてのアルゴリズムを簡単に見つけることができます。
パスワードを暗号化するためにDESを推奨している人はわかりません。先生に感銘を与えるには、次の手順に従うことをお勧めします。
このソリューションはプロジェクトを現実のものにし、将来の暗号モジュールの試験に合格するために再利用できます:)。それ以外の場合、StanislavLから提案されたソリューションが好きです。
楽しい!
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 ) );
}
}
これらの関数を使用して、単純なテキストを暗号化および復号化できます
//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");
}