0

これが私のコードです:

import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.PrintWriter;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.util.Date;
import javax.crypto.Cipher;
import javax.crypto.CipherOutputStream;
import javax.crypto.NoSuchPaddingException;
import javax.crypto.spec.SecretKeySpec;

public class EncryptedLogger {

private static Date lastLogTime = null;
private static EncryptedLogger instance = null;
private static FileOutputStream fos = null;
private static CipherOutputStream cos = null;
private static PrintWriter writer = null;
private Cipher cipher;
byte[] Key ={(byte) 0x12,(byte) 0x34,0x55,(byte) 0x66,0x67,(byte)0x88,(byte)0x90,0x12,(byte) 0x23,0x45,0x67,(byte)0x89,0x12,0x33,(byte) 0x55,0x74};

public static EncryptedLogger getInstance(){
    if (instance==null) {
        instance = new EncryptedLogger();
    }
    return instance;
}

private EncryptedLogger(){

    class SQLShutdownHook extends Thread{
        @Override
        public void run() {
            EncryptedLogger.close();
            super.run();
        }
    }

    SecretKeySpec sks = new SecretKeySpec(Key,"AES");
    try {
        cipher = Cipher.getInstance("AES/ECB/NoPadding");
        cipher.init(Cipher.ENCRYPT_MODE,sks);

        fos = new FileOutputStream(new File("log.txt"),true);
    } catch (InvalidKeyException e) {
        e.printStackTrace();
    } catch (NoSuchAlgorithmException e) {
        e.printStackTrace();
    } catch (NoSuchPaddingException e) {
        e.printStackTrace();
    } catch (FileNotFoundException e) {
        e.printStackTrace();
    }
    cos = new CipherOutputStream(fos, cipher);
    writer = new PrintWriter(cos);

    SQLShutdownHook hook = new SQLShutdownHook();
    Runtime.getRuntime().addShutdownHook(hook);
}

public synchronized void logSQL(String s){
    if ((lastLogTime==null)||((new Date().getTime() -lastLogTime.getTime())>1000)){
        lastLogTime = new Date();
        writer.printf("-- %1$tm-%1$te-%1$tY %1$tH-%1$tM-%1$tS\n%2$s\n",new Date(),s);   
    }
    else{
        writer.println(s);
    }
}

public synchronized void logComment(String s){
    writer.printf("-- %1$tm-%1$te-%1$tY %1$tH-%1$tM-%1$tS: %2$s\n",new Date(),s);
}

public static void close(){
    writer.flush();
    writer.close();
}

public static void main(String[] args) throws InterruptedException {
    EncryptedLogger.getInstance().logSQL("1");
    EncryptedLogger.getInstance().logSQL("22");
    EncryptedLogger.getInstance().logSQL("33333");
    EncryptedLogger.getInstance().logSQL("4900");
    EncryptedLogger.getInstance().logSQL("5");
    EncryptedLogger.getInstance().logSQL("66666");
    EncryptedLogger.getInstance().logSQL("Some test logging statement");
    EncryptedLogger.getInstance().logSQL("AAAAAAAAAAAAAAAAAAAAAAAAAA");
    EncryptedLogger.getInstance().logComment("here is test commentary");
}

}

ご覧のとおり、PrintWriter->CipherOutputStream->FileOutputStream チェーンを介してパイプするテキスト エントリを暗号化しようとしています。しかし、結果ファイルを復号化すると、バイトが欠落しています。EncryptedLogger.close() メソッドでcosfosをフラッシュしようとしましたが、結果は同じです。明らかに私は何かが欠けています。なにが問題ですか?

編集:これが私が使用する復号化コードです。それは私のものではなく、チュートリアルか何かから取ったものです...そして、同様の暗号化を使用するとうまく機能します。しかし、私のコードを使用すると...

import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.io.OutputStream;
import javax.crypto.Cipher;
import javax.crypto.CipherInputStream;
import javax.crypto.SecretKey;
import javax.crypto.spec.SecretKeySpec;

public class AESDecrypter
{
        Cipher dcipher;

        public AESDecrypter(SecretKey key)
        {

                try
                {
                        dcipher = Cipher.getInstance("AES");
                        dcipher.init(Cipher.DECRYPT_MODE, key);
                }
                catch (Exception e)
                {
                        e.printStackTrace();
                }
        }

        byte[] buf = new byte[1024];

        public void decrypt(InputStream in, OutputStream out)
        {
            System.out.println("decrypting");
            try
                {
                        in = new CipherInputStream(in, dcipher);
                        int numRead = 0;
                        while ((numRead = in.read(buf)) >= 0)
                        {
                                out.write(buf, 0, numRead);
                        }
                        out.close();
                }
                catch (java.io.IOException e)
                {
                }
        }

        public static void main(String args[])
        {
                try
                {
                        byte[] keystr ={(byte) 0x12,(byte) 0x34,0x55,(byte) 0x66,0x67,(byte)0x88,(byte)0x90,0x12,(byte) 0x23,0x45,0x67,(byte)0x89,0x12,0x33,(byte) 0x55,0x74};
                        SecretKeySpec sks = new SecretKeySpec(keystr,"AES");                        
                        AESDecrypter encrypter = new AESDecrypter(sks);
                        encrypter.decrypt(new FileInputStream("sqllogenc.log"),new FileOutputStream("sqllogdec.log"));
                }
                catch (Exception e)
                {
                        e.printStackTrace();
                }
        }
}

EDIT2 : fosに直接書き込むと、次の出力が得られます:

-- 04-19-2012 16-17-56
1
22
33333
4900
5
66666 + delay starting 1100
Some test logging statement
AAAAAAAAAAAAAAAAAAAAAAAAAA
-- 04-19-2012 16-17-56: here is test commentary

cosを使用して書き込み、復号化する場合:

-- 04-19-2012 16-22-13
1
22
33333
4900
5
66666 + delay starting 1100
Some test logging statement
AAAAAAAAAAAAAAAAAAAAAAAAAA
-- 04-19-2012 16-22-13: here 

ご覧のとおり、改行を含む最後の行の一部が欠落しています。

4

2 に答える 2

1

AES/ECB/NoPadding両側で同じ暗号変換(など)を使用する必要があります。NoPaddingまた、モードでは任意のサイズのデータ​​を渡すことができないため、他の種類のパディングを指定する必要があることに注意してください。

したがって、両側のようにCiphersを作成する必要があります。Cipher.getInstance("AES/ECB/PKCS5Padding")

CBCまた、の使用またはCTR代わりに、rossumの提案に注意してくださいECB

于 2012-04-19T14:17:31.553 に答える
1

AES のブロック サイズは 128 ビットに固定されています。AES/ECB/NoPadding を使用する場合、メッセージのサイズがブロック サイズの倍数であることを確認する責任があります。

おそらくそうではないため、復号化するとテキストが少なくなります。

任意の長さのテキストには AES/ECB/NoPadding を使用する必要があります。

于 2012-04-19T14:29:39.667 に答える