कृपया ध्यान दें: नीचे दिया गया कोड निजी कुंजी निर्यात करने के लिए है। यदि आप सार्वजनिक कुंजी निर्यात करना चाहते हैं, तो कृपया मेरे उत्तर here दिए गए देखें।
पीईएम प्रारूप बस ASN.1 कुंजी के डीईआर एन्कोडिंग (प्रति PKCS#1) को बेस 64 में परिवर्तित किया गया है। कुंजी का प्रतिनिधित्व करने के लिए आवश्यक फ़ील्ड की सीमित संख्या को देखते हुए, उचित प्रारूप को आउटपुट करने के लिए त्वरित और गंदे डीईआर एन्कोडर बनाने के लिए यह बहुत सरल है, तो बेस 64 इसे एन्कोड करें। जैसे, कोड इस प्रकार है कि विशेष रूप से सुंदर नहीं है, लेकिन काम करता है: (
public static String ExportPublicKeyToPEMFormat(RSACryptoServiceProvider csp)
{
TextWriter outputStream = new StringWriter();
var parameters = csp.ExportParameters(false);
using (var stream = new MemoryStream())
{
var writer = new BinaryWriter(stream);
writer.Write((byte)0x30); // SEQUENCE
using (var innerStream = new MemoryStream())
{
var innerWriter = new BinaryWriter(innerStream);
EncodeIntegerBigEndian(innerWriter, new byte[] { 0x00 }); // Version
EncodeIntegerBigEndian(innerWriter, parameters.Modulus);
EncodeIntegerBigEndian(innerWriter, parameters.Exponent);
//All Parameter Must Have Value so Set Other Parameter Value Whit Invalid Data (for keeping Key Structure use "parameters.Exponent" value for invalid data)
EncodeIntegerBigEndian(innerWriter, parameters.Exponent); // instead of parameters.D
EncodeIntegerBigEndian(innerWriter, parameters.Exponent); // instead of parameters.P
EncodeIntegerBigEndian(innerWriter, parameters.Exponent); // instead of parameters.Q
EncodeIntegerBigEndian(innerWriter, parameters.Exponent); // instead of parameters.DP
EncodeIntegerBigEndian(innerWriter, parameters.Exponent); // instead of parameters.DQ
EncodeIntegerBigEndian(innerWriter, parameters.Exponent); // instead of parameters.InverseQ
var length = (int)innerStream.Length;
EncodeLength(writer, length);
writer.Write(innerStream.GetBuffer(), 0, length);
}
var base64 = Convert.ToBase64String(stream.GetBuffer(), 0, (int)stream.Length).ToCharArray();
outputStream.WriteLine("-----BEGIN PUBLIC KEY-----");
// Output as Base64 with lines chopped at 64 characters
for (var i = 0; i < base64.Length; i += 64)
{
outputStream.WriteLine(base64, i, Math.Min(64, base64.Length - i));
}
outputStream.WriteLine("-----END PUBLIC KEY-----");
return outputStream.ToString();
}
}
private static void EncodeIntegerBigEndian(BinaryWriter stream, byte[] value, bool forceUnsigned = true)
{
stream.Write((byte)0x02); // INTEGER
var prefixZeros = 0;
for (var i = 0; i < value.Length; i++)
{
if (value[i] != 0) break;
prefixZeros++;
}
if (value.Length - prefixZeros == 0)
{
EncodeLength(stream, 1);
stream.Write((byte)0);
}
else
{
if (forceUnsigned && value[prefixZeros] > 0x7f)
{
// Add a prefix zero to force unsigned if the MSB is 1
EncodeLength(stream, value.Length - prefixZeros + 1);
stream.Write((byte)0);
}
else
{
EncodeLength(stream, value.Length - prefixZeros);
}
for (var i = prefixZeros; i < value.Length; i++)
{
stream.Write(value[i]);
}
}
}
private static void EncodeLength(BinaryWriter stream, int length)
{
if (length < 0) throw new ArgumentOutOfRangeException("length", "Length must be non-negative");
if (length < 0x80)
{
// Short form
stream.Write((byte)length);
}
else
{
// Long form
var temp = length;
var bytesRequired = 0;
while (temp > 0)
{
temp >>= 8;
bytesRequired++;
}
stream.Write((byte)(bytesRequired | 0x80));
for (var i = bytesRequired - 1; i >= 0; i--)
{
stream.Write((byte)(length >> (8 * i) & 0xff));
}
}
}
कैसे और कहाँ एक करता है उस वर्ग के एन उदाहरण में एक कुंजी है? – rene
टीथ दर्द बिंदु .NET और [आरएफसी 3275] (https://www.ietf.org/rfc/rfc3275.txt) से एक्सएमएल एन्कोडिंग के उनके उपयोग के कारण है। .NET ASN.1/DER या PEM एन्कोडेड कुंजी का उपयोग नहीं करता है। मुझे लगता है कि यह एकमात्र क्रिप्टो लाइब्रेरी है जो इस तरह से चीजें करता है। – jww