2

注: Java NOOB。

わかりました、これはここで数十回回答されていることを知っていますが、解決策は機能していないようです/私が理解している場所に直接適用されるようには見えません. (はい、暗号化/復号化、AES などを完全に理解していないことはわかっていますが、それは重要ではありません。これを理解しようとしています)

文字列を渡し、暗号化された文字列を返したいユーティリティ API があります。次に、暗号化された文字列を渡し、復号化された文字列を返します。単純。渡す多くの文字列に対しては正常に機能しますが、一部の文字列では例外が発生しますjavax.crypto.BadPaddingException: Given final block not properly padded.

たとえば、次の暗号化/復号化は正常に行われます。
util/encrypt/?token=123456789012wha= 4TR0CbCcQKqeRK73zr83aw==
util/decrypt/?token=4TR0CbCcQKqeRK73zr83aw=== 123456789012wha

以下は暗号化しますが、復号化しません:
util/encrypt/?token=123456789012what= NYaWmwnySoGNHyNmY9Jh+f3O2rqoLI1IAcnsl5V4OCE=
util/decrypt/?token=NYaWmwnySoGNHyNmY9Jh+f3O2rqoLI1IAcnsl5V4OCE== 例外

これが私のコントローラーのコードです:

private static final String ALGO = "AES";


@RequestMapping(value = "/util/encrypt/", method = RequestMethod.GET)
@ResponseBody
public String encrypt(HttpServletResponse httpResponse,
        @RequestParam(value = "token", required=true) String token) throws Exception 
{
    Key key = generateKey();
    Cipher c = Cipher.getInstance(ALGO);
    c.init(Cipher.ENCRYPT_MODE, key);
    byte[] encVal = c.doFinal(token.getBytes());
    String encryptedValue = Base64.encodeBase64String(encVal);
    return encryptedValue.trim();
}



@RequestMapping(value = "/util/decrypt/", method = RequestMethod.GET)
@ResponseBody
public String decrypt(HttpServletResponse httpResponse,
        @RequestParam(value = "token", required=true) String token) throws Exception 
{
    token = URLDecoder.decode(token, "UTF-8");
    Key key = generateKey();
    Cipher c = Cipher.getInstance(ALGO);
    c.init(Cipher.DECRYPT_MODE, key);
    byte[] decordedValue = Base64.decodeBase64(token);
    byte[] decValue = c.doFinal(decordedValue);
    String decryptedValue = new String(decValue);
    return decryptedValue.trim();
}



private Key generateKey() throws Exception 
{
    Key key = new SecretKeySpec(getAesKey().getBytes(), ALGO);
    return key;
}

私はそれが呼び出しに何かあるに違いないと考えており、Cipher.getInstance()使用しようとしましCipher.getInstance("AES/CBC/PKCS5Padding")たが、復号化するときに常に失敗します。ここで何が起こっているのか、それを修正する方法を本当に理解したいと思っています。

4

2 に答える 2

3

関数encodeBase64URLSafeStringを使用します。javadocは言う

base64 アルゴリズムの URL セーフ バージョンを使用してバイナリ データをエンコードしますが、出力をチャンクしません。URL セーフのバリエーションでは、+ および / 文字の代わりに - および _ が生成されます。注: パディングは追加されません。

これで問題は解決するはずです。

于 2013-06-24T22:40:49.430 に答える
2

このクラスは文字ストリームではなくバイト ストリームで直接動作するため、下位 127 ASCII チャート (ISO-8859-1、Windows-1252、UTF-8、等)。

byte[]/string との間の変換では、すべてのデータが保持されるわけではありません。暗号文のテキスト表現は実際には必要ないのに、なぜ文字列に変換するのですか?

于 2013-06-24T22:28:09.370 に答える