我们有一个C#/ .Net 4.0应用程序,它将RSA私钥从PEM文件导入RSACryptoServiceProvider。
此应用程序适用于从512到4096位的RSA-Keys,但没有使用特殊类型的rsa私钥。
您可以在此处找到两个示例键:test keys
OpenSSL-Command:openssl genrsa -out PRIVATE.KEY 2048
主要区别在于选择两个素数(p和q)。而不是两者都是用1024位生成的,它们在非工作密钥中是1023和1025位。 根据RSA规范,这应该没问题。
但是在ImportParameters()上,我们总是得到一个带有“错误数据”的加密 - 例外。任何想法如何获取更多信息,为什么私钥数据被拒绝或如何获得更多信息? 我们搜索了信息,如果微软对rsa密钥有要求,但找不到 任何有用的规格。
两个密钥都可以被OpenSSL以及使用这些私钥进行测试的各种智能卡使用。
以下是字节长度:
工作密钥:
不-工作密钥:
还试图用BouncyCastle解析PEM文件并从中导出RsaParameters, 但他们也被“糟糕的数据”拒绝了。 (而使用BouncyCastle不是一个选项btw。:()
提前致谢!
答案 0 :(得分:1)
以防万一其他人遇到同样的问题。 MSDN-Mod给了我一个与微软认为RSA-Keys应该是什么样的信息的链接。
2.2.2.9.1 RSA Private Key BLOB
对于2048位RSA密钥,P和Q预计每个都是128字节...
答案 1 :(得分:0)
我有类似的问题。多亏了你,我注意到一些缓冲区有一个超出预期的额外字节。所有这些都具有0作为第一个字节,并且值> = 128作为第二个字节。在解析密钥时剥离0前缀解决了我的问题。
答案 2 :(得分:0)
如果你使用BouncyCastle做这项工作会更好。下面,一些代码使用Rsa传递publicKey加密和privateKey来解密。两个密钥也是使用BouncyCastle生成的,如您所见:
class Program
{
private static string _csr;
private static string _publicKey;
private static string _privateKey;
static void Main(string[] args)
{
GeneratePkcs10("braspag.com.br", "braspag", "BR", RootLenght.RootLength2048);
CryptDecryptTest();
Console.ReadKey();
}
private static void GeneratePkcs10
(string domainName, string companyName, string countryIso2Characters, RootLenght rootLength)
{
try
{
var rsaKeyPairGenerator = new RsaKeyPairGenerator();
var secureRandom = new SecureRandom();
// Note: the numbers {3, 5, 17, 257 or 65537} as Fermat primes.
// NIST doesn't allow a public exponent smaller than 65537, since smaller exponents are a problem if they aren't properly padded.
// Note: the default in openssl is '65537', i.e. 0x10001.
var genParam = new RsaKeyGenerationParameters
(BigInteger.ValueOf(0x10001), secureRandom, (int)rootLength, 128);
rsaKeyPairGenerator.Init(genParam);
AsymmetricCipherKeyPair pair = rsaKeyPairGenerator.GenerateKeyPair();
IDictionary attrs = new Hashtable();
attrs.Add(X509Name.CN, domainName);
attrs.Add(X509Name.O, companyName);
attrs.Add(X509Name.C, countryIso2Characters);
var subject = new X509Name(new ArrayList(attrs.Keys), attrs);
var textWriter = new StringWriter(CultureInfo.InvariantCulture);
var pemWriter = new PemWriter(textWriter);
pemWriter.WriteObject(pair.Private);
pemWriter.Writer.Flush();
_privateKey = textWriter.ToString();
textWriter.Close();
textWriter = new StringWriter(CultureInfo.InvariantCulture);
pemWriter = new PemWriter(textWriter);
pemWriter.WriteObject(pair.Public);
pemWriter.Writer.Flush();
_publicKey = textWriter.ToString();
textWriter.Close();
ISignatureFactory signatureFactory = new Asn1SignatureFactory("SHA256WITHRSA", pair.Private, secureRandom);
var pkcs10CertificationRequest = new Pkcs10CertificationRequest
(signatureFactory, subject, pair.Public, null, pair.Private);
_csr = Convert.ToBase64String(pkcs10CertificationRequest.GetEncoded());
}
catch (Exception ex)
{
throw ex;
}
}
private static void CryptDecryptTest()
{
const string originalText = "test";
var encryptedText = RsaEncryptWithPublic(originalText, _publicKey);
var decryptedText = RsaDecryptWithPrivate(encryptedText, _privateKey);
Console.WriteLine(string.Format("Original Text: {0}", originalText));
Console.WriteLine(string.Format("Encrypted Text: {0}", encryptedText));
Console.WriteLine(string.Format("Decrypted Text: {0}", decryptedText));
}
public static string RsaEncryptWithPublic(string clearText, string publicKey)
{
var bytesToEncrypt = Encoding.UTF8.GetBytes(clearText);
var encryptEngine = new Pkcs1Encoding(new RsaEngine());
using (var txtreader = new StringReader(publicKey))
{
var keyParameter = (AsymmetricKeyParameter)new PemReader(txtreader).ReadObject();
encryptEngine.Init(true, keyParameter);
}
var encrypted = Convert.ToBase64String(encryptEngine.ProcessBlock(bytesToEncrypt, 0, bytesToEncrypt.Length));
return encrypted;
}
public static string RsaDecryptWithPrivate(string base64Input, string privateKey)
{
var bytesToDecrypt = Convert.FromBase64String(base64Input);
AsymmetricCipherKeyPair keyPair;
var decryptEngine = new Pkcs1Encoding(new RsaEngine());
using (var txtreader = new StringReader(privateKey))
{
keyPair = (AsymmetricCipherKeyPair)new PemReader(txtreader).ReadObject();
decryptEngine.Init(false, keyPair.Private);
}
var decrypted = Encoding.UTF8.GetString(decryptEngine.ProcessBlock(bytesToDecrypt, 0, bytesToDecrypt.Length));
return decrypted;
}
private enum RootLenght
{
RootLength2048 = 2048,
RootLength3072 = 3072,
RootLength4096 = 4096,
}
}