从 bouncycastle 导入 RSA 密钥有时会抛出 "Bad Data"
Import RSA key from bouncycastle sometimes throws "Bad Data"
有时(经常足以成为 .NET 和 bouncy castle 之间的严重问题),bouncycastle 生成的密钥不会导入到 dotnet RSA 加密提供程序中。
它只会抛出 "Données Incorrectes" ;没有更多的细节。 ("Bad data")。我无法调试问题,因为有罪的函数实现似乎隐藏在 CLR 中(Utils._ImportKey() ;参考来源 RSACryptoServiceProvider.cs:297)。
我尝试更改 "provider" 但没有成功。
这里也有同样的问题.. 通过更改密钥或密钥大小在某种程度上 解决了 : BouncyCastle RSAPrivateKey to .NET RSAPrivateKey ;它在我的单元测试中失败,密钥大小从 512 位到 2048 位不等。
怎么会出现workaround/debug这样的问题? 错误数据 是什么意思?
这是一个测试用例,其值失败:
[TestCase(
"3130061425891827008704201520933220266588903615593292093008732204896232681270200769431823371565724812996700795538563485957721923348815282268698793938491993",//mod
"65537",//pe
"3130061425891827008704201520933220266588903615593292093008732204896232681270200769431823371565724812996700795538563485957721923348815282268698793938491993",//priv e
"108172619413453999338304010966268975159507181290909920458641813606026415083917",//p
"75249617574313725168879024231390763478340191084309820124417146187514704207891",//q
"46308055148448439895562160789624828220320330169183342667312429963694967752481", //dp
"237677507940292370873826357872619864199100043554818389089435727311526981263", //dq
"4755193289666548078142536433103759575424135202658906348751587662200087509503"//qinv
)]
public void TestBadKeyForMicrosoft(string mo, string pe, string prive, string p, string q, string dp, string dq, string qinv)
{
var k = new RsaPrivateCrtKeyParameters(
new BigInteger(mo),//mod
new BigInteger(pe),//pe
new BigInteger(prive),//priv e
new BigInteger(p),//p
new BigInteger(q),//q
new BigInteger(dp),//dp
new BigInteger(dq),//dq
new BigInteger(qinv)//qinv
);
var dotNetRsa = Org.BouncyCastle.Security.DotNetUtilities.ToRSAParameters(k);
//var rsaCsp = new RSACryptoServiceProvider(new CspParameters(24 /*PROV_RSA_AES */)) { PersistKeyInCsp = false };
var rsaCsp = new RSACryptoServiceProvider() {PersistKeyInCsp = false};
rsaCsp.ImportParameters(dotNetRsa);
}
我想这只是一个填充问题。
Bouncy-castle最新GIT版本有以下代码:
nb: "Nuget" 版本 (2011)
中未修复
public static RSAParameters ToRSAParameters(RsaPrivateCrtKeyParameters privKey)
{
RSAParameters rp = new RSAParameters();
rp.Modulus = privKey.Modulus.ToByteArrayUnsigned();
rp.Exponent = privKey.PublicExponent.ToByteArrayUnsigned();
rp.P = privKey.P.ToByteArrayUnsigned();
rp.Q = privKey.Q.ToByteArrayUnsigned();
rp.D = ConvertRSAParametersField(privKey.Exponent, rp.Modulus.Length);
rp.DP = ConvertRSAParametersField(privKey.DP, rp.P.Length);
rp.DQ = ConvertRSAParametersField(privKey.DQ, rp.Q.Length);
rp.InverseQ = ConvertRSAParametersField(privKey.QInv, rp.Q.Length);
return rp;
}
private static byte[] ConvertRSAParametersField(BigInteger n, int size)
{
byte[] bs = n.ToByteArrayUnsigned();
if (bs.Length == size)
return bs;
if (bs.Length > size)
throw new ArgumentException("Specified size too small", "size");
byte[] padded = new byte[size];
Array.Copy(bs, 0, padded, size - bs.Length, bs.Length);
return padded;
}
此代码与您在其他任何地方看到的代码不同,后者基本上 copy/paste 关键参数,并且不执行额外的填充步骤。
有时(经常足以成为 .NET 和 bouncy castle 之间的严重问题),bouncycastle 生成的密钥不会导入到 dotnet RSA 加密提供程序中。
它只会抛出 "Données Incorrectes" ;没有更多的细节。 ("Bad data")。我无法调试问题,因为有罪的函数实现似乎隐藏在 CLR 中(Utils._ImportKey() ;参考来源 RSACryptoServiceProvider.cs:297)。
我尝试更改 "provider" 但没有成功。
这里也有同样的问题.. 通过更改密钥或密钥大小在某种程度上 解决了 : BouncyCastle RSAPrivateKey to .NET RSAPrivateKey ;它在我的单元测试中失败,密钥大小从 512 位到 2048 位不等。
怎么会出现workaround/debug这样的问题? 错误数据 是什么意思?
这是一个测试用例,其值失败:
[TestCase(
"3130061425891827008704201520933220266588903615593292093008732204896232681270200769431823371565724812996700795538563485957721923348815282268698793938491993",//mod
"65537",//pe
"3130061425891827008704201520933220266588903615593292093008732204896232681270200769431823371565724812996700795538563485957721923348815282268698793938491993",//priv e
"108172619413453999338304010966268975159507181290909920458641813606026415083917",//p
"75249617574313725168879024231390763478340191084309820124417146187514704207891",//q
"46308055148448439895562160789624828220320330169183342667312429963694967752481", //dp
"237677507940292370873826357872619864199100043554818389089435727311526981263", //dq
"4755193289666548078142536433103759575424135202658906348751587662200087509503"//qinv
)]
public void TestBadKeyForMicrosoft(string mo, string pe, string prive, string p, string q, string dp, string dq, string qinv)
{
var k = new RsaPrivateCrtKeyParameters(
new BigInteger(mo),//mod
new BigInteger(pe),//pe
new BigInteger(prive),//priv e
new BigInteger(p),//p
new BigInteger(q),//q
new BigInteger(dp),//dp
new BigInteger(dq),//dq
new BigInteger(qinv)//qinv
);
var dotNetRsa = Org.BouncyCastle.Security.DotNetUtilities.ToRSAParameters(k);
//var rsaCsp = new RSACryptoServiceProvider(new CspParameters(24 /*PROV_RSA_AES */)) { PersistKeyInCsp = false };
var rsaCsp = new RSACryptoServiceProvider() {PersistKeyInCsp = false};
rsaCsp.ImportParameters(dotNetRsa);
}
我想这只是一个填充问题。
Bouncy-castle最新GIT版本有以下代码:
nb: "Nuget" 版本 (2011)
中未修复public static RSAParameters ToRSAParameters(RsaPrivateCrtKeyParameters privKey)
{
RSAParameters rp = new RSAParameters();
rp.Modulus = privKey.Modulus.ToByteArrayUnsigned();
rp.Exponent = privKey.PublicExponent.ToByteArrayUnsigned();
rp.P = privKey.P.ToByteArrayUnsigned();
rp.Q = privKey.Q.ToByteArrayUnsigned();
rp.D = ConvertRSAParametersField(privKey.Exponent, rp.Modulus.Length);
rp.DP = ConvertRSAParametersField(privKey.DP, rp.P.Length);
rp.DQ = ConvertRSAParametersField(privKey.DQ, rp.Q.Length);
rp.InverseQ = ConvertRSAParametersField(privKey.QInv, rp.Q.Length);
return rp;
}
private static byte[] ConvertRSAParametersField(BigInteger n, int size)
{
byte[] bs = n.ToByteArrayUnsigned();
if (bs.Length == size)
return bs;
if (bs.Length > size)
throw new ArgumentException("Specified size too small", "size");
byte[] padded = new byte[size];
Array.Copy(bs, 0, padded, size - bs.Length, bs.Length);
return padded;
}
此代码与您在其他任何地方看到的代码不同,后者基本上 copy/paste 关键参数,并且不执行额外的填充步骤。