使用.NET RSAKeyValue XML字符串时,Java RSA加密无法正常工作

时间:2012-11-29 10:23:14

标签: java .net encryption rsa

我有来自.NET Web服务的以下RSA XML字符串

<RSAKeyValue>
    <Modulus>+Tir6+unMOaQ5tHqjjjwnlAMhccnCSMFEi3a0mhIxbW+O/GukjomGyzckQT2h0Ys70JezHbNq5YS3sYkNF29kCkz4HuNfy9eEjE/clA9/zyfT8ZcbnusLcLz2xNgbTp62fQdzBnReI5+dpj/N24krYvHaYIr8ACxDqBv2TR3E9M=</Modulus>
    <Exponent>AQAB</Exponent>
</RSAKeyValue>

当我使用它在java中进行RSA加密时,我从他们的Web服务中得到以下错误

javax.xml.ws.soap.SOAPFaultException: Server was unable to process request. ---> Response Code: 100 Message: Invalid authentication credentials ---> Exception of type 'Capita.HSE.GS.Entities.Exceptions.NotificationException' was thrown.
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)
at $Proxy32.checkEngineerDetailSecure(Unknown Source)
at TestWebService.main(TestWebService.java:98)

奇怪的是,如果他们给我一个我要加密的字符串的加密版本并将其传递回给它们就可以了。我加密的代码是

    private static String rsaEncryptPassword(String modulus, String exponent, String password) throws NoSuchAlgorithmException, NoSuchProviderException, InvalidKeySpecException,
        NoSuchPaddingException, InvalidKeyException, IllegalBlockSizeException, BadPaddingException {

    byte[] modulusBytes = Base64.decodeBase64(modulus.getBytes());
    byte[] exponentBytes = Base64.decodeBase64(exponent.getBytes());

    BigInteger modulusInt = new BigInteger(1, modulusBytes);
    BigInteger exponentInt = new BigInteger(1, exponentBytes);

    RSAPublicKeySpec rsaPubKey = new RSAPublicKeySpec(modulusInt, exponentInt);
    KeyFactory fact = KeyFactory.getInstance("RSA");
    PublicKey pubKey = fact.generatePublic(rsaPubKey);

    Cipher cipher = Cipher.getInstance("RSA/ECB/PKCS1PADDING");
    cipher.init(Cipher.ENCRYPT_MODE, pubKey);

    byte[] cipherData = cipher.doFinal(password.getBytes());

    byte[] encryptedBytes = Base64.encodeBase64(cipherData);

    String encryptedString = new String(encryptedBytes);
    System.out.println(encryptedString);

    return encryptedString;
}

在阅读所有表格和帮助网站后,我不知道为什么这不起作用。任何帮助将不胜感激。

1 个答案:

答案 0 :(得分:1)

我们终于解决了这个问题。事实证明.Net服务使用的是Unicode UTF-16编码。所以当我们得到字符串的字节时,我们必须使它成为UTF-16。但是UTF-16字节数组有多种格式。有UTF-16LE,UTF-16BE和UTF-16。

在我们将字符串转换为字节数组的情况下,我们必须使用UTF-16LE。所以最后,解决方案是

byte[] cipherData = cipher.doFinal(password.getBytes("UTF-16LE"));

使用加密时,请确保您知道解密系统使用的字符编码,并确保从您要加密的字符串生成字节数组时使用的是字符编码。