1

.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;
}

すべてのフォームとヘルプ サイトを読んだ後、なぜこれが機能しないのか、私は途方に暮れています。どんな助けでも大歓迎です。

4

1 に答える 1

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"));

暗号化を使用するときは、復号化システムが使用している文字エンコーディングを確認し、暗号化する文字列からバイト配列を生成するときに使用している文字エンコーディングであることを確認してください。

于 2012-11-29T16:15:22.243 に答える