我想要在C#中导入/导出PEM / DER字符串的函数。我在python和C#上使用RSA,但我没有解决方案谁在两种语言之间工作得很好。 经过多次尝试和多次研究,我终于找到了一个为读取PEM公钥工作的解决方案。以下代码有效:
// pubkey is the PEM file without header/footer and encoded base64
Asn1Object obj = Asn1Object.FromByteArray(pubkey_bytes);
DerSequence publicKeySequence = (DerSequence)obj;
DerSequence publicKey = (DerSequence)Asn1Object.FromByteArray(publicKeySequence.GetEncoded());
DerInteger modulus = (DerInteger)publicKey[0];
DerInteger exponent = (DerInteger)publicKey[1];
RsaKeyParameters keyParameters = new RsaKeyParameters(false, modulus.PositiveValue, exponent.PositiveValue);
RSAParameters parameters = DotNetUtilities.ToRSAParameters(keyParameters);
这段代码的灵感来源于我在StackOverflow上找到的解决方案。但是,当我试图使用相同的私钥解决方案时,我有一个例外“Spécified尺寸太小”。此错误似乎出现在“InverseQ”行中。在我正在使用的代码下面:
// Private key encode base64 without header/footer
Asn1Object obj = Asn1Object.FromByteArray(privkey_bytes);
DerSequence privateKeySequence = (DerSequence)obj;
DerSequence privateKey = (DerSequence)Asn1Object.FromByteArray(privateKeySequence.GetEncoded());
DerInteger M = (DerInteger)privateKey[1];
DerInteger E = (DerInteger)privateKey[2];
DerInteger D = (DerInteger)privateKey[3];
DerInteger P = (DerInteger)privateKey[4];
DerInteger Q = (DerInteger)privateKey[5];
DerInteger DP = (DerInteger)privateKey[6];
DerInteger DQ = (DerInteger)privateKey[7];
DerInteger IQ = (DerInteger)privateKey[8];
var keyParameters = new RsaPrivateCrtKeyParameters(M.PositiveValue,
E.PositiveValue, D.PositiveValue, P.PositiveValue, Q.PositiveValue,
DP.PositiveValue, DQ.PositiveValue, IQ.PositiveValue);
RSAParameters parameters = DotNetUtilities.ToRSAParameters(keyParameters); // Exception here !
我还尝试了另一个StackOverflow帖子中的代码,用于修复填充问题,但这不是我的问题:
RSAParameters parameters = new RSAParameters();
parameters.Modulus = M.PositiveValue.ToByteArrayUnsigned();
parameters.Exponent = E.PositiveValue.ToByteArrayUnsigned();
parameters.P = P.PositiveValue.ToByteArrayUnsigned();
parameters.Q = Q.PositiveValue.ToByteArrayUnsigned();Modulus.Length);
parameters.DP = ConvertRSAParametersField(DP.PositiveValue, parameters.P.Length);
parameters.DQ = ConvertRSAParametersField(DQ.PositiveValue, parameters.Q.Length);
parameters.InverseQ = ConvertRSAParametersField(IQ.PositiveValue, parameters.Q.Length);
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); // Exception HERE
return rp;
}
private static byte[] ConvertRSAParametersField(BigInteger n, int size)
{
byte[] bs = n.ToByteArrayUnsigned();
if (bs.Length == size)
return bs;
if (bs.Length > size) // HERE
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;
}
我的私钥是由python生成的,我认为它是普通密钥:
-----BEGIN RSA PRIVATE KEY-----
MIICYAIBAAKBgQCUkUk/vvyTI3begsdjz7eQVchjMTYMTyqt8HHHSXYXY2GrQCZS
VfBVxFLmx19brgMdLrKO93CjJWt+ACXAaLHmuGCsvNgGjCFqgg4XxM4Xamt9PeOc
F8HhMH7iS3OcgybQuu9GrekZB0yL2L9GVpyVrXpVlVHi4gBVjUr80e5LUwIDAQAB
AoGAGgK9wk1bxx8EZrya0BzD1J9QMB2jitApdr6MDQoNhNa/eM4IZ43oP/vZT9JE
Hbb/kJJmbKVhsQ6SHUNFO6qJA0FWYNqEA1xsTtat3RXAB/WCExxW9GwDG6pEXjK8
OrJFbKyIOhmqy3sBib9V76ROYsMi7Gioih8vtYKz8NFBiZECRQCmOHzCqEbsWJnK
5JUsUG8DyR3wg8mzi98m1qYGz3hsuBJMCW2M/QBSgyWGdDxExbQMcTb9lmTelq4W
sHbZLQ3FVxJsbwI9AOTP4ZCLDnzblroQjiUCW1vbVE6YnoO0YTb67Dj/g9CNOZpz
E0lJ3boUlg6lOEpDdwKxSswXhQU53OMJXQJFAKC+BaB0/Uk4EVnNHZkiG4lsp2Bd
AeR4wg8cCqiRYCK7Cy6u+1sZm4Mvwk05AMN88TYLEiO/mcJLswTMF9LDqAqLvoxP
AjxDmlPXo+4k37AZyzhkIN0jN5siGZ+D5DBw0RQoBv5ICOHDC0rgdW2IQ/rN2uzV
rDcmWYFy6WQI1j636ZUCRHWmzCi6ymkcUnqwlYXsjbZSVM7njOc3sJyVhaOgqs+o
1Zjbtpqq7DYEBHPFizh/nu6kf4lT3w5+vIKGs8r4k2IUMcJi
-----END RSA PRIVATE KEY-----
我对“Asn1Object.FromByteArray()”返回的参数的顺序有疑问。我注意到[0]只是一个“0”,这对我来说意味着空洞。长度是9所以它似乎是好方法,我只是不确定它们返回的顺序。试图找到一些文件,但我一无所获。
提前感谢人们帮助我
修改
首先,我想说我的目标是获得一个RSAParameters对象。
由于某人删除了他的帖子,我改变了
rp.InverseQ = ConvertRSAParametersField(privKey.QInv, rp.Q.Length);
到
rp.InverseQ = ConvertRSAParametersField(privKey.QInv, rp.P.Length);
但是在完成之后,我收到了一个异常的System.Security.Cryptography.CryptographicException,他告诉我“数据不正确”。在线
var csp = new RSACryptoServiceProvider(); // my csp object is already defined somewhere else but it change nothing
csp.ImportParameters(parameters); // Exception here, he doesn't like my object who doesn't seems valid for him.
真正的问题似乎是“为什么我的对象被RSACryptoServiceProvider.ImportParameters()拒绝