2017-08-05 19 views
-1

AESを使用してデータを暗号化しようとしていますが、出力が入力よりも大きい理由はわかりません。 私はその後、キー暗号化されたデータが入力データより大きい

public byte[] deriveKey(String p, byte[] s, int i, int l) throws Exception { 

    PBEKeySpec ks = new PBEKeySpec(p.toCharArray(), s, i, l); 
    SecretKeyFactory skf = SecretKeyFactory.getInstance("PBKDF2WithHmacSHA1"); 
    return skf.generateSecret(ks).getEncoded(); 
} 

を導出するために、この機能を使用(154バイト)私は(112バイト)のデータと暗号化機能にキーを送るが、私は暗号化されたデータを取得

public String encrypt(String s,byte[] d) throws Exception { 

    // Perform Encryption 
    SecretKeySpec eks = new SecretKeySpec(d, "AES"); 
    Cipher c = Cipher.getInstance("AES/CTR/NoPadding"); 
    c.init(Cipher.ENCRYPT_MODE, eks, new IvParameterSpec(new byte[16])); 
    byte[] es = c.doFinal(s.getBytes(StandardCharsets.UTF_8)); 
} 
+1

暗号化は圧縮ではありません。暗号化の結果は、暗号化方式によって大きくても小さくてもよい。 –

+1

@ישואוהבאותךしかしOPのケースではありません。彼はCTRモードを使用しているので、得られる暗号文は平文と全く同じバイト長でなければなりません。 –

+0

あなたの例は不完全でした。暗号化関数は文字列を返しますが、最後の文はバイト配列を返します。私の推測では、あなたの結果は、結果のサイズを考慮に入れて返す前に、結果をコード化しています。 –

答えて

-1

多くの暗号化アルゴリズムでは、パディングは避けられません。そのため、暗号のサイズが大きくなるのが見えます。 s.getBytes(StandardCharsets.UTF_8)https://security.stackexchange.com/questions/29993/aes-cbc-padding-when-the-message-length-is-a-multiple-of-the-block-size

+0

パディングの必要性は、暗号自体ではなく、ブロックモードによって決まります。 CTRモードは、定義上、パディングを必要としません。あなたがリンクしている記事では、使用されているモードはCBC、**ではなく** CTRです。 –

+0

指定されたコードは、パディングを指定しません: 'Cipher c = Cipher.getInstance(" AES/CTR/NoPadding ");' – rossum

0

暗号化したい平文を使用すると、右の暗号化の前にバイト配列にエンコードした文字列(s)です:あなたは何が起こるかを理解するためにこの投稿は役に立つかもしれません。

平文文字列にASCII以外の文字(コードポイント128以上)が含まれている場合、それらはUTF-8で2バイト以上の文字としてエンコードされます(Wikipedia articleの表を参照)。英語のテキストは、文字と同じバイト数で構成されています。他の言語はあまり幸運ではないかもしれませんし、文字列からバイナリデータへのエンコーディングは爆破されるでしょう。

CTRモードはストリーミング動作モードなので、平文/暗号文入力は常に暗号文/平文出力と同じサイズになります。もちろん、AES-CTRのようなスキームには、キー、データ、IV /ノンスという3つの入力があります。あなたが鍵パスワードを/変更している場合

のみあなたは、静的なゼロバイトのIVを使用して、暗号化するたびに多少のセキュアになります。パスワード/キーを一度でも再利用すれば、2回のパッド(多くの時間パッド)に遭遇し、攻撃者は単純に暗号文を見ると、平文を見るだけで平文を推測することができます(nice example)。

パスワード/キーの1回の使用を保証できない場合は、暗号化するたびに新しいIVを使用する必要があります。もう一度new IvParameterSpec(new byte[16])などですが、

SecureRandom r = new SecureRandom(); 
byte[] iv = new byte[16]; 
r.nextBytes(iv); 
Arrays.fill(iv, 12, 16, (byte)0); // zero out the counter part 
関連する問題