微信返金通知復号エラーpad block corruptedまたはpad block corrupted

2699 ワード

一部の友人は次のようなエラーに遭遇した可能性があります.
pad block corrupted
または
last block incomplete in decryption
これは符号化エラーによる可能性が高い
微信支払いはreq_infoがbase 64符号化を行う場合、使用する文字セットはUTF-8ではなくISO-8859-1
UTF-8で復号すると必ずエラーが表示されます.
理由は次のとおりです.
byte[]をStringに変換し、Stringからbyte[]に変換すると、
1番目のbyte[]の値と2番目のbyte[]の値は異なり、
文字セットがISO-8859-1であるか、デフォルト文字セットがISO-8859-1であるかを指定しない限り.
UTF-8はマルチバイト符号化であるため、1文字の符号化を複数バイトで表す必要があるため、変換後にbyte[]配列長、内容が一致しない場合もある.
一方、ISO-8859-1符号化はシングルバイト符号化であるため、この符号化を使用すると上記の問題は発生しない
詳細は下記を参照してください.
https://blog.csdn.net/qq_27760433/article/details/78327328
どうやってこの問題を解決しますか?
方法は2つあります.
(1),
Java 8が持参したjavaを使用すると.util.Base 64クラス、
例:
Base64.Decoder decoder = Base64.getDecoder();
では、復号方法はこう書きます.
public static String decryptData(final String base64Data) throws Exception
{
	final Cipher cipher = Cipher.getInstance(ALGORITHM_MODE_PADDING, "BC");
	cipher.init(Cipher.DECRYPT_MODE, key);
	return new String(cipher.doFinal(CyptoUtil.base64_decode_8859(base64Data).getBytes("ISO-8859-1")), "utf-8");
	// : ISO-8859-1, utf-8
}

上のCyptoUtil.base64_decode_8859の定義は次のとおりです.
public static String base64_decode_8859(final String source)
{
	String result = "";


	final Base64.Decoder decoder = Base64.getDecoder();
	try
	{
		result = new String(decoder.decode(source), "ISO-8859-1");
		// ISO-8859-1
	}
	catch (final UnsupportedEncodingException e)
	{
		e.printStackTrace();
	}


	return result;
}

これに対応して、暗号化の方法は次のように書かれています.
public static String encryptData(final String data) throws Exception
{
	//  
	final Cipher cipher = Cipher.getInstance(ALGORITHM_MODE_PADDING, "BC");
	//  
	cipher.init(Cipher.ENCRYPT_MODE, key);
	return CyptoUtil.base64_encode_8859(new String(cipher.doFinal(data.getBytes()), "ISO-8859-1"));
}

上のCyptoUtil.base64_encode_8859()は次のように定義されます.
public static String base64_encode_8859(final String source)
{
	String result = "";

	final Base64.Encoder encoder = Base64.getEncoder();
	byte[] textByte = null;
	try
	{
		textByte = source.getBytes("ISO-8859-1");
                // ISO-8859-1
	}
	catch (final UnsupportedEncodingException e)
	{
		e.printStackTrace();
	}
	result = encoder.encodeToString(textByte);
	return result;
}

(2),
2つ目の方法は、java 8が持参したjavaを使用しないことです.util.Base 64クラス、他の人が書いたBase 64 Utilツールクラスを探しています.https://blog.csdn.net/m0_37218608/article/details/79505068
2つの方法は個人的に1つをお勧めします.結局JAVAの公式提供なので、信頼できます.
本文は主に符号化エラーを強調したい.残りのコードは参考してください.
https://blog.csdn.net/u010660575/article/details/76672402