我在加密要发送到 SOAP 服务的数据时遇到问题。
我想问题出在 SecretKey 生成中,因为密码不正确时响应仍然相同。
当前代码是:
WServiceSoap ws = new WService().getWServiceSoap();
MessageDigest md = MessageDigest.getInstance("md5");
byte[] digestOfPassword = md.digest("12345678".getBytes("utf-8"));
final byte[] keyBytes = Arrays.copyOf(digestOfPassword, 24);
for (int j = 0, k = 16; j < 8;) {
keyBytes[k++] = keyBytes[j++];
}
SecretKey opKey = new SecretKeySpec(keyBytes, "DESede");
byte[] opIV = { 0, 0, 0, 1, 2, 3, 4, 5 };
Cipher c = Cipher.getInstance("DESede/CBC/PKCS5Padding");
c.init(Cipher.ENCRYPT_MODE, opKey, new IvParameterSpec(opIV));
byte[] encrypted = c.doFinal(
ClientDirectOperacionCTMS.DATOS_OPERACION.getBytes("UTF-8"));
String encryptedDatosOperacion= Base64.encodeBase64String(encrypted);
String result= ws.operacionCTMS(encryptedDatosOperacion);
System.out.println(result);
, 例外是
Exception in thread "main" javax.xml.ws.soap.SOAPFaultException: Server was unable to process request. ---> La operación de pago con tarjeta no ha sido satisfactoria. ---> Additional non-parsable characters are at the end of the string.
at com.sun.xml.internal.ws.fault.SOAP11Fault.getProtocolException(SOAP11Fault.java:178)
at com.sun.xml.internal.ws.fault.SOAPFaultBuilder.createException(SOAPFaultBuilder.java:111)
at com.sun.xml.internal.ws.client.sei.SyncMethodHandler.invoke(SyncMethodHandler.java:108)
at com.sun.xml.internal.ws.client.sei.SyncMethodHandler.invoke(SyncMethodHandler.java:78)
at com.sun.xml.internal.ws.client.sei.SEIStub.invoke(SEIStub.java:107)
我也试过这段代码但没有成功:
final byte[] keyBytes = Arrays.copyOf(Base64.decodeBase64("12345678"), 24);
SecretKey opKey = new SecretKeySpec(keyBytes, "DESede");
服务器完成的解密是
CheckKey(ref rgbKey);
cryptoProvider = new TripleDESCryptoServiceProvider();
cryptoTransform = cryptoProvider.CreateDecryptor(rgbKey, s_rgbIV);
memoryStream = new MemoryStream();
using (CryptoStream cryptoStream = new CryptoStream(
memoryStream, cryptoTransform, CryptoStreamMode.Write))
{
cryptoStream.Write(rgbEncryptedText, 0, rgbEncryptedText.Length);
}
originalText = Encoding.UTF8.GetString(memoryStream.ToArray());
, 其中 CheckKey 是
private static void CheckKey(ref Byte[] rgbKey)
{
if (rgbKey.Length > KEY_MAX_LENGTH)
{
Array.Resize(ref rgbKey, KEY_MAX_LENGTH);
}
else if (rgbKey.Length < KEY_MAX_LENGTH)
{
Byte fill = 0x41;
Int32 offset = rgbKey.Length;
Array.Resize(ref rgbKey, KEY_MAX_LENGTH);
for (Int32 index = offset; index < KEY_MAX_LENGTH; index++)
{
rgbKey[index] = fill++;
}
}
}