2017-11-29 1 views
0

私はサーバーに接続するアンドロイドメッセージングアプリケーションを持っています。アプリとサーバーは "パケット"で通信します。これらのパケットは、hybrid encryptionで暗号化された逆シリアル化オブジェクトです。データを暗号化しようとしたとき、私は次のエラーを取得するいくつかの理由:javax.crypto.IllegalBlockSizeExceptionを修正する方法:入力はアンドロイドで64バイト未満でなければなりませんか?

W/System.err: javax.crypto.IllegalBlockSizeException: input must be under 64 bytes 
W/System.err:  at com.android.org.conscrypt.OpenSSLCipherRSA.engineDoFinal(OpenSSLCipherRSA.java:245) 
W/System.err:  at javax.crypto.Cipher.doFinal(Cipher.java:1204) 
W/System.err:  at javax.crypto.SealedObject.<init>(SealedObject.java:103) 
W/System.err:  at com.baiocchi.enigma.client.util.encryption.EncryptionOutputStream.writeObject(EncryptionOutputStream.java:35) 
W/System.err:  at com.baiocchi.enigma.client.util.CredentialInflator.deflateCredentials(CredentialInflator.java:31) 
W/System.err:  at com.baiocchi.enigma.shared.packet.Packet.encryptCredentials(Packet.java:55) 
W/System.err:  at com.baiocchi.enigma.client.util.handlers.PacketDeflationHandler.run(PacketDeflationHandler.java:34) 
W/System.err:  at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1112) 
W/System.err:  at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:587) 
W/System.err:  at java.lang.Thread.run(Thread.java:841) 

私はアイデアの出だとオンライン一切答えをfoudnなかったです。助けてください!

エンクリプタ:

public class Encryptor { 


    public static byte[] encrypt(byte[] data, RSAKey asymmetricKey) { 
     if (asymmetricKey instanceof RSAPublicKey) { 
      return encrypt(data, (RSAPublicKey) asymmetricKey); 
     } 
     return encrypt(data, (RSAPrivateKey) asymmetricKey); 
    } 

    private static byte[] encrypt(byte[] data, RSAPublicKey asymmetricKey) { 
     try { 
      final Cipher cipher = Cipher.getInstance(Config.ASYMMETRIC_TRANSFORMATION); 
      cipher.init(Cipher.ENCRYPT_MODE, asymmetricKey); 
      return cipher.doFinal(data); 
     } catch (Exception e) { 
      e.printStackTrace(); 
     } 
     return null; 
    } 

    private static byte[] encrypt(byte[] data, RSAPrivateKey asymmetricKey) { 
     try { 
      final Cipher cipher = Cipher.getInstance(Config.ASYMMETRIC_TRANSFORMATION); 
      cipher.init(Cipher.ENCRYPT_MODE, asymmetricKey); 
      return cipher.doFinal(data); 
     } catch (Exception e) { 
      e.printStackTrace(); 
     } 
     return null; 
    } 
} 

EncryptionOutputStream:

import javax.crypto.Cipher; 
import javax.crypto.IllegalBlockSizeException; 
import javax.crypto.NoSuchPaddingException; 
import javax.crypto.SealedObject; 
import javax.crypto.spec.IvParameterSpec; 
import java.io.ByteArrayOutputStream; 
import java.io.IOException; 
import java.io.ObjectOutputStream; 
import java.io.Serializable; 
import java.security.InvalidAlgorithmParameterException; 
import java.security.InvalidKeyException; 
import java.security.NoSuchAlgorithmException; 

public class EncryptionOutputStream extends ByteArrayOutputStream { 
    private final Cipher cipher; 

    public EncryptionOutputStream(SymmetricEncryptionKey symmetricEncryptionKey) throws NoSuchPaddingException, NoSuchAlgorithmException, InvalidKeyException, InvalidAlgorithmParameterException { 
     super(); 
     cipher = Cipher.getInstance(Config.SYMMETRIC_TRANSFORMATION); 
     cipher.init(Cipher.ENCRYPT_MODE, symmetricEncryptionKey.getKey(), new IvParameterSpec(symmetricEncryptionKey.getIvParameter())); 
    } 

    public void writeObject(Serializable object) throws IOException { 
     try { 
      final SealedObject sealedObject = new SealedObject(object, cipher); 
      final ObjectOutputStream outputStream = new ObjectOutputStream(this); 
      outputStream.writeObject(sealedObject); 
     } catch (final IllegalBlockSizeException e) { 
      e.printStackTrace(); 
     } 
    } 

} 

パケット暗号化方法:

public final void encryptCredentials(RSAKey asymmetricKey) throws IOException { 
    if (credentials != null) { 
     SymmetricEncryptionKey symmetricEncryptionKey = EncryptionKeyGenerator.createNewSymmetricKey().getSymmetricEncryptionKey(); 
     encryptedCredentials = CredentialInflator.deflateCredentials(symmetricEncryptionKey, credentials); 
     credentials = null; 
     encryptedKey = Encryptor.encrypt(symmetricEncryptionKey.getKey().getEncoded(), asymmetricKey); 
     encryptedIvParameter = Encryptor.encrypt(symmetricEncryptionKey.getIvParameter(), asymmetricKey); 
    } 
} 

資格暗号方式:

を ここで使用される方法であります210
public static byte[] deflateCredentials(SymmetricEncryptionKey key, Credentials credentials) throws IOException { 
    try (EncryptionOutputStream outStream = new EncryptionOutputStream(key)) { 
     outStream.writeObject(credentials); 
     return outStream.toByteArray(); 
    } catch (NoSuchPaddingException e) { 
     e.printStackTrace(); 
    } catch (NoSuchAlgorithmException e) { 
     e.printStackTrace(); 
    } catch (InvalidKeyException e) { 
     e.printStackTrace(); 
    } catch (InvalidAlgorithmParameterException e) { 
     e.printStackTrace(); 
    } 
    return null; 
} 

SymmetricEncryptionKeyクラス:

import javax.crypto.SecretKey; 
public class SymmetricEncryptionKey { 

private final SecretKey key; 
private byte[] ivParameter = new byte[16]; 

public SymmetricEncryptionKey(SecretKey key, byte[] ivParameter) { 
    this.key = key; 
    this.ivParameter = ivParameter; 
} 

public SecretKey getKey() { 
    return key; 
} 

public byte[] getIvParameter() { 
    return ivParameter; 
}} 
+0

例外は投稿したコードをかなり追跡していません。しかし、あなたはConfigクラスの定数の値のような重要な詳細を除外しました。理想的には[MCVE](https://stackoverflow.com/help/mcve)を投稿すると、コードを自分で実行して同じエラーが表示されます。 –

答えて

0

データの最後のブロックは、(0バイトを含むことができる)、64バイト以下でなければなりません。これはアルゴリズムが64バイトブロックで動作し、最終ブロックで適切にデータを埋め込む必要があるためです。 64バイト以上残っている場合は、次の64バイトを非最終として暗号化する必要がある最終ブロックを実行すべきではありません。

あなたがそれを知らないなら、あなたは多くの暗号を勉強していません。私はこれをやっておらず、代わりにSSL経由で接続をトンネリングすることを検討したいと思います。エキスパートでさえ暗号化が容易で間違ってしまう。たとえば、どのように鍵交換をしていますか?テスト済みのライブラリ/ソリューションを使用することは、自分で何かを実行するよりも優れています。

関連する問題