Шифрование RSA в .NET - дешифрование в Java -> Java бросает «модуль не положительный» ошибка

StackOverflow https://stackoverflow.com/questions/3970684

Вопрос

У меня проблемы с нашим сторонним поставщиком, влюбляющим SSO. Они получают следующую ошибку при проверке моей подписи:

java.lang.arithmeticexception: Biginteger: модуль не положительный - в Java.math.biginteger.modpow (biginteger.java:1556)

У меня нет контроля над их кодом Java. Вот что я сейчас делаю:

Я создал ключевую пару в C #, используя этот код:

        CspParameters csp = new CspParameters();
        csp.KeyNumber = (int)KeyNumber.Signature;
        using (RSACryptoServiceProvider rsa = new RSACryptoServiceProvider(1024, csp))
        {

            File.AppendAllText(path + "PrivateKey.xml", rsa.ToXmlString(true));
            File.AppendAllText(path + "PublicKey.xml", rsa.ToXmlString(false));
        }

Вот код для подписи:

public string MD5withRSASignature(string encryptedStringToSign)
    {

        byte[] signature;
        using (RSACryptoServiceProvider rsa = new RSACryptoServiceProvider(1024))
        {
            XmlDocument xDoc = new XmlDocument();
            xDoc.Load(PRIVATE_KEY_PATH);
            rsa.FromXmlString(xDoc.OuterXml);
            byte[] bytes = Encoding.UTF8.GetBytes(encryptedStringToSign);
            signature = rsa.SignData(bytes, new MD5CryptoServiceProvider());
        }

        return Convert.ToBase64String(signature);
    }

(Да, я знаю, что закрытый ключ должен быть в ключевом магазине).

Вот код, который они используют для преобразования ключей XML (это Java)

private static RSAPublicKey ReadXMLKey(String fileName)
{

        DocumentBuilderFactory factory =     DocumentBuilderFactory.newInstance();
        DocumentBuilder builder = factory.newDocumentBuilder();
        Document document = builder.parse( new File(fileName) );
        byte[] modBytes = GetBytesFromElement(document, "Modulus");
        byte[] expBytes = GetBytesFromElement(document, "Exponent");
        RSAPublicKeySpec rsaKeyspec = new RSAPublicKeySpec(new BigInteger(modBytes), new BigInteger(expBytes));
        RSAPublicKey key = (RSAPublicKey)KeyFactory.getInstance("RSA").generatePublic(rsaKeyspec);

        return key;
         }

private static byte[] GetBytesFromElement(Document doc, String tag) throws IOException
{
    BASE64Decoder decoder = new BASE64Decoder();
    NodeList list = doc.getElementsByTagName(tag);
    byte[] results = null;
    if (list.getLength() == 1)
    {
        Element item = (Element)list.item(0);
        Text text = (Text)item.getFirstChild();
        results = decoder.decodeBuffer(text.getNodeValue().trim());
    }
    return results;
}
Это было полезно?

Решение

Исключение связано с открытым ключом RSA, который использует Java. Ни один из ваших кода не адресует этот момент. Как на стороне Java получила этот ключ, какой формат используется?

Одна общая ошибка, которая может объяснить ошибку, заключается в том, что модуль преобразуется в массив байтов но Ведущий нулевой байт отсутствует, когда он должен быть. В основном, Этот дизайн Biginteger немного сложнее использовать, чем он может впервые появиться. Он предназначен для совместимости с DER-кодированными целыми числами ASN.1. Выделение этого все, что если первый байт b вашего модуля имеет высокий битовый набор, т.е. 128 <= b < 256, вы должны добавить ведущий нулевой байт или ваш модуль будет интерпретировать как отрицательное число. Для простоты вы всегда можете получить ведущую нулевую байт; Ни один вред не придет, если бы не было необходимости.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top