Java のセキュリティに問題があります。大量のバイトがあり、それらを N バイトのチャンクに分割し、暗号化し、別々の (独立した) メッセージで送信したいと考えています。
ここに私の基本的な暗号があります:
private byte[] generateIv(int size) {
byte[] iv = new byte[size];
randomSecureRandom.nextBytes(iv);
return iv;
}
@Override
public byte[] encryptData(byte[] iv, byte[] in, Key key) throws CryptoException {
try {
Cipher c = Cipher.getInstance("AES/CTR/PKCS5Padding");
c.init(Cipher.ENCRYPT_MODE, key, new IvParameterSpec(iv));
return c.doFinal(in);
} catch (Exception ex) {
throw new CryptoException(ex);
}
}
@Override
public byte[] decryptData(byte[] iv, byte[] in, Key key) throws CryptoException {
try {
Cipher c = Cipher.getInstance("AES/CTR/PKCS5Padding");
c.init(Cipher.DECRYPT_MODE,key, new IvParameterSpec(iv));
return c.doFinal(in);
} catch(Exception ex) {
throw new CryptoException(ex);
}
}
@Override
public byte[] createHMAC(byte[] pauload, Key sigKey) throws CryptoException {
try {
Mac mac = Mac.getInstance("HMACSHA256");
mac.init(sigKey);
byte[] digest = mac.doFinal(pauload);
return digest;
} catch (Exception e) {
throw new CryptoException("unable to create HMAC",e);
}
}
次のようなメッセージを作成します (最初のハンドシェイクで AES-128 セッション キーが生成されます)。
byte[] iv = generateIv();
byte[] hmac = createHMAC (inputBytes,key);
byte[] enc = encryptData(iv,inputBytes,key);
それから私はメッセージに書きます:
[iv bytes][enc bytes][hmac bytes]
反対側では、私は:
byte[] iv = readFirstEightBytes(inputBytes);
byte[] dec = decryptData(iv,inputBytes[8..N+8],key);
byte[] hmac = createHMAC(dec,inputBytes[N+9..end],key);
// compare hmac
return dec;
これはすべてうまく機能しますが、ハンマーで叩き始めると、本当に、本当に、遅くなる傾向があります。私のホットスポットは次のとおりです。
encryptData 27%
createHMAC 22%
decryptData 18%
私はここで素朴なのか疑問に思っていましたか?明らかな何かが欠けていますか?毎回新しい Cipher インスタンスを取得するべきではないのではないかと思っていました...しかし、多くの同時実行性が得られました。インスタンスをスレッドセーフに共有しようとすることもおそらく理想的ではないと推測しています...
コードの残りの部分には改善の余地がたくさんあるので、暗号化の部分がさらに悪くなります。
誰が考えているのですか?それとも、20 mb/s の合計スループットは (最新の頑丈なラップトップで) 十分に優れているのでしょうか?