0

上記のように、Java の UTF-16LE に問題があります。コードを実行すると、通常、メッセージが正しく暗号化、復号化、および出力されます。暗号化された文字の 2 つが失われることもあれば、ギリシャ語などの英語以外の文字が出力されることもあります。

これはクラス用であり、教授を困惑させました。エラーについての助けをいただければ幸いです。

/*This program was written by me for my professors class.

このプログラムの目的は、XOR 暗号化を使用してメッセージを暗号化し、同じ方法で復号化し、これらのメソッドのコードブックを生成することです。*/

import java.security.*;

public class Crypto 
{
    public static void main(String[] args) throws Exception
    {           
        Crypto c = new Crypto(); 

        byte[]codebook = null;
        String message = "";   

        System.out.println("Generating codebook");
        codebook = c.makeCodebook(14);
        System.out.println();

        System.out.println("Now Encrypting");
        System.out.println("This is the contents of the Encrypted Message: ");
        message = c.crypt("1234567", codebook);
        System.out.println();

        System.out.println("Now Decrypting");
        System.out.println("This is the contents of the Decrypted Message");
        message = c.crypt(message, codebook);

        System.out.println();
        System.out.println("Your message is: ");      
        System.out.println(message);

    }//publis static void main(String [] args)

    //Encrypts or decrypts message against the codebook assuming the appropriate length
    public String crypt (String message, byte [] codebook) throws Exception
    {
        //Take the message and put it into an array of bytes.
        //This array of bytes is what will be XORed against the codebook
        byte[] cryptedMessage = message.getBytes("UTF-16LE");
        byte[] result = new byte[14];
        message = "";
        System.out.println(message.length());
        System.out.println(cryptedMessage.length);
        System.out.println(result.length);
        //Let's see the contents of encryptedMessage
        for(int i = 0; i< cryptedMessage.length; i++)
        {
            System.out.print(cryptedMessage[i]+" ");
        }//for(int i = 0; i< encryptedMessage.length; i++)
        System.out.println();

        //XOR codebook and encryptedMessage
        System.out.println("This is the message using XOR:");
        for(int i = 0; i<result.length; i++)
        {
            //since XOR has return type of an int, we cast it to a byte
            result[i] = (byte)(((byte)(codebook[i])) ^ ((byte)(cryptedMessage[i])));
            System.out.print(result[i]+" ");
        }//while(result[i]!=0)
        //output
        System.out.println();
        //output

        System.out.println(message.length());
        System.out.println(cryptedMessage.length);
        System.out.println(result.length);
        return new String(result, "UTF-16LE");
    }//public String crypt (String message, byte [] codebook) throws Exception

    //Creates truly random numbers and makes a byte array using those truly random numbers
    public byte [] makeCodebook (int length) throws Exception
    {
        SecureRandom SecureRandom = new SecureRandom();//instance of SecureRandom named random
        byte[] codebook = null;

        codebook = new byte[length];
        SecureRandom.nextBytes(codebook);//generate bytes using the byte[]codebook

        //output
        System.out.println("This is the contents of the codebook: ");
        for(int i = 0; i < codebook.length;i++)
        {
            System.out.print(codebook[i]+" ");
        }//for(int i = 0; i < codebook[i];i++)
        //output
        System.out.println();
        return codebook;
    }//public byte [] MakeCodebook (int length) throws Exception

}//Public class Crypto
4

2 に答える 2

3

問題はおそらく、XORランダム データに対する ing が、UTF-16LE バイト シーケンスとして解釈されるときに有効な文字セットを表現しない出力を生成することがあるからです。

暗号文を UTF-16LE 文字列として解釈しようとする代わりに、生成した暗号文バイトを base64 でエンコードし、結果の base64 でエンコードされた文字列を返すことを検討してください。次に、復号化するときに、入力文字列を base64 デコードして暗号文のバイトを取得し、XOR を実行して平文のバイトを取得し、平文のバイトを UTF-16LE シーケンスとして解釈して平文のバイトから平文の文字列を作成します。


スペース不足を心配することなく、以下のコメントに返信できるように更新しました。

先ほど言ったように、暗号文のバイトを base64 でエンコードできます。それは確かにJavaで実行可能です。commons-codec ライブラリにはそれを行うメソッドがあり、検索すると他のメソッドが見つかります。外部ライブラリの使用が許可されていない場合は、任意のバイトを何かの有効なエンコーディングであることが保証されたバイトに変換する独自の方法をロールバックします。

たとえば、暗号文の各バイトを上位 4 ビットと下位 4 ビットに分割できます。したがって、各バイトは、それぞれが 0 ~ 15 の範囲の値のペアを生成します。次に、これらの数値に の ASCII コードを追加することにより、各バイトから 2 バイトのシーケンスを生成でき'A'ます。これはあまり効率的ではありませんが、機能します。

于 2012-05-14T16:16:42.137 に答える
0

ステートメントが以下のチェックを追加した場合、ArrayIndexOutOfBoundsException エラーのコードをチェックする必要があります。アラビア語のような英語以外の文字を試すと、常に //XOR コードブックと encryptedMessage System.out.println("This is the message using XOR:"); がスローされます。for(int i = 0; i

            //since XOR has return type of an int, we cast it to a byte
            if(result.length<=cryptedMessage.length){
            result[i] = (byte)(((byte)(codebook[i])) ^ ((byte)(cryptedMessage[i])));
            System.out.print(result[i]+" ");
            }
        }
于 2012-05-14T16:49:14.517 に答える