Java AES:インストールされているプロバイダーがこのキーをサポートしていません:javax.crypto.spec.secretkeyspec

StackOverflow https://stackoverflow.com/questions/8362262

質問

私は128ビットAES暗号化を設定しようとしています、そして、私は自分のcipher.initに例外を投げかけています:

No installed provider supports this key: javax.crypto.spec.SecretKeySpec

次のコードを使用して、クライアント側のキーを生成しています。

private KeyGenerator kgen;
try {
        kgen = KeyGenerator.getInstance("AES");
    } catch (NoSuchAlgorithmException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }
    kgen.init(128);
}
SecretKey skey = kgen.generateKey();

このキーは、ヘッダーとしてサーバーに渡されます。この関数を使用してbase64エンコードされています。

public String secretKeyToString(SecretKey s) {
        Base64 b64 = new Base64();
        byte[] bytes = b64.encodeBase64(s.getEncoded());
        return new String(bytes);
}

サーバーがヘッダーを引いて、そうします

protected static byte[] encrypt(byte[] data, String base64encodedKey) throws InvalidKeyException, IllegalBlockSizeException, BadPaddingException {
    Cipher cipher;
    try {
        cipher = Cipher.getInstance("AES");
    } catch (NoSuchAlgorithmException ex) {
        //log error
    } catch (NoSuchPaddingException ex) {
        //log error
    }
    SecretKey key = b64EncodedStringToSecretKey(base64encodedKey);
    cipher.init(Cipher.ENCRYPT_MODE, key); //THIS IS WHERE IT FAILS
    data = cipher.doFinal(data);
    return data;
}
private static SecretKey b64EncodedStringToSecretKey(String base64encodedKey) {
    SecretKey key = null;

    try {
        byte[] temp = Base64.decodeBase64(base64encodedKey.getBytes());
        key = new SecretKeySpec(temp, SYMMETRIC_ALGORITHM);
    } catch (Exception e) {
        // Do nothing
    }

    return key;
}

これをデバッグするために、クライアント側のキー生成の両方の後、サーバー側のcipher.initの直前にブレークポイントを置きます。 NetBeansによると、シークレットを構成するバイトは同一であり、長さは16バイトです(実際、私が知る限り、オブジェクトは同一です)。

私は無制限の強さJCEのものを知っていますが、128ビットAEに必要な印象を受けていません。

クライアント側:Javaバージョン「1.6.0_26」

サーバー側:Javaバージョン「1.6.0_20」

何か案は?

役に立ちましたか?

解決

次の方法で、さまざまな方法でコードを実行します。Java1。{5,6,7}(AESを使用);異なるBase64コーデック(Apache Commons Codec、DataTypeConverted、Base64);異なる文字セット。異なるJVM(ソケットを介して)間で…役に立たない。エラーがありませんでした。

問題を絞り込むために、次のコードを実行できますか 両方 終わり?

static {
  System.out.println(System.getProperty("java.version"));
  for (Provider provider : Security.getProviders())
    System.out.println(provider);
}

public static void main(String[] args) throws Exception {
  KeyGenerator keyGenerator = KeyGenerator.getInstance("AES");
  keyGenerator.init(128);
  SecretKey secretKey = keyGenerator.generateKey();
  Cipher cipher = Cipher.getInstance("AES");
  cipher.init(Cipher.ENCRYPT_MODE, secretKey);
}

(私はあなたがあなたが使用しているJDKバージョンなどをすでに述べていることを知っていますが、それは傷つくことはできません。)

キーがクライアントからサーバーに転送されている間(または逆の場合)、キーが破損しないことを考えると、次の場合

  • クライアントはスローしますが、サーバーはそうではありません。エラーはクライアント側にあります。
  • クライアントはスローしませんが、サーバーはそうします。エラーはサーバー側にあります。
  • クライアントとサーバーはどちらもスローします。どちらもいません。さらなる調査が必要です。

いずれにせよ、エラーがスローされている場合は、 全体 どこかにトレースをスタックします。エラー No installed provider supports this key: javax.crypto.spec.SecretKeySpec 何も教えてくれません(少なくとも私にとってはそうではなく、この特定のエラーも再現できませんでした)。

他のヒント

このエラーは、JCE(Java暗号拡張)をインストールする必要があることを示している可能性があります。

このファイル(または新しいバージョン)をダウンロードし、jarsをjdk_folder/jre/lib/securityにコピーしますhttp://www.oracle.com/technetwork/pt/java/javase/downloads/jce-6-download-429243.html

このエラーは、間違ったキーを提供するときに私に起こります SecretKeySpec コンストラクタ。

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top