-1

私はセキュリティに不慣れで、例外を削除するために多くのことを試みました(コードの下)。RC2 暗号と RC6 暗号の両方でこの例外が発生します。入力は 128 ビットStringと 128 ビットのキーである必要があり、出力は 128 ビットの暗号テキストである必要があります。

import java.security.spec.AlgorithmParameterSpec;
import javax.crypto.Cipher;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
import java.util.*;

public class RC2Encrypt
{
    public static void main(String args []) throws Exception
    {
        Scanner s=new Scanner(System.in);
        System.out.println("Enter PlainTextString:");
        String input=s.nextLine();

        System.out.println();
        System.out.println("Enter 16 digit key:");
        String strPassword=s.nextLine();

        SecretKeySpec key = new SecretKeySpec(strPassword.getBytes(), "RC2");
        AlgorithmParameterSpec paramSpec = new IvParameterSpec(strPassword.getBytes());
        Cipher cipher =  Cipher.getInstance("RC2");
        cipher.init(Cipher.ENCRYPT_MODE, key, paramSpec);

        byte[] encrypted = cipher.doFinal(input.getBytes());

        String b1 = new String(encrypted);
        System.out.println("Original string: " + input);
        System.out.println("Encrypted string: " + b1);
    }
}

これにより、次の例外が生成されます。

Exception in thread "main" java.security.InvalidAlgorithmParameterException: Wrong IV    length: must be 8 bytes long
    at com.sun.crypto.provider.SunJCE_f.a(DashoA13*..)
    at com.sun.crypto.provider.RC2Cipher.engineInit(DashoA13*..)
    at javax.crypto.Cipher.a(DashoA13*..)
    at javax.crypto.Cipher.a(DashoA13*..)
    at javax.crypto.Cipher.init(DashoA13*..)
    at javax.crypto.Cipher.init(DashoA13*..)
    at RC2Encrypt.main(RC2Encrypt.java:40) 
4

2 に答える 2

1

RC2 は非常に弱いため、別のアルゴリズムをお勧めします。私の知る限り、JRE にバンドルされている RC6 サポートはありません。

次のように TDES を使用できます。

SecretKeySpec key = new SecretKeySpec(keyBytes, "DESede");
IvParameterSpec ivSpec = new IvParameterSpec(ivBytes);
Cipher cipher = Cipher.getInstance("DESede/CBC/PKCS5Padding");
cipher.init(Cipher.ENCRYPT_MODE, key, ivSpec);
byte[] encrypted = cipher.doFinal(input.getBytes());

ランダムなバイトで構成される初期化ベクトルを指定する必要があり、 (コードのように) キーではないことに注意してください。また、TDES には 128 ビットまたは 192 ビットのキーが必要です。

于 2013-01-12T19:41:15.150 に答える
0

コードには複数の問題があります。

最も重要なのは、文字とバイトを混同していることです。エンコーディング (テキストをバイナリでエンコードして元に戻すこと) と(バイナリを読み取り可能なテキストとしてエンコードすること)について知っておく必要があります。

16 文字でエンコードされた 8 バイトが予想される場合、これは、16 進数のデコード (各バイトに 2 文字を使用) を実行する必要があることを意味します。これを行う最善の方法は、Apache 共通コーデック ライブラリまたは Bouncy Castle ライブラリを使用することです。RC6 を含む、より多くの暗号化アルゴリズムが含まれているため、後者をお勧めします。最善の方法は、暗号化機能に Bouncy Castle プロバイダーを使用することです。

OK、これでキーと IV の部分は解決しました。次はプレーン テキストです。プレーン テキストは、バイナリ エンコードする必要があります。残念ながら、現在はプラットフォームのデフォルトの文字セットを使用しています。これは、別のシステム (別の文字セットを使用している場合は、自分の PC でも別のアプリケーション) と交換する場合、互換性の問題が発生することを意味します。この問題を解決するには、エンコーディングを自分で指定する必要があります。たとえばString.getBytes(Charset.forName("UTF-8"))、Java 7 以降では or を使用しますString.getBytes(StandardCharsets.UTF_8)。コンストラクターについても同じことを行います。

さらに、キーと IV に同じバイトを使用するべきではありません。IV は、セキュリティの脆弱性を導入することなく、同じキーで複数の暗号文を暗号化するために使用されます。たとえば、攻撃者は、それほど秘密ではない最初の暗号文に「yes」という単語が含まれていることを知ることができます。次に、次の暗号ブロックが来て、まったく同じバイトが含まれています。明らかに、送信者は「はい」という言葉をもう一度送信しました。IV が変更された場合、攻撃者はまったく異なる暗号文を見ることになりますが、ストリーム暗号の場合は 3 バイトの長さになります。

最後に、キーと IV はランダムに生成する必要があります (おそらく過去のある時点で)。キーの代わりにパスワードが必要な場合は、次善の代替手段として PBKDF (パスワード ベースのキー派生関数) を使用する必要があります。しかし、それはより高度なトピックになる可能性があると思います。

于 2013-01-13T13:10:44.693 に答える