इनकोडिंग दुर्भाग्य से, सी # यह करने के लिए किसी भी आसान तरीका प्रदान नहीं करता है।
public static RSACryptoServiceProvider DecodeX509PublicKey(byte[] x509key)
{
byte[] SeqOID = { 0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x01, 0x01 };
MemoryStream ms = new MemoryStream(x509key);
BinaryReader reader = new BinaryReader(ms);
if (reader.ReadByte() == 0x30)
ReadASNLength(reader); //skip the size
else
return null;
int identifierSize = 0; //total length of Object Identifier section
if (reader.ReadByte() == 0x30)
identifierSize = ReadASNLength(reader);
else
return null;
if (reader.ReadByte() == 0x06) //is the next element an object identifier?
{
int oidLength = ReadASNLength(reader);
byte[] oidBytes = new byte[oidLength];
reader.Read(oidBytes, 0, oidBytes.Length);
if (oidBytes.SequenceEqual(SeqOID) == false) //is the object identifier rsaEncryption PKCS#1?
return null;
int remainingBytes = identifierSize - 2 - oidBytes.Length;
reader.ReadBytes(remainingBytes);
}
if (reader.ReadByte() == 0x03) //is the next element a bit string?
{
ReadASNLength(reader); //skip the size
reader.ReadByte(); //skip unused bits indicator
if (reader.ReadByte() == 0x30)
{
ReadASNLength(reader); //skip the size
if (reader.ReadByte() == 0x02) //is it an integer?
{
int modulusSize = ReadASNLength(reader);
byte[] modulus = new byte[modulusSize];
reader.Read(modulus, 0, modulus.Length);
if (modulus[0] == 0x00) //strip off the first byte if it's 0
{
byte[] tempModulus = new byte[modulus.Length - 1];
Array.Copy(modulus, 1, tempModulus, 0, modulus.Length - 1);
modulus = tempModulus;
}
if (reader.ReadByte() == 0x02) //is it an integer?
{
int exponentSize = ReadASNLength(reader);
byte[] exponent = new byte[exponentSize];
reader.Read(exponent, 0, exponent.Length);
RSACryptoServiceProvider RSA = new RSACryptoServiceProvider();
RSAParameters RSAKeyInfo = new RSAParameters();
RSAKeyInfo.Modulus = modulus;
RSAKeyInfo.Exponent = exponent;
RSA.ImportParameters(RSAKeyInfo);
return RSA;
}
}
}
}
return null;
}
public static int ReadASNLength(BinaryReader reader)
{
//Note: this method only reads lengths up to 4 bytes long as
//this is satisfactory for the majority of situations.
int length = reader.ReadByte();
if ((length & 0x00000080) == 0x00000080) //is the length greater than 1 byte
{
int count = length & 0x0000000f;
byte[] lengthBytes = new byte[4];
reader.Read(lengthBytes, 4 - count, count);
Array.Reverse(lengthBytes); //
length = BitConverter.ToInt32(lengthBytes, 0);
}
return length;
}
ऊपर कोड this question पर ही आधारित होता है (जो केवल कुछ महत्वपूर्ण आकार के लिए काम किया): लेकिन यह सही ढंग से एक X509 सार्वजनिक कुंजी (Base64 करने के लिए सुनिश्चित पहले x509key पैरामीटर को डिकोड कर) को डिकोड होगा। उपरोक्त कोड हालांकि किसी भी आरएसए कुंजी आकार के लिए काम करेगा, और आपके द्वारा प्रदान की गई कुंजी के साथ-साथ 2048-बिट और 4096-बिट कुंजी के साथ परीक्षण किया गया है।
एक वैकल्पिक समाधान उपकरण का उपयोग करके प्रमाणपत्र उत्पन्न करना होगा (XCA एक अच्छा है), एक पी 12 (पीकेसीएस 12) फ़ाइल को प्रमाण निर्यात करें और फिर चाबियाँ प्राप्त करने के लिए जावा और सी # दोनों में प्रमाणपत्र लोड करें।
सी # में आप X509Certificate2
कक्षा का उपयोग कर एक पीकेसीएस 12 फ़ाइल लोड कर सकते हैं।
X509Certificate2 cert = new X509Certificate2(certificateFile, certificatePassword, X509KeyStorageFlags.Exportable | X509KeyStorageFlags.PersistKeySet);
RSACryptoServiceProvider provider1 = (RSACryptoServiceProvider)cert.PublicKey.Key;
RSACryptoServiceProvider provider2 = (RSACryptoServiceProvider)cert.PrivateKey;
जावा में आप KeyStore
कक्षा का उपयोग कर एक पीकेसीएस 12 फ़ाइल लोड कर सकते हैं।
KeyStore keystore = KeyStore.getInstance("PKCS12");
keystore.load(new FileInputStream(certificateFile), certificatePassword.toCharArray());
Key key = keystore.getKey(certName, certificatePassword.toCharArray());
Certificate cert = keystore.getCertificate(certName);
PublicKey publicKey = cert.getPublicKey();
KeyPair keys = new KeyPair(publicKey, (PrivateKey) key);
@gpa: इस उत्तर को अस्वीकार कर दिया गया।क्या यह आपके लिए काम नहीं करता है? यदि कोई समस्या है, तो क्या आप कुछ स्पष्टीकरण दे सकते हैं? – Syon
देर से जवाब देने के लिए खेद है, लेकिन समाधान मेरे लिए काम नहीं करेगा, क्योंकि सार्वजनिक कुंजी जावा द्वारा उत्पन्न होती है और फ़ाइल में क्रमबद्ध होती है। डॉटनेट एप्लिकेशन ने एक ही सार्वजनिक कुंजी पढ़ी होगी और इसकी पब्लिककी का निर्माण किया होगा ... – gpa
उत्पन्न करने के लिए विशिष्ट जावा कोड क्या है और फिर सार्वजनिक कुंजी को फ़ाइल में क्रमबद्ध करें? (क्या आप इसे अपने प्रश्न में जोड़ सकते हैं) जावा क्रमबद्ध ऑब्जेक्ट को पढ़ने वाला डॉटनेट आसानी से करने योग्य नहीं है, लेकिन यदि आप एक मानक प्रारूप में सार्वजनिक कुंजी को सहेज रहे हैं, तो इसे सी # में पुनर्निर्माण करना संभव होना चाहिए। – Syon