C# 导入私钥时出现RSA密钥对异常

C# 导入私钥时出现RSA密钥对异常,c#,cryptography,rsa,private-key,C#,Cryptography,Rsa,Private Key,我不熟悉RSA和密码学,我需要使用RSA加密和解密数据,我有一个java程序,它可以生成密钥对并将它们保存在XML格式的.key文件中(这是绝对正确的,并且通过加密和解密数据进行了测试),然后我想在.NET应用程序中使用它们,我正在导入用于加密和解密的密钥。公钥正常,加密完成没有问题,但私钥导入失败,出现以下异常消息 Bad data (CryptographicException.ThrowCryptogaphicException(Int32 hr)) 这是经过编码的公钥: <RSA

我不熟悉RSA和密码学,我需要使用RSA加密和解密数据,我有一个java程序,它可以生成密钥对并将它们保存在XML格式的
.key
文件中(这是绝对正确的,并且通过加密和解密数据进行了测试),然后我想在.NET应用程序中使用它们,我正在导入用于加密和解密的密钥。公钥正常,加密完成没有问题,但私钥导入失败,出现以下异常消息

Bad data (CryptographicException.ThrowCryptogaphicException(Int32 hr))
这是经过编码的公钥:

<RSAKeyValue>
<Modulus>iFouk9viRs5dcvJCvDM1vXC4sBuSB9SPcdJhRyFLoNW/pka6MNAiu4cOksFRejiuM1ZswyJMy+ow
lmLflJ/XrfnUQxLwLp61oij4CrzHKl9jjHorqIA7uEQKY8RBiUjZ7kbO5nFaIWs1NWMVks8Srdhv
8pVd1sLKKUs66c/ndAk=</Modulus>
<Exponent>AQAB</Exponent>
</RSAKeyValue>
<RSAKeyValue>
<Modulus>iFouk9viRs5dcvJCvDM1vXC4sBuSB9SPcdJhRyFLoNW/pka6MNAiu4cOksFRejiuM1ZswyJMy+ow
lmLflJ/XrfnUQxLwLp61oij4CrzHKl9jjHorqIA7uEQKY8RBiUjZ7kbO5nFaIWs1NWMVks8Srdhv
8pVd1sLKKUs66c/ndAk=</Modulus>
<Exponent>AQAB</Exponent>
<P>AO9WnDNOt9Xewnoy8KTed56Z+3Nfto6J8wCXKzX3LhuuiKNUBe8qFoinrteQJq/9NAEXnNCafxDW
ThIkr9GtMxE=</P>
<Q>AJHYMk0bOEGZlQbaJk3VDovvOJuRt5NI3WtXWl1v5VUW6aQQO3rV3+3GSN6Xa3hTKXtCVVL26Awy
OkDykUPjQXk=</Q>
<DP>KIHsJfLowlXVbIE6oWzVqg49tKU6bJ2Ed1Eeix+uuhisH5iU+ImTDsXynaFUKu0b5CNu8w9y+hKL
XB7BcydxQQ==</DP>
<DQ>di267NIersF1idzhZvY62FdbBmx4VaeYi+93sPkH2wA7CI+CsxF1Z6XhzETkd9bjaRaiLx0VgTR+
Eby8y0bt+Q==</DQ>
<InverseQ>HYF8gahVyzsz0IotzKI2Oh53sJMZWVxsvzkhqGlDtY1THFGZE5j8kl/UK0+FSN6yOYxBIuKNZ7om
 MgLQEMK1PQ==</InverseQ>
<D>DERQvGyjxsr6DUVOS7AvvYNOmklgseOlpA/RQJz2ONoCC+uBBLM07LoRzZImymAfC+9SiZukXRQM
mvr6MlzPAm04NWyZNzbjhLvmn1gmvDclDZ9X9bhYp8MBftPWU5PFBALOjVpD+mlbI2lTYCugf6pJ
MHEMe17mNJ0eWCerfAE=</D>
</RSAKeyValue>

iFouk9viRs5dcvJCvDM1vXC4sBuSB9SPcdJhRyFLoNW/pka6MNAiu4cOksFRejiuM1ZswyJMy+ow
lmLflJ/XRFNUQXLWLP61OIJ4CRZHKL9JJJHORQIA7UEQKY8RBIUJZ7KBO5NFAIWS1NWMVKS8SRDHV
8PVD1SLKUS66C/ndAk=
AQAB
这是经过编码的公钥:

<RSAKeyValue>
<Modulus>iFouk9viRs5dcvJCvDM1vXC4sBuSB9SPcdJhRyFLoNW/pka6MNAiu4cOksFRejiuM1ZswyJMy+ow
lmLflJ/XrfnUQxLwLp61oij4CrzHKl9jjHorqIA7uEQKY8RBiUjZ7kbO5nFaIWs1NWMVks8Srdhv
8pVd1sLKKUs66c/ndAk=</Modulus>
<Exponent>AQAB</Exponent>
</RSAKeyValue>
<RSAKeyValue>
<Modulus>iFouk9viRs5dcvJCvDM1vXC4sBuSB9SPcdJhRyFLoNW/pka6MNAiu4cOksFRejiuM1ZswyJMy+ow
lmLflJ/XrfnUQxLwLp61oij4CrzHKl9jjHorqIA7uEQKY8RBiUjZ7kbO5nFaIWs1NWMVks8Srdhv
8pVd1sLKKUs66c/ndAk=</Modulus>
<Exponent>AQAB</Exponent>
<P>AO9WnDNOt9Xewnoy8KTed56Z+3Nfto6J8wCXKzX3LhuuiKNUBe8qFoinrteQJq/9NAEXnNCafxDW
ThIkr9GtMxE=</P>
<Q>AJHYMk0bOEGZlQbaJk3VDovvOJuRt5NI3WtXWl1v5VUW6aQQO3rV3+3GSN6Xa3hTKXtCVVL26Awy
OkDykUPjQXk=</Q>
<DP>KIHsJfLowlXVbIE6oWzVqg49tKU6bJ2Ed1Eeix+uuhisH5iU+ImTDsXynaFUKu0b5CNu8w9y+hKL
XB7BcydxQQ==</DP>
<DQ>di267NIersF1idzhZvY62FdbBmx4VaeYi+93sPkH2wA7CI+CsxF1Z6XhzETkd9bjaRaiLx0VgTR+
Eby8y0bt+Q==</DQ>
<InverseQ>HYF8gahVyzsz0IotzKI2Oh53sJMZWVxsvzkhqGlDtY1THFGZE5j8kl/UK0+FSN6yOYxBIuKNZ7om
 MgLQEMK1PQ==</InverseQ>
<D>DERQvGyjxsr6DUVOS7AvvYNOmklgseOlpA/RQJz2ONoCC+uBBLM07LoRzZImymAfC+9SiZukXRQM
mvr6MlzPAm04NWyZNzbjhLvmn1gmvDclDZ9X9bhYp8MBftPWU5PFBALOjVpD+mlbI2lTYCugf6pJ
MHEMe17mNJ0eWCerfAE=</D>
</RSAKeyValue>

iFouk9viRs5dcvJCvDM1vXC4sBuSB9SPcdJhRyFLoNW/pka6MNAiu4cOksFRejiuM1ZswyJMy+ow
lmLflJ/XRFNUQXLWLP61OIJ4CRZHKL9JJJHORQIA7UEQKY8RBIUJZ7KBO5NFAIWS1NWMVKS8SRDHV
8PVD1SLKUS66C/ndAk=
AQAB

AO9WnDNOt9Xewnoy8KTed56Z+3Nfto6J8wCXKzX3LhuuiKNUBe8qFoinrteQJq/9NAEXNNCAFWDW ThIkr9GtMxE=

AJHYMK0BOEGZLQBAJK3VDOVOJURT5NI3WTXWL1V5VUW6AQO3RV3+3GSN6Xa3hTKXtCVVL26Awy OkDykUPjQXk= KIHSJFLOWLXVBIE6OWZVQG49TKU6BJ2ED1EIx+uuhisH5iU+IMTDSxYNAFUK0B5CNU8W9Y+hKL XB7BcydxQQ== di267NIersF1idzhZvY62FdbBmx4VaeYi+93sPkH2wA7CI+CsxF1Z6XhzETkd9bjaRaiLx0VgTR+ Eby8y0bt+Q== HYF8GAHVYZZZZZZZI2OH53SJMZWVXSVZSVKHQGLDTY1THFGZE5J8KL/UK0+FSN6yOYxBIuKNZ7om MgLQEMK1PQ== DERQvGyjxsr6DUVOS7AvvYNOmklgseOlpA/rqjz2onoc+uBBLM07LoRzZImymAfC+9SiZukXRQM mvr6MlzPAm04NWyZNzbjhLvmn1gmvDclDZ9X9bhYp8MBftPWU5PFBALOjVpD+mlbI2lTYCugf6pJ MHEMe17mNJ0eWCerfAE=
请帮助我了解发生了什么以及私钥有什么问题

这是解决问题后工作正常的代码:

 private String getPublicKeyXml(RSAPublicKey pk) throws UnsupportedEncodingException {

    StringBuilder builder = new StringBuilder();
    builder.append("<RSAKeyValue>\n");

    byte[] m = pk.getModulus().toByteArray();
    byte[] mm = stripLeadingZeros(m);

    write(builder, "Modulus", mm);
    write(builder, "Exponent", pk.getPublicExponent());

    builder.append("</RSAKeyValue>");

    return builder.toString();
}

private String getPrivateKeyXml(PrivateKey pk) throws UnsupportedEncodingException {
    RSAPrivateCrtKey privKey = (RSAPrivateCrtKey) pk;
    BigInteger n = privKey.getModulus();
    BigInteger e = privKey.getPublicExponent();
    BigInteger d = privKey.getPrivateExponent();
    BigInteger p = privKey.getPrimeP();
    BigInteger q = privKey.getPrimeQ();
    BigInteger dp = privKey.getPrimeExponentP();
    BigInteger dq = privKey.getPrimeExponentQ();
    BigInteger inverseQ = privKey.getCrtCoefficient();

    StringBuilder builder = new StringBuilder();
    builder.append("<RSAKeyValue>\n");
    write(builder, "Modulus", stripLeadingZeros(n.toByteArray()));
    write(builder, "Exponent", stripLeadingZeros(e.toByteArray()));
    write(builder, "P", stripLeadingZeros(p.toByteArray()));
    write(builder, "Q", stripLeadingZeros(q.toByteArray()));
    write(builder, "DP", stripLeadingZeros(dp.toByteArray()));
    write(builder, "DQ", stripLeadingZeros(dq.toByteArray()));
    write(builder, "InverseQ", stripLeadingZeros(inverseQ.toByteArray()));
    write(builder, "D", stripLeadingZeros(d.toByteArray()));
    builder.append("</RSAKeyValue>");

    return builder.toString();
}

private void write(StringBuilder builder, String tag, byte[] bigInt) throws UnsupportedEncodingException {
    builder.append("\t<");
    builder.append(tag);
    builder.append(">");
    builder.append(encode(bigInt).trim());
    builder.append("</");
    builder.append(tag);
    builder.append(">\n");
}

private void write(StringBuilder builder, String tag, BigInteger bigInt) throws UnsupportedEncodingException {
    builder.append("\t<");
    builder.append(tag);
    builder.append(">");
    builder.append(encode(bigInt));
    builder.append("</");
    builder.append(tag);
    builder.append(">\n");
}

private static String encode(BigInteger bigInt) throws UnsupportedEncodingException {
    return new String(new sun.misc.BASE64Encoder().encode(bigInt.toByteArray()));
}

private static String encode(byte[] bigInt) throws UnsupportedEncodingException {
    return new String(new sun.misc.BASE64Encoder().encode(bigInt));
}

private byte[] stripLeadingZeros(byte[] a) {
    int lastZero = -1;
    for (int i = 0; i < a.length; i++) {
        if (a[i] == 0) {
            lastZero = i;
        } else {
            break;
        }
    }
    lastZero++;
    byte[] result = new byte[a.length - lastZero];
    System.arraycopy(a, lastZero, result, 0, result.length);
    return result;
}
私有字符串getPublicKeyXml(rsPublicKey pk)引发不支持的编码异常{
StringBuilder=新的StringBuilder();
生成器。追加(“\n”);
字节[]m=pk.getmodule().toByteArray();
字节[]mm=带引线零(m);
书写(建筑商,“模数”,mm);
编写(builder,“Exponent”,pk.getPublicExponent());
生成器。追加(“”);
返回builder.toString();
}
私有字符串getPrivateKeyXml(PrivateKey pk)引发不支持的DencodingException{
RSAPrivateCrtKey privKey=(RSAPrivateCrtKey)主键;
biginger n=privKey.getmodule();
BigInteger e=privKey.getPublicExponent();
BigInteger d=privKey.getPrivateExponent();
BigInteger p=privKey.getPrimeP();
biginger q=privKey.getPrimeQ();
BigInteger dp=privKey.getPrimeExponentP();
BigInteger dq=privKey.getPrimeExponentQ();
biginger inverseQ=privKey.getCrtCoefficient();
StringBuilder=新的StringBuilder();
生成器。追加(“\n”);
写入(生成器,“模数”,带引线零(n.toByteArray());
写入(生成器,“指数”,带引线的零(例如toByteArray());
写(builder,“P”,strippleadingzero(P.toByteArray());
写入(builder,“Q”,strippleadingzero(Q.toByteArray());
写入(builder,“DP”,strippleadingzero(DP.toByteArray());
写入(生成器,“DQ”,带引线零(DQ.toByteArray());
写入(生成器,“InverseQ”,带引线零(InverseQ.toByteArray());
写(builder,“D”,strippleadingzero(D.toByteArray());
生成器。追加(“”);
返回builder.toString();
}
私有void write(StringBuilder生成器,字符串标记,字节[]bigInt)引发不支持的DencodingException{
生成器。追加(“\t”);
append(encode(bigInt.trim());
生成器。追加(“\n”);
}
私有void write(StringBuilder生成器、字符串标记、BigInteger-bigInt)引发不受支持的DencodingException{
生成器。追加(“\t”);
append(encode(bigInt));
生成器。追加(“\n”);
}
私有静态字符串编码(BigInteger bigInt)引发不支持的编码异常{
返回新字符串(new sun.misc.BASE64Encoder().encode(bigInt.toByteArray());
}
私有静态字符串编码(字节[]bigInt)引发不支持的DencodingException{
返回新字符串(new sun.misc.BASE64Encoder().encode(bigInt));
}
专用字节[]条带零(字节[]a){
int lastZero=-1;
for(int i=0;i
公钥正常,加密完成没有问题,但私钥导入失败,出现以下异常消息

Bad data (CryptographicException.ThrowCryptogaphicException(Int32 hr))
错误数据(加密异常。ThrowCryptogaphicException(Int32 hr))

请看“常见错误”部分。那些仍在我脑海中萦绕的:

  • 错误的钥匙号码或钥匙用法
  • 错误的加密服务提供者
  • 正确的加密服务提供程序,错误的提供程序类型
  • 加密服务提供程序不支持密钥大小
  • 在字节数组中保留0,使数组中的八位字节过多

我自己解决了这个问题,私钥(如P、Q、模数或其他密钥)中显示的数据在其字节数组的前导(开始)处不应包含零,因此当我消除了它们可能的零后,问题就消失了。请将其作为答案发布。Java确实返回
biginger
值,如果在
biginger
的实例上调用
toByteArray()
,它将返回有符号表示。这可能包括第一个
00
h字节。由于模数始终具有密钥长度的大小,并且具有最高的位集,
00
h始终是前置的。请注意,其他值(包括私有指数)可能小于密钥大小,并且并非所有实现都接受较小的数组(在这方面不知道C)。如果下次发布,请确保包含