RSA di crittografia in .NET - decrittazione in JAVA -> Java getta “modulo non positiva” l'errore

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

Domanda

Sto avendo problemi con il nostro fornitore di terze parti implimenting uno sso. Essi stanno ricevendo il seguente errore durante la verifica la mia firma:

java.lang.ArithmeticException: BigInteger: modulo non è positivo - a java.math.BigInteger.modPow (BigInteger.java:1556)

Non ho alcun controllo sulla loro codice Java. Ecco quello che sto facendo ora:

Ho creato una coppia di chiavi in ??C # utilizzando questo codice:

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

Ecco il codice per la firma:

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

(Sì, lo so la chiave privata dovrebbe essere in un negozio chiave).

Ecco il codice che usano per i tasti Conversione XML (questo è 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;
}
È stato utile?

Soluzione

L'eccezione ha a che fare con la chiave pubblica RSA che Java sta usando. Nessuno dei tuoi indirizzi di codice che punto. Come ha fatto il lato Java ottenere quella chiave, quale formato viene utilizzato?

Un errore comune che può spiegare l'errore è se il modulo viene convertito in un array di byte ma un importante byte zero non è presente quando è necessario essere. Fondamentalmente, questo BigInteger costruttore è un po 'più complicato per l'uso di quanto possa apparire a prima vista. È stato progettato per essere compatibile con gli interi ASN.1 DER-encoded. Il risultato di tutto ciò è che se il primo b byte del vostro modulo ha il set alto bit, vale a dire 128 <= b < 256, è necessario anteporre un leader byte zero o il vostro modulo verrà interpretato come un numero negativo. Per semplicità si può sempre anteporre un leader byte zero; nessun danno verrà se non era necessario.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top