2017-08-29 17 views
1

Bouncy Castle 1.58(org.bouncycastle:bcprov-jdk15on:1.58)を使用してパスワードからペイロードを暗号化しようとしています:JavaでBouncy Castle暗号を初期化しようとすると鍵長が128/192/256ではない

import org.bouncycastle.jce.provider.BouncyCastleProvider; 

import javax.crypto.Cipher; 
import javax.crypto.SecretKey; 
import javax.crypto.SecretKeyFactory; 
import javax.crypto.spec.PBEKeySpec; 
import javax.crypto.spec.PBEParameterSpec; 
import java.security.SecureRandom; 
import java.security.Security; 

public class Scratch { 
    public static void main(String[] args) throws Exception { 
     int keyLength = 128; 

     Security.addProvider(new BouncyCastleProvider()); 

     String password = "password"; 

     SecureRandom randomGenerator = new SecureRandom(); 
     byte[] salt = randomGenerator.generateSeed(128/8); 
     PBEKeySpec keySpec = new PBEKeySpec(password.toCharArray(), salt, 872791, keyLength); 
     SecretKeyFactory secretKeyFactory = SecretKeyFactory.getInstance("PBKDF2WithHmacSHA512"); 
     SecretKey passwordKey = secretKeyFactory.generateSecret(keySpec); 
     System.out.println("passwordKey: " + passwordKey); 
     System.out.println("passwordKey.getEncoded(): " + Arrays.toString(passwordKey.getEncoded())); 
     System.out.println("passwordKey.getEncoded().length: " + passwordKey.getEncoded().length); 
     System.out.println("passwordKey.getFormat():" + passwordKey.getFormat()); 
     System.out.println("passwordKey.getAlgorithm(): " + passwordKey.getAlgorithm()); 

     Cipher cipher = Cipher.getInstance("AES/GCM/NoPadding", "BC"); 
     PBEParameterSpec parSpec = new PBEParameterSpec(salt, 872791); 
     cipher.init(Cipher.ENCRYPT_MODE, passwordKey, parSpec); 
    } 
} 

、これは私が取得エラーです:

Exception in thread "main" org.bouncycastle.jcajce.provider.symmetric.util.BaseBlockCipher$InvalidKeyOrParametersException: Key length not 128/192/256 bits. 
    at org.bouncycastle.jcajce.provider.symmetric.util.BaseBlockCipher.engineInit(Unknown Source) 
    at javax.crypto.Cipher.init(Cipher.java:1394) 
    at javax.crypto.Cipher.init(Cipher.java:1327) 
    at tech.dashman.dashman.Scratch.main(Scratch.java:30) 
Caused by: java.lang.IllegalArgumentException: Key length not 128/192/256 bits. 
    at org.bouncycastle.crypto.engines.AESEngine.generateWorkingKey(Unknown Source) 
    at org.bouncycastle.crypto.engines.AESEngine.init(Unknown Source) 
    at org.bouncycastle.crypto.modes.GCMBlockCipher.init(Unknown Source) 
    at org.bouncycastle.jcajce.provider.symmetric.util.BaseBlockCipher$AEADGenericBlockCipher.init(Unknown Source) 
    ... 4 more 

およびデバッグ出力は次のようになります。

passwordKey: [email protected] 
passwordKey.getEncoded(): [122, -75, -99, 114, -123, 71, 6, 50, 45, 64, -97, 10, -66, 7, 110, 17] 
passwordKey.getEncoded().length: 16 
passwordKey.getFormat():RAW 
passwordKey.getAlgorithm(): PBKDF2WithHmacSHA512 

何A私は行方不明ですか?

+0

は、256ビットの実際の重要ですか? 128ビットの鍵は256ビット鍵と同じくらい安全であり、どちらもブルートフォース攻撃の影響を受けないことに注意してください。もちろん、大きなキーは赤い車と同じように男らしいです。 {ほとんどの人が128ビットの代わりに256ビットの暗号化を使用するのはなぜですか?](https://security.stackexchange.com/a/19762/5121)を参照してください。 – zaph

+0

サイズ、128,192、および256のいずれも機能しません。 – Pablo

+0

エラーメッセージ: '原因:java.lang.IllegalArgumentException:キーの長さが128/192/256ビットではありません。 '実際に失敗したキーは何ですか? – zaph

答えて

1

問題が見つかりました。私は秘密鍵の工場を取得するときにプロバイダを指定していませんでした。交換:この例の作品を作った

SecretKeyFactory secretKeyFactory = SecretKeyFactory.getInstance("PBKDF2WithHmacSHA512", "BC"); 

ため

SecretKeyFactory secretKeyFactory = SecretKeyFactory.getInstance("PBKDF2WithHmacSHA512"); 

を。 AESについては

+1

これが解決策である場合、例外はあまり意味がありません。問題がプロバイダーの場合、Bouncy Castleが無効なキーの例外をスローするのはなぜですか? 'passwordKey.getEncoded()'を見ると、いくつかの文字は上位ビットがセットされています。それらは、キーが現れるよりも小さくなるように、単一のコードポイントに結合されていますか?たぶん、Bouncy Castleはもっと寛容で、文字を組み合わせることなくバイト配列として扱うでしょうか? – jww

+0

@jww私はPabloがもっと多くの変更を加えたと確信しています。確かにこのコード自体は助けてはなりません(IMHOの定義通り、BCによって提供されないため別の例外が生成されることさえあります) – gusto2

1

あなたはPBE秘密鍵に基づいていますAES秘密鍵を、必要とする:

SecretKeyFactory secKeyFactory = SecretKeyFactory.getInstance("PBKDF2WithHmacSHA512"); 
KeySpec spec = new PBEKeySpec(password, salt, iterations, 128); 
SecretKey pbeSecretKey = secKeyFactory.generateSecret(spec); 
SecretKey aesSecret = new SecretKeySpec(pbeSecretKey.getEncoded(), "AES"); 

Cipher cipher = Cipher.getInstance("AES/GCM/NoPadding","BC"); 
関連する問題