Я зашифровать сообщение в .NET с RSACryptoServiceProvider с закрытым ключом. (PKCS # 1 v1.5).NET шифровать RSACryptoServiceProvider с 4096 закрытым ключом, как расшифровать его на Android
Когда я пытаюсь расшифровать в .NET с помощью следующего кода, который использует открытый ключ все работает отлично:
private static string Decrypt(string key, string content)
{
byte[] rgb = Convert.FromBase64String(content);
var cryptoServiceProvider = new RSACryptoServiceProvider(new CspParameters()
{
ProviderType = 1
});
cryptoServiceProvider.ImportCspBlob(Convert.FromBase64String(key));
return Convert.ToBase64String(cryptoServiceProvider.Decrypt(rgb, false));
}
Когда с другой стороны, я стараюсь найти алгоритм для того же метода дешифрования в Android, я не могу его расшифровать с помощью открытого ключа. Я экспортировал модуль и exponent от открытый ключ в. NET, чтобы загрузить его на Android.
Метод в Android здесь:
public String Decrypt(String input) {
try {
KeyFactory keyFactory = KeyFactory.getInstance("RSA");
String modulusString = "mmGn1IXB+/NEm1ecLiUzgz7g2L6L5EE5DUcptppTNwZSqxeYKn0AuAccupL0iyX3LMPw6Dl9pjPXDjk93TQwYwyGgZaXOSRDQd/W2Y93g8erpGBRm/Olt7QN2GYhxP8Vn+cWUbNuikdD4yMfYX9NeD9UNt5WJGFf+jRkLk0zRK0A7ZIS+q0NvGJ/CgaRuoe3x4Mh1qYP9ZWNRw8rsDbZ6N2zyUa3Hk/WJkptRa6jrzc937r3QYF3eDTurVJZHwC7c3TJ474/8up3YNREnpK1p7hqwQ78fn35Tw4ZyTNxCevVJfYtc7pKHHiwfk36OxtOIesfKlMnHMs4vMWJm79ctixqAe3i9aFbbRj710dKAfZZ0FnwSnTpsoKO5g7N8mKY8nVpZej7tcLdTL44JqWEqnQkocRqgO/p3R8V/6To/OjQGf0r6ut9y/LnlM5qalnKJ1gFg1D7gCzZJ150TX4AO5kGSAFRyjkwGxnR0WLKf+BDZ8T/syOrFOrzg6b05OxiECwCvLWk0AaQiJkdu2uHbsFUj3J2BcwDYm/kZiD0Ri886xHqZMNExZshlIqiecqCskQhaMVC1+aCm+IFf16Qg/+eMYCd+3jm/deezT4rcMBOV/M+muownGYQ9WOdjEK53h9oVheahD3LqCW8MizABFimvXR3wAgkIUvhocVhSN0=";
String exponentString = "AQAB";
byte[] modulusBytes = Base64.decode(modulusString.getBytes("UTF-8"), Base64.DEFAULT);
byte[] dBytes = Base64.decode(exponentString.getBytes("UTF-8"), Base64.DEFAULT);
BigInteger modulus = new BigInteger(1, modulusBytes);
BigInteger d = new BigInteger(1, dBytes);
RSAPublicKeySpec keySpec = new RSAPublicKeySpec(modulus, d);
PublicKey key = keyFactory.generatePublic(keySpec);
//at one point I read somewhere that .net reverses the byte array so that it needs to be reversed for java, but who knows any more
/*byte[] inputArrayReversed = Base64.decode(input.getBytes("UTF-8"), Base64.DEFAULT);
for (int i = 0; i < inputArrayReversed.length/2; i++) {
byte temp = inputArrayReversed[i];
inputArrayReversed[i] = inputArrayReversed[inputArrayReversed.length - 1];
inputArrayReversed[inputArrayReversed.length - 1] = temp;
}*/
byte[] decryptedText = null;
Cipher cipher = Cipher.getInstance("RSA/ECB/PKCS1Padding");
cipher.init(Cipher.DECRYPT_MODE, key);
decryptedText = cipher.doFinal(Base64.decode(input.getBytes("UTF-8"), Base64.DEFAULT));
return Base64.encodeToString(decryptedText, Base64.NO_WRAP);
//return new String(decryptedText, "UTF-8");
} catch (Exception e) {
e.printStackTrace();
}
return "";
}
На самом деле я пытался также с различными алгоритмами, указанных в Cypher классе, также пробовал много других комбинаций, пытались использовать SpongyCastle вместо встроенного в поставщиков Android RSA, но ничего не получалось , Если кто-нибудь подскажет мне в правильном направлении, я буду абсолютно благодарен.
Первая подсказка - это то, что расшифрованная строка из .NET насчитывает около 25 символов, и когда я получаю Android для возврата расшифрованной строки без исключений, она обычно намного длиннее, примерно 500 байт.
Второй намек удален
Третий намек Я также попытался spongycastle, но это не помогло, что многое
В любом случае, спасибо заранее за любую помощь !!!
UPDATE 1
Второй намек удаляется, потому что был не прав, игнорировать его. Теперь у меня есть один вопрос, если следующее может доказать, что открытый ключ загружен правильно, просто чтобы исключить эту проблему.
Модуль BigInteger и показатель в верхнем коде Android и следующие BigIntegers в .NET показывают равные целочисленные значения.
var parameters = csp.ExportParameters(false);
var modulusInteger = new BigInteger(parameters.Modulus.Reverse().Concat(new byte[] { 0 }).ToArray());
var exponentInteger = new BigInteger(parameters.Exponent.Reverse().Concat(new byte[] { 0 }).ToArray());
UPDATE 2
This и This SO ответы предоставить некоторые интересные подсказки
Не могли бы вы попробовать и обратный модуль вместо шифротекста ? Выход RSA определяется как строка октета, а модуль - число. Строки октетов не имеют маленьких/больших проблем, но номера действительно. То же самое относится и к публичному экспоненту, но поскольку это значение '010001', это двоичный палиндром. Тем не менее, если это * не * '010001', а небольшое случайное число, ваш алгоритм все равно может потерпеть неудачу. Если это решает проблему, было бы неплохо прокомментировать, поэтому я могу преобразовать этот комментарий в ответ. –
не будет ли это предположение противоречить моему второму намеку, но, конечно, к концу дня я попробую это и дам вам знать. – Brcinho
Это отладка с расстояния. В моем - теперь значительном опыте - он всегда будет доходить до кодера, ударяя головой ладонью, а мы просто обеспечим достаточную энтропию для того, чтобы кодер продолжал отлаживать :) –