Мне нужно отправить зашифрованную строку из личного ключа на веб-сервер для аутентификации. У меня есть клиентский код Java, который правильно генерирует зашифрованную строку (чтобы веб-сервер мог расшифровать ее с помощью открытого ключа). Я пытаюсь написать код C # для выполнения точно такого же шифрования, но не удалось.
Сначала в java было создано хранилище ключей с использованием keytool, похожего на это:
keytool -genkey -dname "cn=Application Test, ou=XXX, o=YYY, c=US" -alias AppTest -keypass AppTest -keystore AppTest.jks -storepass AppTest -validity 1800 -keyalg RSA
Тогда этот код Java правильно считывает хранилище ключей и шифрует данные (privateKey.getAlgorithm () возвращает «RSA»):
KeyStore ks = KeyStore.getInstance("JKS");
InputStream is = new FileInputStream("AppTest.jks");
ks.load(is, "AppTest".toCharArray());
is.close();
PrivateKey privateKey = (PrivateKey) ks.getKey(user, password.toCharArray());
// Encrypt with the private key
String stamp = "123456";
byte[] bytesStampUtf8Unencrypted = stamp.getBytes(Charset.forName("UTF-8"));
Cipher cipher = Cipher.getInstance(privateKey.getAlgorithm());
cipher.init(Cipher.ENCRYPT_MODE, privateKey);
byte[] bytesTimestampUtf8Encrypted = cipher.doFinal(bytesStampUtf8Unencrypted);
String encrypted = new String((new Base64()).encode(bytesStampUtf8Unencrypted));
Все это прекрасно работает при передаче в веб-сервис. Затем я использовал keytool для преобразования из хранилища ключей java в сертификат PKCS12 для использования в моем приложении .NET:
keytool -importkeystore -srckeystore AppTest.keystore -destkeystore KEYSTORE.p12 -srcstoretype JKS -deststoretype PKCS12 -srcstorepass AppTest -deststorepass AppTest-srcalias AppTest -destalias AppTest -srckeypass AppTest -destkeypass AppTest -noprompt
Используя keytool, я сравнил отпечатки пальцев из хранилища ключей и файлов P12 - идентичные. Я думал, что следующий код C # должен работать:
X509Certificate2 myCertificate =
new X509Certificate2(@"C:\Temp\KEYSTORE.p12", "AppTest");
RSACryptoServiceProvider privateKey =
myCertificate.PrivateKey as RSACryptoServiceProvider;
String stamp = "123456";
byte[] buffer = Encoding.UTF8.GetBytes(stamp);
byte[] encryptedBytes = privateKey.Encrypt(buffer, false);
String encrypted = Convert.ToBase64String(encryptedBytes);
Он правильно читает преобразованный файл хранилища ключей, выполняет без проблем и генерирует то, что выглядит как зашифрованные данные, но веб-службе НЕ нравится зашифрованная строка (не может расшифровываться с помощью открытого ключа). Когда я заменил зашифрованную строку C # на зашифрованную строку Java (в отладчике) и отправил эту строку через программу C # в веб-службу - все это тоже работало - поэтому я уверен, что проблема заключается в процессе шифрования, а не в веб-сервисе связи.
У меня нет контроля над тем, как был сгенерирован исходный ключ (как хранилище ключей Java), и каким способом шифрования ожидается веб-служба. Я могу управлять только клиентом .NET, который взаимодействует с веб-службой на основе Java.
Мне не хватает какого-либо флага, параметра, переменной, что?