1

暗号化時にエラーが発生する問題があります。

javax.crypto.IllegalBlockSizeException: data not block size aligned
    at org.bouncycastle.jcajce.provider.symmetric.util.BaseBlockCipher.engineDoFinal(Unknown Source)
    at javax.crypto.Cipher.doFinal(Cipher.java:2086)
    at com.lcp.sso.logic.SsoCipher.encode(SsoCipher.java:89)

オブジェクトのコンストラクタ:

public MyCipher() throws NoSuchAlgorithmException, NoSuchProviderException, NoSuchPaddingException, InvalidKeyException, UnsupportedEncodingException {
    Security.addProvider(new BouncyCastleProvider());
    KeyGenerator keyGen = KeyGenerator.getInstance("DESede", "BC");
    keyGen.init(new SecureRandom());
    SecretKey keySpec = keyGen.generateKey();

    this.sharedKey = keySpec.getEncoded().toString();
    this.encrypter = Cipher.getInstance("DESede/ECB/Nopadding", "BC");
    this.encrypter.init(Cipher.ENCRYPT_MODE, keySpec);
    this.decrypter = Cipher.getInstance("DESede/ECB/Nopadding", "BC");
    this.decrypter.init(Cipher.DECRYPT_MODE, keySpec);
}

エラーが発生するメソッド:

public String encode(String arg_text) throws IllegalBlockSizeException, BadPaddingException {
    byte[] encrypt = arg_text.getBytes();

    if(encrypt.length % 8 != 0){ //not a multiple of 8
        //create a new array with a size which is a multiple of 8
        byte[] padded = new byte[encrypt.length + 8 - (encrypt.length % 8)];

        //copy the old array into it
        System.arraycopy(encrypt, 0, padded, 0, encrypt.length);
        encrypt = padded;
    }

    byte[] b = Base64.encodeBase64URLSafe(encrypt);
    return Base64.encodeBase64String(encrypter.doFinal(b));
}

そこで最後のメソッドを呼び出すと、エラーが発生します。8 の倍数になるようにバイト配列をヌルで埋めて、正しいブロック サイズにしていると断言します。

私が使用している:
Eclipse バージョン: Juno Service Release 1
サーバー: Localhost の Tomcat v7.0 サーバー (具体的には 7.0.32 )

---編集---

プログラムはまだ動作していません (編集: はい、そうです! ムアハハハ!) しかし、この問題は解決されました。

オブジェクトのコンストラクタ:

public MyCipher() throws NoSuchAlgorithmException, NoSuchProviderException, NoSuchPaddingException, InvalidKeyException, UnsupportedEncodingException, InvalidParameterSpecException, InvalidAlgorithmParameterException {
    Security.addProvider(new BouncyCastleProvider());
    KeyGenerator keyGen = KeyGenerator.getInstance("DES", "BC");
    keyGen.init(new SecureRandom());
    SecretKey keySpec = keyGen.generateKey();

    this.sharedKey = new String( Base64.encodeBase64URLSafe( keySpec.getEncoded() ) );
    this.encrypter = Cipher.getInstance("DES/CBC/PKCS5Padding", "BC");
    this.encrypter.init(Cipher.ENCRYPT_MODE, keySpec);

    AlgorithmParameters params = this.encrypter.getParameters();
    byte[] iv = params.getParameterSpec(IvParameterSpec.class).getIV();
    IvParameterSpec ivSpec = new IvParameterSpec(iv);

    this.sharedIV = new String( Base64.encodeBase64URLSafe( iv ) );
    this.decrypter = Cipher.getInstance("DES/CBC/PKCS5Padding", "BC");
    this.decrypter.init(Cipher.DECRYPT_MODE, keySpec, ivSpec);
}

そして、暗号化方法は次のとおりです。

public String encode(String arg_text) throws IllegalBlockSizeException, BadPaddingException, UnsupportedEncodingException {
    byte[] encrypt = arg_text.getBytes();
    return new String( Base64.encodeBase64URLSafe(encrypter.doFinal(encrypt)), "US-ASCII");
}

現在、暗号化と復号化に問題なく機能しています。どうもありがとうございます。

4

1 に答える 1

4

いくつかの面で奇妙なコード。コードが機能しない理由から始めて、のサイズがencrypt8の倍数であることを確認していますが、8の倍数ではない可能性がある暗号化を試みていますbyte[] b = Base64.encodeBase64URLSafe(encrypt);。次のコードは機能するはずです:

public String encode(String arg_text) throws IllegalBlockSizeException, BadPaddingException {
    byte[] encrypt = arg_text.getBytes();

    if(encrypt.length % 8 != 0){ //not a multiple of 8
        //create a new array with a size which is a multiple of 8
        byte[] padded = new byte[encrypt.length + 8 - (encrypt.length % 8)];

        //copy the old array into it
        System.arraycopy(encrypt, 0, padded, 0, encrypt.length);
        encrypt = padded;
    }

    return new String(Base64.encodeBase64URLSafe(encrypter.doFinal(b)), "US-ASCII");
}

this.encrypter = Cipher.getInstance("DESede/ECB/Nopadding", "BC");では、文字列の「Nopadding」部分はどこにあるでしょうか。さて、コードはあなたが要求したことを実行します...しかし、ライブラリはパディング作業を行うことができます.あなたはそれを伝えるだけです. this.encrypter = Cipher.getInstance("DESede/ECB/PKCS5Padding", "BC");代わりに試してみて、それが機能するかどうかを確認してください。

しかし、実際には、なぜ ECB モードで 3DES を使用したいのでしょうか? 理由がレガシーでない限り (ここで見たものからはありそうもないことですが)、意味がありません。暗号についてもう少し読む必要があると思います。

于 2013-02-28T23:32:46.467 に答える