我遇到问题,我们的第三方供应商正在使用sso。验证我的签名时,他们收到以下错误:
java.lang.ArithmeticException:BigInteger:modulus not positive - at 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;
}
答案 0 :(得分:4)
该异常与Java正在使用的RSA公钥有关。你的代码都没有说明这一点。 Java方是如何获得该密钥的,使用的格式是什么?
可以解决错误的一个常见错误是,如果将模数转换为字节数组但,则需要时不存在前导零字节。基本上,this BigInteger constructor使用起来比它最初看起来有点棘手。它旨在与DER编码的ASN.1整数兼容。这一切的结果是,如果模数的第一个字节b
具有高位设置,即128 <= b < 256
,则必须预先设置前导零字节,否则模数将被解释为负数。为简单起见,您始终可以预先设置前导零字节;如果没有必要,就不会有伤害。